1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-16 11:29:54 +00:00
openmw/components/shader/shadermanager.hpp

135 lines
5.1 KiB
C++
Raw Normal View History

#ifndef OPENMW_COMPONENTS_SHADERMANAGER_H
#define OPENMW_COMPONENTS_SHADERMANAGER_H
2022-09-22 18:26:05 +00:00
#include <array>
#include <map>
2022-09-22 18:26:05 +00:00
#include <memory>
2020-06-25 19:46:07 +00:00
#include <mutex>
2022-09-22 18:26:05 +00:00
#include <string>
#include <vector>
#include <osg/ref_ptr>
#include <filesystem>
2022-09-22 18:26:05 +00:00
#include <osg/Program>
#include <osg/Shader>
2022-09-22 18:26:05 +00:00
namespace osgViewer
{
2022-08-12 16:47:29 +00:00
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;
2021-03-02 07:30:54 +00:00
ShaderManager();
~ShaderManager();
2021-02-21 18:38:15 +00:00
2022-09-22 18:26:05 +00:00
void setShaderPath(const std::filesystem::path& path);
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).
2018-10-09 06:21:12 +00:00
/// @note May return nullptr on failure.
/// @note Thread safe.
2022-09-22 18:26:05 +00:00
osg::ref_ptr<osg::Shader> getShader(
const std::string& templateName, const DefineMap& defines, osg::Shader::Type shaderType);
2022-09-22 18:26:05 +00:00
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; }
2016-02-17 14:04:05 +00:00
/// 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
2022-09-22 18:26:05 +00:00
/// @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);
2016-02-17 14:04:05 +00:00
2022-09-22 18:26:05 +00:00
bool createSourceFromTemplate(std::string& source, std::vector<std::string>& linkedShaderTemplateNames,
const std::string& templateName, const ShaderManager::DefineMap& defines);
2022-06-06 20:40:38 +00:00
void setMaxTextureUnits(int maxTextureUnits) { mMaxTextureUnits = maxTextureUnits; }
int getMaxTextureUnits() const { return mMaxTextureUnits; }
int getAvailableTextureUnits() const { return mMaxTextureUnits - mReservedTextureUnits; }
enum class Slot
{
OpaqueDepthTexture,
SkyTexture,
};
int reserveGlobalTextureUnits(Slot slot);
2022-06-06 20:40:38 +00:00
2022-08-12 16:26:04 +00:00
void update(osgViewer::Viewer& viewer);
void setHotReloadEnabled(bool value);
void triggerShaderReload();
2022-09-22 18:26:05 +00:00
private:
2022-09-22 18:26:05 +00:00
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;
2022-09-22 18:26:05 +00:00
typedef std::map<MapKey, osg::ref_ptr<osg::Shader>> ShaderMap;
ShaderMap mShaders;
2022-09-22 18:26:05 +00:00
typedef std::map<std::pair<osg::ref_ptr<osg::Shader>, osg::ref_ptr<osg::Shader>>, osg::ref_ptr<osg::Program>>
ProgramMap;
2016-02-17 14:04:05 +00:00
ProgramMap mPrograms;
2022-09-22 18:26:05 +00:00
typedef std::vector<osg::ref_ptr<osg::Shader>> ShaderList;
typedef std::map<osg::ref_ptr<osg::Shader>, ShaderList> LinkedShadersMap;
LinkedShadersMap mLinkedShaders;
2020-06-25 19:46:07 +00:00
std::mutex mMutex;
osg::ref_ptr<const osg::Program> mProgramTemplate;
2022-06-06 20:40:38 +00:00
int mMaxTextureUnits = 0;
int mReservedTextureUnits = 0;
std::unique_ptr<HotReloadManager> mHotReloadManager;
2022-09-22 18:26:05 +00:00
std::array<int, 2> mReservedTextureUnitsBySlot = { -1, -1 };
};
bool parseForeachDirective(std::string& source, const std::string& templateName, size_t foundPos);
2022-09-22 18:26:05 +00:00
bool parseLinkDirective(
std::string& source, std::string& linkTarget, const std::string& templateName, size_t foundPos);
2020-05-01 21:03:13 +00:00
bool parseDefines(std::string& source, const ShaderManager::DefineMap& defines,
const ShaderManager::DefineMap& globalDefines, const std::string& templateName);
2022-09-22 18:26:05 +00:00
bool parseDirectives(std::string& source, std::vector<std::string>& linkedShaderTemplateNames,
const ShaderManager::DefineMap& defines, const ShaderManager::DefineMap& globalDefines,
const std::string& templateName);
}
#endif