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 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
#ifndef OPENMW_COMPONENTS_SHADERVISITOR_H
#define OPENMW_COMPONENTS_SHADERVISITOR_H
#include <osg/NodeVisitor>
#include <osg/Program>
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);
void setProgramTemplate(const osg::Program* programTemplate) { mProgramTemplate = programTemplate; }
/// 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 setAdjustCoverageForAlphaTest(bool adjustCoverage);
void setSupportsNormalsRT(bool supports) { mSupportsNormalsRT = supports; }
void setWeatherParticleOcclusion(bool value) { mWeatherParticleOcclusion = value; }
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 mAdjustCoverageForAlphaTest;
bool mSupportsNormalsRT;
bool mWeatherParticleOcclusion = false;
ShaderManager& mShaderManager;
Resource::ImageManager& mImageManager;
struct ShaderRequirements
{
ShaderRequirements();
~ShaderRequirements() = default;
// <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 mBlendFuncOverridden;
bool mAdditiveBlending;
bool mDiffuseHeight; // true if diffuse map has height info in alpha channel
bool mNormalHeight; // true if normal map has height info in alpha channel
bool mReconstructNormalZ; // used for red-green normal maps (e.g. BC5)
// -1 == no tangents required
int mTexStageRequiringTangents;
bool mSoftParticles;
// 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);
osg::ref_ptr<const osg::Program> mProgramTemplate;
};
class ReinstateRemovedStateVisitor : public osg::NodeVisitor
{
public:
ReinstateRemovedStateVisitor(bool allowedToModifyStateSets);
void apply(osg::Node& node) override;
private:
bool mAllowedToModifyStateSets;
};
}
#endif
|