diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 9258b754f7..5449fd4608 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -244,7 +244,7 @@ namespace MWRender for (auto itr = shadowDefines.begin(); itr != shadowDefines.end(); itr++) globalDefines[itr->first] = itr->second; - mResourceSystem->getSceneManager()->getShaderManager().setGlobalDefines(globalDefines); + mResourceSystem->getSceneManager()->getShaderManager().setGlobalDefines(globalDefines, mViewer); mPathgrid.reset(new Pathgrid(mRootNode)); diff --git a/components/shader/shadermanager.cpp b/components/shader/shadermanager.cpp index 3b18d0b756..533b3ae561 100644 --- a/components/shader/shadermanager.cpp +++ b/components/shader/shadermanager.cpp @@ -337,10 +337,29 @@ namespace Shader return DefineMap(mGlobalDefines); } - void ShaderManager::setGlobalDefines(DefineMap & defines) + void ShaderManager::setGlobalDefines(DefineMap & defines, osg::ref_ptr viewer) { mGlobalDefines = defines; - // TODO: We need to trigger the regeneration of all shaders. + bool threadsStarted = viewer->areThreadsRunning(); + if (threadsStarted) + viewer->stopThreading(); + for (auto shaderMapElement: mShaders) + { + std::string templateId = shaderMapElement.first.first; + ShaderManager::DefineMap defines = shaderMapElement.first.second; + osg::ref_ptr shader = shaderMapElement.second; + if (shader == nullptr) + // I'm not sure how to handle a shader that was already broken as there's no way to get a potential replacement to the nodes that need it. + continue; + std::string shaderSource = mShaderTemplates[templateId]; + if (!parseDefines(shaderSource, defines, mGlobalDefines) || !parseFors(shaderSource)) + // We just broke the shader and there's no way to force existing objects back to fixed-function mode as we would when creating the shader. + // If we put a nullptr in the shader map, we just lose the ability to put a working one in later. + continue; + shader->setShaderSource(shaderSource); + } + if (threadsStarted) + viewer->startThreading(); } void ShaderManager::releaseGLObjects(osg::State *state) diff --git a/components/shader/shadermanager.hpp b/components/shader/shadermanager.hpp index baaa738659..16b4d639bb 100644 --- a/components/shader/shadermanager.hpp +++ b/components/shader/shadermanager.hpp @@ -8,6 +8,8 @@ #include +#include + #include namespace Shader @@ -37,7 +39,7 @@ namespace Shader /// Set the DefineMap used to construct all shaders /// @param defines The DefineMap to use - void setGlobalDefines(DefineMap& defines); + void setGlobalDefines(DefineMap & defines, osg::ref_ptr viewer); void releaseGLObjects(osg::State* state);