1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
#ifndef OPENMW_COMPONENTS_SHADERVISITOR_H
#define OPENMW_COMPONENTS_SHADERVISITOR_H
#include <osg/NodeVisitor>
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& defaultShaderPrefix);
/// 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 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);
void setApplyLightingToEnvMaps(bool apply);
void setConvertAlphaTestToAlphaToCoverage(bool convert);
void setTranslucentFramebuffer(bool translucent);
void apply(osg::Node& node) override;
void apply(osg::Drawable& drawable) override;
void apply(osg::Geometry& geometry) override;
void applyStateSet(osg::ref_ptr<osg::StateSet> stateset, osg::Node& node);
void pushRequirements(osg::Node& node);
void popRequirements();
private:
bool mForceShaders;
bool mAllowedToModifyStateSets;
bool mAutoUseNormalMaps;
std::string mNormalMapPattern;
std::string mNormalHeightMapPattern;
bool mAutoUseSpecularMaps;
std::string mSpecularMapPattern;
bool mApplyLightingToEnvMaps;
bool mConvertAlphaTestToAlphaToCoverage;
bool mTranslucentFramebuffer;
ShaderManager& mShaderManager;
Resource::ImageManager& mImageManager;
struct ShaderRequirements
{
ShaderRequirements();
~ShaderRequirements();
// <texture stage, texture name>
std::map<int, std::string> mTextures;
bool mShaderRequired;
int mColorMode;
bool mMaterialOverridden;
bool mAlphaTestOverridden;
bool mAlphaBlendOverridden;
GLenum mAlphaFunc;
float mAlphaRef;
bool mAlphaBlend;
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<ShaderRequirements> mRequirements;
std::string mDefaultShaderPrefix;
void createProgram(const ShaderRequirements& reqs);
void ensureFFP(osg::Node& node);
bool adjustGeometry(osg::Geometry& sourceGeometry, const ShaderRequirements& reqs);
};
class ReinstateRemovedStateVisitor : public osg::NodeVisitor
{
public:
ReinstateRemovedStateVisitor(bool allowedToModifyStateSets);
void apply(osg::Node& node) override;
private:
bool mAllowedToModifyStateSets;
};
}
#endif
|