File: shadervisitor.hpp

package info (click to toggle)
openmw 0.49.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 33,992 kB
  • sloc: cpp: 372,479; xml: 2,149; sh: 1,403; python: 797; makefile: 26
file content (147 lines) | stat: -rw-r--r-- 4,653 bytes parent folder | download
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