From 2e031f195b571d8133b82c11b508e42c6bf0b9d8 Mon Sep 17 00:00:00 2001 From: Bo Svensson <90132211+bosvensson1@users.noreply.github.com> Date: Sun, 7 Nov 2021 17:26:02 +0000 Subject: [PATCH] fixes LightBufferBinding messages (#3223) This PR aims to solve `uniform block LightBufferBinding has no binding` messages @glassmancody has reportedly encountered since PR #3110 due to an apparent bug in OSG. While we do have to add a workaround here that adds a bit of clunkiness, #3216 should allow us to clean up these interactions a bit in the future. --- apps/openmw/mwrender/groundcover.cpp | 2 +- components/shader/shadermanager.cpp | 10 +++++++++- components/shader/shadermanager.hpp | 3 +++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/groundcover.cpp b/apps/openmw/mwrender/groundcover.cpp index 77c4f0fab5..e2d1f0c50d 100644 --- a/apps/openmw/mwrender/groundcover.cpp +++ b/apps/openmw/mwrender/groundcover.cpp @@ -152,7 +152,7 @@ namespace MWRender mStateset->setAttribute(new osg::VertexAttribDivisor(6, 1)); mStateset->setAttribute(new osg::VertexAttribDivisor(7, 1)); - mProgramTemplate = mSceneManager->getShaderManager().getProgramTemplate() ? static_cast(mSceneManager->getShaderManager().getProgramTemplate()->clone(osg::CopyOp::SHALLOW_COPY)) : new osg::Program; + mProgramTemplate = mSceneManager->getShaderManager().getProgramTemplate() ? Shader::ShaderManager::cloneProgram(mSceneManager->getShaderManager().getProgramTemplate()) : osg::ref_ptr(new osg::Program); mProgramTemplate->addBindAttribLocation("aOffset", 6); mProgramTemplate->addBindAttribLocation("aRotation", 7); } diff --git a/components/shader/shadermanager.cpp b/components/shader/shadermanager.cpp index e057cfac02..30c7ed1b1d 100644 --- a/components/shader/shadermanager.cpp +++ b/components/shader/shadermanager.cpp @@ -345,7 +345,7 @@ namespace Shader if (found == mPrograms.end()) { if (!programTemplate) programTemplate = mProgramTemplate; - osg::ref_ptr program = programTemplate ? static_cast(programTemplate->clone(osg::CopyOp::SHALLOW_COPY)) : new osg::Program; + osg::ref_ptr program = programTemplate ? cloneProgram(programTemplate) : osg::ref_ptr(new osg::Program); program->addShader(vertexShader); program->addShader(fragmentShader); found = mPrograms.insert(std::make_pair(std::make_pair(vertexShader, fragmentShader), program)).first; @@ -353,6 +353,14 @@ namespace Shader return found->second; } + osg::ref_ptr ShaderManager::cloneProgram(const osg::Program* src) + { + osg::ref_ptr program = static_cast(src->clone(osg::CopyOp::SHALLOW_COPY)); + for (auto [name, idx] : src->getUniformBlockBindingList()) + program->addBindUniformBlock(name, idx); + return program; + } + ShaderManager::DefineMap ShaderManager::getGlobalDefines() { return DefineMap(mGlobalDefines); diff --git a/components/shader/shadermanager.hpp b/components/shader/shadermanager.hpp index d0ee069b10..613f33b168 100644 --- a/components/shader/shadermanager.hpp +++ b/components/shader/shadermanager.hpp @@ -38,6 +38,9 @@ namespace Shader 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 cloneProgram(const osg::Program*); + /// Get (a copy of) the DefineMap used to construct all shaders DefineMap getGlobalDefines();