mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-30 19:15:41 +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);
|
||||
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));
|
||||
|
||||
|
|
|
@ -712,4 +712,28 @@ namespace SceneUtil
|
|||
|
||||
// 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 <components/shader/shadermanager.hpp>
|
||||
|
||||
namespace SceneUtil
|
||||
{
|
||||
class MWShadow : public osgShadow::ViewDependentShadowMap
|
||||
{
|
||||
public:
|
||||
static const int numberOfShadowMapsPerLight = 3;
|
||||
static const int enableShadows = true;
|
||||
static const bool debugHud = true;
|
||||
|
||||
MWShadow();
|
||||
|
@ -16,6 +19,10 @@ namespace SceneUtil
|
|||
const static int baseShadowTextureUnit = 8 - numberOfShadowMapsPerLight;
|
||||
|
||||
virtual void cull(osgUtil::CullVisitor& cv);
|
||||
|
||||
virtual Shader::ShaderManager::DefineMap getShadowDefines();
|
||||
|
||||
virtual Shader::ShaderManager::DefineMap getShadowsDisabledDefines();
|
||||
protected:
|
||||
const int debugTextureUnit;
|
||||
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
#include <boost/filesystem/fstream.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include "components/sceneutil/shadow.hpp"
|
||||
|
||||
namespace Shader
|
||||
{
|
||||
|
||||
|
@ -211,7 +209,7 @@ namespace Shader
|
|||
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 = '@';
|
||||
size_t foundPos = 0;
|
||||
|
@ -226,6 +224,7 @@ namespace Shader
|
|||
}
|
||||
std::string define = source.substr(foundPos+1, endPos - (foundPos+1));
|
||||
ShaderManager::DefineMap::const_iterator defineFound = defines.find(define);
|
||||
ShaderManager::DefineMap::const_iterator globalDefineFound = globalDefines.find(define);
|
||||
if (define == "foreach")
|
||||
{
|
||||
source.replace(foundPos, 1, "$");
|
||||
|
@ -253,44 +252,27 @@ namespace Shader
|
|||
{
|
||||
source.replace(foundPos, 1, "$");
|
||||
}
|
||||
else if (defineFound == defines.end())
|
||||
else if (defineFound != defines.end())
|
||||
{
|
||||
std::cerr << "Undefined " << define << std::endl;
|
||||
return false;
|
||||
source.replace(foundPos, endPos - foundPos, defineFound->second);
|
||||
}
|
||||
else if (globalDefineFound != globalDefines.end())
|
||||
{
|
||||
source.replace(foundPos, endPos - foundPos, globalDefineFound->second);
|
||||
}
|
||||
else
|
||||
{
|
||||
source.replace(foundPos, endPos-foundPos, defineFound->second);
|
||||
std::cerr << "Undefined " << define << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
// 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
|
||||
TemplateMap::iterator templateIt = mShaderTemplates.find(shaderTemplate);
|
||||
if (templateIt == mShaderTemplates.end())
|
||||
|
@ -314,11 +296,11 @@ namespace Shader
|
|||
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())
|
||||
{
|
||||
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.
|
||||
mShaders.insert(std::make_pair(std::make_pair(shaderTemplate, defines), nullptr));
|
||||
|
@ -331,7 +313,7 @@ namespace Shader
|
|||
static unsigned int counter = 0;
|
||||
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;
|
||||
}
|
||||
|
@ -350,6 +332,17 @@ namespace Shader
|
|||
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)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
|
||||
|
|
|
@ -26,18 +26,26 @@ namespace Shader
|
|||
/// @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).
|
||||
/// @param disableShadows Whether to disable shadows in the shader regardless of the overall setting. False by default.
|
||||
/// @note May return NULL on failure.
|
||||
/// @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);
|
||||
|
||||
/// 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);
|
||||
|
||||
private:
|
||||
std::string mPath;
|
||||
|
||||
DefineMap mGlobalDefines;
|
||||
|
||||
// <name, code>
|
||||
typedef std::map<std::string, std::string> TemplateMap;
|
||||
TemplateMap mShaderTemplates;
|
||||
|
|
Loading…
Reference in a new issue