diff --git a/components/shader/shadermanager.cpp b/components/shader/shadermanager.cpp index fc9a1f722..9c0e70d48 100644 --- a/components/shader/shadermanager.cpp +++ b/components/shader/shadermanager.cpp @@ -3,6 +3,8 @@ #include #include +#include + #include #include #include @@ -78,4 +80,18 @@ namespace Shader return shaderIt->second; } + osg::ref_ptr ShaderManager::getProgram(osg::ref_ptr vertexShader, osg::ref_ptr fragmentShader) + { + OpenThreads::ScopedLock lock(mMutex); + ProgramMap::iterator found = mPrograms.find(std::make_pair(vertexShader, fragmentShader)); + if (found == mPrograms.end()) + { + osg::ref_ptr program (new osg::Program); + program->addShader(vertexShader); + program->addShader(fragmentShader); + found = mPrograms.insert(std::make_pair(std::make_pair(vertexShader, fragmentShader), program)).first; + } + return found->second; + } + } diff --git a/components/shader/shadermanager.hpp b/components/shader/shadermanager.hpp index e0ec3fe5f..5196dbe80 100644 --- a/components/shader/shadermanager.hpp +++ b/components/shader/shadermanager.hpp @@ -30,6 +30,9 @@ namespace Shader /// @note Thread safe. osg::ref_ptr getShader(const std::string& shaderTemplate, const DefineMap& defines, osg::Shader::Type shaderType); + osg::ref_ptr getProgram(osg::ref_ptr vertexShader, osg::ref_ptr fragmentShader); + + private: std::string mPath; @@ -41,6 +44,9 @@ namespace Shader typedef std::map > ShaderMap; ShaderMap mShaders; + typedef std::map, osg::ref_ptr >, osg::ref_ptr > ProgramMap; + ProgramMap mPrograms; + OpenThreads::Mutex mMutex; }; diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index 96357ea9d..a077cb09e 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -131,11 +131,7 @@ namespace Shader if (vertexShader && fragmentShader) { - osg::ref_ptr program (new osg::Program); - program->addShader(vertexShader); - program->addShader(fragmentShader); - - stateset->setAttributeAndModes(program, osg::StateAttribute::ON); + stateset->setAttributeAndModes(mShaderManager.getProgram(vertexShader, fragmentShader), osg::StateAttribute::ON); for (std::map::const_iterator texIt = reqs.mTextures.begin(); texIt != reqs.mTextures.end(); ++texIt) {