mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 12:26:39 +00:00 
			
		
		
		
	Don't use FFP-friendly texture image units for shadow maps Closes #7102 See merge request OpenMW/openmw!2682
		
			
				
	
	
		
			145 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
	
		
			5.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#ifndef OPENMW_COMPONENTS_SHADERMANAGER_H
 | 
						|
#define OPENMW_COMPONENTS_SHADERMANAGER_H
 | 
						|
 | 
						|
#include <array>
 | 
						|
#include <map>
 | 
						|
#include <memory>
 | 
						|
#include <mutex>
 | 
						|
#include <optional>
 | 
						|
#include <string>
 | 
						|
#include <vector>
 | 
						|
 | 
						|
#include <osg/ref_ptr>
 | 
						|
 | 
						|
#include <filesystem>
 | 
						|
#include <osg/Program>
 | 
						|
#include <osg/Shader>
 | 
						|
 | 
						|
namespace osgViewer
 | 
						|
{
 | 
						|
    class Viewer;
 | 
						|
}
 | 
						|
 | 
						|
namespace Shader
 | 
						|
{
 | 
						|
    struct HotReloadManager;
 | 
						|
    /// @brief Reads shader template files and turns them into a concrete shader, based on a list of define's.
 | 
						|
    /// @par Shader templates can get the value of a define with the syntax @define.
 | 
						|
    class ShaderManager
 | 
						|
    {
 | 
						|
    public:
 | 
						|
        friend HotReloadManager;
 | 
						|
        ShaderManager();
 | 
						|
        ~ShaderManager();
 | 
						|
 | 
						|
        void setShaderPath(const std::filesystem::path& path);
 | 
						|
 | 
						|
        typedef std::map<std::string, std::string> DefineMap;
 | 
						|
 | 
						|
        /// Create or retrieve a shader instance.
 | 
						|
        /// @param templateName The path 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).
 | 
						|
        /// @note May return nullptr on failure.
 | 
						|
        /// @note Thread safe.
 | 
						|
        osg::ref_ptr<osg::Shader> getShader(std::string templateName, const DefineMap& defines = {},
 | 
						|
            std::optional<osg::Shader::Type> type = std::nullopt);
 | 
						|
 | 
						|
        osg::ref_ptr<osg::Program> getProgram(const std::string& templateName, const DefineMap& defines = {},
 | 
						|
            const osg::Program* programTemplate = nullptr);
 | 
						|
 | 
						|
        osg::ref_ptr<osg::Program> getProgram(osg::ref_ptr<osg::Shader> vertexShader,
 | 
						|
            osg::ref_ptr<osg::Shader> fragmentShader, const osg::Program* programTemplate = nullptr);
 | 
						|
 | 
						|
        const osg::Program* getProgramTemplate() const { return mProgramTemplate; }
 | 
						|
        void setProgramTemplate(const osg::Program* program) { mProgramTemplate = program; }
 | 
						|
 | 
						|
        /// Clone an osg::Program including bindUniformBlocks that osg::Program::clone does not copy for some reason.
 | 
						|
        static osg::ref_ptr<osg::Program> cloneProgram(const osg::Program*);
 | 
						|
 | 
						|
        /// 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
 | 
						|
        /// @note This will change the source code for any shaders already created, potentially causing problems if
 | 
						|
        /// they're being used to render a frame. It is recommended that any associated Viewers have their threading
 | 
						|
        /// stopped while this function is running if any shaders are in use.
 | 
						|
        void setGlobalDefines(DefineMap& globalDefines);
 | 
						|
 | 
						|
        void releaseGLObjects(osg::State* state);
 | 
						|
 | 
						|
        bool createSourceFromTemplate(std::string& source, std::vector<std::string>& linkedShaderTemplateNames,
 | 
						|
            const std::string& templateName, const ShaderManager::DefineMap& defines);
 | 
						|
 | 
						|
        void setMaxTextureUnits(int maxTextureUnits) { mMaxTextureUnits = maxTextureUnits; }
 | 
						|
        int getMaxTextureUnits() const { return mMaxTextureUnits; }
 | 
						|
        int getAvailableTextureUnits() const { return mMaxTextureUnits - mReservedTextureUnits; }
 | 
						|
 | 
						|
        enum class Slot
 | 
						|
        {
 | 
						|
            OpaqueDepthTexture,
 | 
						|
            SkyTexture,
 | 
						|
            ShadowMaps,
 | 
						|
            SLOT_COUNT
 | 
						|
        };
 | 
						|
 | 
						|
        int reserveGlobalTextureUnits(Slot slot, int count = 1);
 | 
						|
 | 
						|
        void update(osgViewer::Viewer& viewer);
 | 
						|
        void setHotReloadEnabled(bool value);
 | 
						|
        void triggerShaderReload();
 | 
						|
 | 
						|
    private:
 | 
						|
        void getLinkedShaders(osg::ref_ptr<osg::Shader> shader, const std::vector<std::string>& linkedShaderNames,
 | 
						|
            const DefineMap& defines);
 | 
						|
        void addLinkedShaders(osg::ref_ptr<osg::Shader> shader, osg::ref_ptr<osg::Program> program);
 | 
						|
 | 
						|
        std::filesystem::path mPath;
 | 
						|
 | 
						|
        DefineMap mGlobalDefines;
 | 
						|
 | 
						|
        // <name, code>
 | 
						|
        typedef std::map<std::string, std::string> TemplateMap;
 | 
						|
        TemplateMap mShaderTemplates;
 | 
						|
 | 
						|
        typedef std::pair<std::string, DefineMap> MapKey;
 | 
						|
        typedef std::map<MapKey, osg::ref_ptr<osg::Shader>> ShaderMap;
 | 
						|
        ShaderMap mShaders;
 | 
						|
 | 
						|
        typedef std::map<std::pair<osg::ref_ptr<osg::Shader>, osg::ref_ptr<osg::Shader>>, osg::ref_ptr<osg::Program>>
 | 
						|
            ProgramMap;
 | 
						|
        ProgramMap mPrograms;
 | 
						|
 | 
						|
        typedef std::vector<osg::ref_ptr<osg::Shader>> ShaderList;
 | 
						|
        typedef std::map<osg::ref_ptr<osg::Shader>, ShaderList> LinkedShadersMap;
 | 
						|
        LinkedShadersMap mLinkedShaders;
 | 
						|
 | 
						|
        std::mutex mMutex;
 | 
						|
 | 
						|
        osg::ref_ptr<const osg::Program> mProgramTemplate;
 | 
						|
 | 
						|
        int mMaxTextureUnits = 0;
 | 
						|
        int mReservedTextureUnits = 0;
 | 
						|
        std::unique_ptr<HotReloadManager> mHotReloadManager;
 | 
						|
        struct ReservedTextureUnits
 | 
						|
        {
 | 
						|
            int index = -1;
 | 
						|
            int count = 0;
 | 
						|
        };
 | 
						|
        std::array<ReservedTextureUnits, static_cast<int>(Slot::SLOT_COUNT)> mReservedTextureUnitsBySlot = {};
 | 
						|
    };
 | 
						|
 | 
						|
    bool parseForeachDirective(std::string& source, const std::string& templateName, size_t foundPos);
 | 
						|
    bool parseLinkDirective(
 | 
						|
        std::string& source, std::string& linkTarget, const std::string& templateName, size_t foundPos);
 | 
						|
 | 
						|
    bool parseDefines(std::string& source, const ShaderManager::DefineMap& defines,
 | 
						|
        const ShaderManager::DefineMap& globalDefines, const std::string& templateName);
 | 
						|
 | 
						|
    bool parseDirectives(std::string& source, std::vector<std::string>& linkedShaderTemplateNames,
 | 
						|
        const ShaderManager::DefineMap& defines, const ShaderManager::DefineMap& globalDefines,
 | 
						|
        const std::string& templateName);
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |