mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-11-04 00:26:45 +00:00 
			
		
		
		
	Add preliminary support for global shader defines.
This commit is contained in:
		
							parent
							
								
									7a9df977c7
								
							
						
					
					
						commit
						98cd9fc144
					
				
					 5 changed files with 70 additions and 34 deletions
				
			
		| 
						 | 
				
			
			@ -238,6 +238,10 @@ namespace MWRender
 | 
			
		|||
        shadowedScene->addChild(sceneRoot);
 | 
			
		||||
        mRootNode->addChild(shadowedScene);
 | 
			
		||||
 | 
			
		||||
        Shader::ShaderManager::DefineMap shadowDefines = tech->getShadowDefines();
 | 
			
		||||
        Shader::ShaderManager::DefineMap globalDefines = mResourceSystem->getSceneManager()->getShaderManager().getGlobalDefines();
 | 
			
		||||
        globalDefines.insert(shadowDefines.begin(), shadowDefines.end());
 | 
			
		||||
        mResourceSystem->getSceneManager()->getShaderManager().setGlobalDefines(globalDefines);
 | 
			
		||||
 | 
			
		||||
        mPathgrid.reset(new Pathgrid(mRootNode));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -712,4 +712,28 @@ namespace SceneUtil
 | 
			
		|||
 | 
			
		||||
        // OSG_NOTICE<<"End of shadow setup Projection matrix "<<*cv.getProjectionMatrix()<<std::endl;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Shader::ShaderManager::DefineMap MWShadow::getShadowDefines()
 | 
			
		||||
    {
 | 
			
		||||
        if (!enableShadows)
 | 
			
		||||
            return getShadowsDisabledDefines();
 | 
			
		||||
 | 
			
		||||
        Shader::ShaderManager::DefineMap definesWithShadows;
 | 
			
		||||
        definesWithShadows.insert(std::make_pair(std::string("shadows_enabled"), std::string("1")));
 | 
			
		||||
        for (int i = 0; i < numberOfShadowMapsPerLight; ++i)
 | 
			
		||||
            definesWithShadows["shadow_texture_unit_list"] += std::to_string(i) + ",";
 | 
			
		||||
        // remove extra comma
 | 
			
		||||
        definesWithShadows["shadow_texture_unit_list"] = definesWithShadows["shadow_texture_unit_list"].substr(0, definesWithShadows["shadow_texture_unit_list"].length() - 1);
 | 
			
		||||
 | 
			
		||||
        return definesWithShadows;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Shader::ShaderManager::DefineMap MWShadow::getShadowsDisabledDefines()
 | 
			
		||||
    {
 | 
			
		||||
        Shader::ShaderManager::DefineMap definesWithShadows;
 | 
			
		||||
        definesWithShadows.insert(std::make_pair(std::string("shadows_enabled"), std::string("0")));
 | 
			
		||||
        definesWithShadows["shadow_texture_unit_list"] = "";
 | 
			
		||||
 | 
			
		||||
        return definesWithShadows;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,12 +3,15 @@
 | 
			
		|||
 | 
			
		||||
#include <osgShadow/ViewDependentShadowMap>
 | 
			
		||||
 | 
			
		||||
#include <components/shader/shadermanager.hpp>
 | 
			
		||||
 | 
			
		||||
namespace SceneUtil
 | 
			
		||||
{
 | 
			
		||||
    class MWShadow : public osgShadow::ViewDependentShadowMap
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        static const int numberOfShadowMapsPerLight = 3;
 | 
			
		||||
        static const int enableShadows = true;
 | 
			
		||||
        static const bool debugHud = true;
 | 
			
		||||
 | 
			
		||||
        MWShadow();
 | 
			
		||||
| 
						 | 
				
			
			@ -16,6 +19,10 @@ namespace SceneUtil
 | 
			
		|||
        const static int baseShadowTextureUnit = 8 - numberOfShadowMapsPerLight;
 | 
			
		||||
 | 
			
		||||
        virtual void cull(osgUtil::CullVisitor& cv);
 | 
			
		||||
 | 
			
		||||
        virtual Shader::ShaderManager::DefineMap getShadowDefines();
 | 
			
		||||
 | 
			
		||||
        virtual Shader::ShaderManager::DefineMap getShadowsDisabledDefines();
 | 
			
		||||
    protected:
 | 
			
		||||
        const int debugTextureUnit;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,8 +11,6 @@
 | 
			
		|||
#include <boost/filesystem/fstream.hpp>
 | 
			
		||||
#include <boost/algorithm/string.hpp>
 | 
			
		||||
 | 
			
		||||
#include "components/sceneutil/shadow.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Shader
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -211,7 +209,7 @@ namespace Shader
 | 
			
		|||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool parseDefines(std::string& source, const ShaderManager::DefineMap& defines)
 | 
			
		||||
    bool parseDefines(std::string& source, const ShaderManager::DefineMap& defines, const ShaderManager::DefineMap& globalDefines)
 | 
			
		||||
    {
 | 
			
		||||
        const char escapeCharacter = '@';
 | 
			
		||||
        size_t foundPos = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -226,6 +224,7 @@ namespace Shader
 | 
			
		|||
            }
 | 
			
		||||
            std::string define = source.substr(foundPos+1, endPos - (foundPos+1));
 | 
			
		||||
            ShaderManager::DefineMap::const_iterator defineFound = defines.find(define);
 | 
			
		||||
            ShaderManager::DefineMap::const_iterator globalDefineFound = globalDefines.find(define);
 | 
			
		||||
            if (define == "foreach")
 | 
			
		||||
            {
 | 
			
		||||
                source.replace(foundPos, 1, "$");
 | 
			
		||||
| 
						 | 
				
			
			@ -253,44 +252,27 @@ namespace Shader
 | 
			
		|||
            {
 | 
			
		||||
                source.replace(foundPos, 1, "$");
 | 
			
		||||
            }
 | 
			
		||||
            else if (defineFound == defines.end())
 | 
			
		||||
            else if (defineFound != defines.end())
 | 
			
		||||
            {
 | 
			
		||||
                std::cerr << "Undefined " << define << std::endl;
 | 
			
		||||
                return false;
 | 
			
		||||
                source.replace(foundPos, endPos - foundPos, defineFound->second);
 | 
			
		||||
            }
 | 
			
		||||
            else if (globalDefineFound != globalDefines.end())
 | 
			
		||||
            {
 | 
			
		||||
                source.replace(foundPos, endPos - foundPos, globalDefineFound->second);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                source.replace(foundPos, endPos-foundPos, defineFound->second);
 | 
			
		||||
                std::cerr << "Undefined " << define << std::endl;
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    osg::ref_ptr<osg::Shader> ShaderManager::getShader(const std::string &shaderTemplate, const ShaderManager::DefineMap &defines, osg::Shader::Type shaderType, bool disableShadows)
 | 
			
		||||
    osg::ref_ptr<osg::Shader> ShaderManager::getShader(const std::string &shaderTemplate, const ShaderManager::DefineMap &defines, osg::Shader::Type shaderType)
 | 
			
		||||
    {
 | 
			
		||||
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
 | 
			
		||||
 | 
			
		||||
        // set up shadows in the shader
 | 
			
		||||
        // get these values from settings manager
 | 
			
		||||
        bool shadows = true & !disableShadows;
 | 
			
		||||
        int numShadowMaps = SceneUtil::MWShadow::numberOfShadowMapsPerLight;
 | 
			
		||||
        DefineMap definesWithShadows;
 | 
			
		||||
        if (shadows)
 | 
			
		||||
        {
 | 
			
		||||
            definesWithShadows.insert(std::make_pair(std::string("shadows_enabled"), std::string("1")));
 | 
			
		||||
            for (int i = 0; i < numShadowMaps; ++i)
 | 
			
		||||
                definesWithShadows["shadow_texture_unit_list"] += std::to_string(i) + ",";
 | 
			
		||||
            // remove extra comma
 | 
			
		||||
            definesWithShadows["shadow_texture_unit_list"] = definesWithShadows["shadow_texture_unit_list"].substr(0, definesWithShadows["shadow_texture_unit_list"].length() - 1);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            definesWithShadows.insert(std::make_pair(std::string("shadows_enabled"), std::string("0")));
 | 
			
		||||
            definesWithShadows["shadow_texture_unit_list"] = "";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        definesWithShadows.insert(defines.begin(), defines.end());
 | 
			
		||||
 | 
			
		||||
        // read the template if we haven't already
 | 
			
		||||
        TemplateMap::iterator templateIt = mShaderTemplates.find(shaderTemplate);
 | 
			
		||||
        if (templateIt == mShaderTemplates.end())
 | 
			
		||||
| 
						 | 
				
			
			@ -314,11 +296,11 @@ namespace Shader
 | 
			
		|||
            templateIt = mShaderTemplates.insert(std::make_pair(shaderTemplate, source)).first;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ShaderMap::iterator shaderIt = mShaders.find(std::make_pair(shaderTemplate, definesWithShadows));
 | 
			
		||||
        ShaderMap::iterator shaderIt = mShaders.find(std::make_pair(shaderTemplate, defines));
 | 
			
		||||
        if (shaderIt == mShaders.end())
 | 
			
		||||
        {
 | 
			
		||||
            std::string shaderSource = templateIt->second;
 | 
			
		||||
            if (!parseDefines(shaderSource, definesWithShadows) || !parseFors(shaderSource))
 | 
			
		||||
            if (!parseDefines(shaderSource, defines, mGlobalDefines) || !parseFors(shaderSource))
 | 
			
		||||
            {
 | 
			
		||||
                // Add to the cache anyway to avoid logging the same error over and over.
 | 
			
		||||
                mShaders.insert(std::make_pair(std::make_pair(shaderTemplate, defines), nullptr));
 | 
			
		||||
| 
						 | 
				
			
			@ -331,7 +313,7 @@ namespace Shader
 | 
			
		|||
            static unsigned int counter = 0;
 | 
			
		||||
            shader->setName(std::to_string(counter++));
 | 
			
		||||
 | 
			
		||||
            shaderIt = mShaders.insert(std::make_pair(std::make_pair(shaderTemplate, definesWithShadows), shader)).first;
 | 
			
		||||
            shaderIt = mShaders.insert(std::make_pair(std::make_pair(shaderTemplate, defines), shader)).first;
 | 
			
		||||
        }
 | 
			
		||||
        return shaderIt->second;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -350,6 +332,17 @@ namespace Shader
 | 
			
		|||
        return found->second;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ShaderManager::DefineMap ShaderManager::getGlobalDefines()
 | 
			
		||||
    {
 | 
			
		||||
        return DefineMap(mGlobalDefines);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ShaderManager::setGlobalDefines(DefineMap & defines)
 | 
			
		||||
    {
 | 
			
		||||
        mGlobalDefines = defines;
 | 
			
		||||
        // TODO: We need to trigger the regeneration of all shaders.
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ShaderManager::releaseGLObjects(osg::State *state)
 | 
			
		||||
    {
 | 
			
		||||
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,18 +26,26 @@ namespace Shader
 | 
			
		|||
        /// @param shaderTemplate The filename of the shader template.
 | 
			
		||||
        /// @param defines Define values that can be retrieved by the shader template.
 | 
			
		||||
        /// @param shaderType The type of shader (usually vertex or fragment shader).
 | 
			
		||||
        /// @param disableShadows Whether to disable shadows in the shader regardless of the overall setting. False by default.
 | 
			
		||||
        /// @note May return NULL on failure.
 | 
			
		||||
        /// @note Thread safe.
 | 
			
		||||
        osg::ref_ptr<osg::Shader> getShader(const std::string& shaderTemplate, const DefineMap& defines, osg::Shader::Type shaderType, bool disableShadows = false);
 | 
			
		||||
        osg::ref_ptr<osg::Shader> getShader(const std::string& shaderTemplate, const DefineMap& defines, osg::Shader::Type shaderType);
 | 
			
		||||
 | 
			
		||||
        osg::ref_ptr<osg::Program> getProgram(osg::ref_ptr<osg::Shader> vertexShader, osg::ref_ptr<osg::Shader> fragmentShader);
 | 
			
		||||
 | 
			
		||||
        /// Get (a copy of) the DefineMap used to construct all shaders
 | 
			
		||||
        DefineMap getGlobalDefines();
 | 
			
		||||
 | 
			
		||||
        /// Set the DefineMap used to construct all shaders
 | 
			
		||||
        /// @param defines The DefineMap to use
 | 
			
		||||
        void setGlobalDefines(DefineMap& defines);
 | 
			
		||||
 | 
			
		||||
        void releaseGLObjects(osg::State* state);
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        std::string mPath;
 | 
			
		||||
 | 
			
		||||
        DefineMap mGlobalDefines;
 | 
			
		||||
 | 
			
		||||
        // <name, code>
 | 
			
		||||
        typedef std::map<std::string, std::string> TemplateMap;
 | 
			
		||||
        TemplateMap mShaderTemplates;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue