#ifndef OPENMW_COMPONENTS_SHADERVISITOR_H #define OPENMW_COMPONENTS_SHADERVISITOR_H #include namespace Resource { class ImageManager; } namespace Shader { class ShaderManager; /// @brief Adjusts the given subgraph to render using shaders. class ShaderVisitor : public osg::NodeVisitor { public: ShaderVisitor(ShaderManager& shaderManager, Resource::ImageManager& imageManager, const std::string& defaultVsTemplate, const std::string& defaultFsTemplate); /// By default, only bump mapped objects will have a shader added to them. /// Setting force = true will cause all objects to render using shaders, regardless of having a bump map. void setForceShaders(bool force); /// Set whether lighting is clamped for visual compatibility with the fixed function pipeline. void setClampLighting(bool clamp); /// By default, only bump mapped objects use per-pixel lighting. /// Setting force = true will cause all shaders to use per-pixel lighting, regardless of having a bump map. void setForcePerPixelLighting(bool force); /// Set if we are allowed to modify StateSets encountered in the graph (default true). /// @par If set to false, then instead of modifying, the StateSet will be cloned and this new StateSet will be assigned to the node. /// @par This option is useful when the ShaderVisitor is run on a "live" subgraph that may have already been submitted for rendering. void setAllowedToModifyStateSets(bool allowed); /// Automatically use normal maps if a file with suitable name exists (see normal map pattern). void setAutoUseNormalMaps(bool use); void setNormalMapPattern(const std::string& pattern); void setNormalHeightMapPattern(const std::string& pattern); void setAutoUseSpecularMaps(bool use); void setSpecularMapPattern(const std::string& pattern); virtual void apply(osg::Node& node); virtual void apply(osg::Drawable& drawable); virtual void apply(osg::Geometry& geometry); void applyStateSet(osg::ref_ptr stateset, osg::Node& node); void pushRequirements(osg::Node& node); void popRequirements(); private: bool mForceShaders; bool mClampLighting; bool mForcePerPixelLighting; bool mAllowedToModifyStateSets; bool mAutoUseNormalMaps; std::string mNormalMapPattern; std::string mNormalHeightMapPattern; bool mAutoUseSpecularMaps; std::string mSpecularMapPattern; ShaderManager& mShaderManager; Resource::ImageManager& mImageManager; struct ShaderRequirements { ShaderRequirements(); ~ShaderRequirements(); // std::map mTextures; bool mShaderRequired; bool mColorMaterial; // osg::Material::ColorMode int mVertexColorMode; bool mMaterialOverridden; bool mNormalHeight; // true if normal map has height info in alpha channel // -1 == no tangents required int mTexStageRequiringTangents; // the Node that requested these requirements osg::Node* mNode; }; std::vector mRequirements; std::string mDefaultVsTemplate; std::string mDefaultFsTemplate; void createProgram(const ShaderRequirements& reqs); bool adjustGeometry(osg::Geometry& sourceGeometry, const ShaderRequirements& reqs); }; } #endif