mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-07 00:15:34 +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);
|
shadowedScene->addChild(sceneRoot);
|
||||||
mRootNode->addChild(shadowedScene);
|
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));
|
mPathgrid.reset(new Pathgrid(mRootNode));
|
||||||
|
|
||||||
|
|
|
@ -712,4 +712,28 @@ namespace SceneUtil
|
||||||
|
|
||||||
// OSG_NOTICE<<"End of shadow setup Projection matrix "<<*cv.getProjectionMatrix()<<std::endl;
|
// 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 <osgShadow/ViewDependentShadowMap>
|
||||||
|
|
||||||
|
#include <components/shader/shadermanager.hpp>
|
||||||
|
|
||||||
namespace SceneUtil
|
namespace SceneUtil
|
||||||
{
|
{
|
||||||
class MWShadow : public osgShadow::ViewDependentShadowMap
|
class MWShadow : public osgShadow::ViewDependentShadowMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const int numberOfShadowMapsPerLight = 3;
|
static const int numberOfShadowMapsPerLight = 3;
|
||||||
|
static const int enableShadows = true;
|
||||||
static const bool debugHud = true;
|
static const bool debugHud = true;
|
||||||
|
|
||||||
MWShadow();
|
MWShadow();
|
||||||
|
@ -16,6 +19,10 @@ namespace SceneUtil
|
||||||
const static int baseShadowTextureUnit = 8 - numberOfShadowMapsPerLight;
|
const static int baseShadowTextureUnit = 8 - numberOfShadowMapsPerLight;
|
||||||
|
|
||||||
virtual void cull(osgUtil::CullVisitor& cv);
|
virtual void cull(osgUtil::CullVisitor& cv);
|
||||||
|
|
||||||
|
virtual Shader::ShaderManager::DefineMap getShadowDefines();
|
||||||
|
|
||||||
|
virtual Shader::ShaderManager::DefineMap getShadowsDisabledDefines();
|
||||||
protected:
|
protected:
|
||||||
const int debugTextureUnit;
|
const int debugTextureUnit;
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,6 @@
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
#include "components/sceneutil/shadow.hpp"
|
|
||||||
|
|
||||||
namespace Shader
|
namespace Shader
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -211,7 +209,7 @@ namespace Shader
|
||||||
return true;
|
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 = '@';
|
const char escapeCharacter = '@';
|
||||||
size_t foundPos = 0;
|
size_t foundPos = 0;
|
||||||
|
@ -226,6 +224,7 @@ namespace Shader
|
||||||
}
|
}
|
||||||
std::string define = source.substr(foundPos+1, endPos - (foundPos+1));
|
std::string define = source.substr(foundPos+1, endPos - (foundPos+1));
|
||||||
ShaderManager::DefineMap::const_iterator defineFound = defines.find(define);
|
ShaderManager::DefineMap::const_iterator defineFound = defines.find(define);
|
||||||
|
ShaderManager::DefineMap::const_iterator globalDefineFound = globalDefines.find(define);
|
||||||
if (define == "foreach")
|
if (define == "foreach")
|
||||||
{
|
{
|
||||||
source.replace(foundPos, 1, "$");
|
source.replace(foundPos, 1, "$");
|
||||||
|
@ -253,44 +252,27 @@ namespace Shader
|
||||||
{
|
{
|
||||||
source.replace(foundPos, 1, "$");
|
source.replace(foundPos, 1, "$");
|
||||||
}
|
}
|
||||||
else if (defineFound == defines.end())
|
else if (defineFound != defines.end())
|
||||||
{
|
{
|
||||||
std::cerr << "Undefined " << define << std::endl;
|
source.replace(foundPos, endPos - foundPos, defineFound->second);
|
||||||
return false;
|
}
|
||||||
|
else if (globalDefineFound != globalDefines.end())
|
||||||
|
{
|
||||||
|
source.replace(foundPos, endPos - foundPos, globalDefineFound->second);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
source.replace(foundPos, endPos-foundPos, defineFound->second);
|
std::cerr << "Undefined " << define << std::endl;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
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);
|
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
|
// read the template if we haven't already
|
||||||
TemplateMap::iterator templateIt = mShaderTemplates.find(shaderTemplate);
|
TemplateMap::iterator templateIt = mShaderTemplates.find(shaderTemplate);
|
||||||
if (templateIt == mShaderTemplates.end())
|
if (templateIt == mShaderTemplates.end())
|
||||||
|
@ -314,11 +296,11 @@ namespace Shader
|
||||||
templateIt = mShaderTemplates.insert(std::make_pair(shaderTemplate, source)).first;
|
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())
|
if (shaderIt == mShaders.end())
|
||||||
{
|
{
|
||||||
std::string shaderSource = templateIt->second;
|
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.
|
// 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));
|
mShaders.insert(std::make_pair(std::make_pair(shaderTemplate, defines), nullptr));
|
||||||
|
@ -331,7 +313,7 @@ namespace Shader
|
||||||
static unsigned int counter = 0;
|
static unsigned int counter = 0;
|
||||||
shader->setName(std::to_string(counter++));
|
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;
|
return shaderIt->second;
|
||||||
}
|
}
|
||||||
|
@ -350,6 +332,17 @@ namespace Shader
|
||||||
return found->second;
|
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)
|
void ShaderManager::releaseGLObjects(osg::State *state)
|
||||||
{
|
{
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
|
||||||
|
|
|
@ -26,18 +26,26 @@ namespace Shader
|
||||||
/// @param shaderTemplate The filename of the shader template.
|
/// @param shaderTemplate The filename of the shader template.
|
||||||
/// @param defines Define values that can be retrieved by 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 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 May return NULL on failure.
|
||||||
/// @note Thread safe.
|
/// @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);
|
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);
|
void releaseGLObjects(osg::State* state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string mPath;
|
std::string mPath;
|
||||||
|
|
||||||
|
DefineMap mGlobalDefines;
|
||||||
|
|
||||||
// <name, code>
|
// <name, code>
|
||||||
typedef std::map<std::string, std::string> TemplateMap;
|
typedef std::map<std::string, std::string> TemplateMap;
|
||||||
TemplateMap mShaderTemplates;
|
TemplateMap mShaderTemplates;
|
||||||
|
|
Loading…
Reference in a new issue