mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-20 11:53:53 +00:00
b21c9cdf31
Shaders: Hot reload, togglable by lua debug command See merge request OpenMW/openmw!2238 (cherry picked from commit4078f19c74
)8d194a16
Shaders: rudimentary hot reloader on shaders4e7c1c5b
Added break when the operation failed6b38d622
Added lua bindings to toggle hot reload (disabled by default) or to trigger a reload31d41252
forgot memory includef78fa989
fixed include, cleaned comments and indentationfc8838c7
Renamed lua binding, and use action to avoid concurrency issueaa51d6de
Missing chrono include ?68d06989
Fixed cyclical included checkb6d7293a
Removed weird lines that I thought were necessary to please the compiler9a475b0c
fixed blank lines and missing breakscdd95f78
replaced empty function body by defaulta1c8dc9d
C++17 compat ?7b78bf4b
Fix files with different defines weren't added to the hot reload managercc9d4364
includes now work when the same shader has different defines15751c57
Lua debug api doc3ab0a991
Hot reload done only once every 200 ms, no point in beeing fasterdf69fc76
Post processing shaders now use the same lua commands, no more launcher option...c71f3508
changed overview.rst of post processing603b30e1
Added some variable names to make it clearer what their function wasbaadc06e
Merge branch 'master' into 'SHADER_HOT_RELOAD'decfbc53
Fix threading issuesb14cc673
adds missing decleration16a4b571
adds missing include166717d6
Makes sure threads are only stopped once ,and that they will be re-started25c1f0ca
Renamed variable to fix case issue
122 lines
5 KiB
C++
122 lines
5 KiB
C++
#ifndef OPENMW_COMPONENTS_SHADERMANAGER_H
|
|
#define OPENMW_COMPONENTS_SHADERMANAGER_H
|
|
|
|
#include <string>
|
|
#include <map>
|
|
#include <mutex>
|
|
#include <vector>
|
|
#include <array>
|
|
#include <memory>
|
|
|
|
#include <osg/ref_ptr>
|
|
|
|
#include <osg/Shader>
|
|
#include <osg/Program>
|
|
|
|
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::string& 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).
|
|
/// @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, 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,
|
|
};
|
|
|
|
int reserveGlobalTextureUnits(Slot slot);
|
|
|
|
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::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;
|
|
|
|
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;
|
|
std::array<int, 2> mReservedTextureUnitsBySlot = {-1, -1};
|
|
};
|
|
|
|
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
|