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
|
#ifndef OPENMW_COMPONENTS_SHADERMANAGER_H
#define OPENMW_COMPONENTS_SHADERMANAGER_H
#include <string>
#include <map>
#include <mutex>
#include <osg/ref_ptr>
#include <osg/Shader>
#include <osgViewer/Viewer>
#include <components/sceneutil/lightmanager.hpp>
namespace Resource
{
class SceneManager;
}
namespace SceneUtil
{
enum class LightingMethod;
}
namespace Shader
{
enum class UBOBinding
{
LightBuffer
};
/// @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:
ShaderManager();
void setShaderPath(const std::string& path);
void setLightingMethod(SceneUtil::LightingMethod method);
typedef std::map<std::string, std::string> DefineMap;
/// Create or retrieve a shader instance.
/// @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).
/// @note May return nullptr on failure.
/// @note Thread safe.
osg::ref_ptr<osg::Shader> getShader(const std::string& templateName, 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
/// @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);
private:
std::string 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;
SceneUtil::LightingMethod mLightingMethod;
std::mutex mMutex;
};
bool parseFors(std::string& source, const std::string& templateName);
bool parseDefines(std::string& source, const ShaderManager::DefineMap& defines,
const ShaderManager::DefineMap& globalDefines, const std::string& templateName);
}
#endif
|