From 5ad297e6ff6f9fae76b3ae2c00d4bc312ed0a0e6 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 3 Dec 2020 18:41:32 +0000 Subject: [PATCH 1/2] Guarantee glow updater regenerates shaders on completion Previously, it would edit the odd numbered stateset, then regenerate shaders for the even-numbered one, then edit the even numbered one, and regenerate shaders for the odd numbered one (or vice versa if it finished during an even numbered frame). This would leave one of the shader programs still trying to use the state that had been removed. --- components/sceneutil/util.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/sceneutil/util.cpp b/components/sceneutil/util.cpp index a23f3f1090..2c0d8efa0c 100644 --- a/components/sceneutil/util.cpp +++ b/components/sceneutil/util.cpp @@ -112,6 +112,8 @@ void GlowUpdater::apply(osg::StateSet *stateset, osg::NodeVisitor *nv) removeTexture(stateset); this->reset(); mDone = true; + // normally done in StateSetUpdater::operator(), but needs doing here so the shader visitor sees the right StateSet + mNode->setStateSet(stateset); mResourceSystem->getSceneManager()->recreateShaders(mNode); } if (mOriginalDuration < 0) // if this glowupdater was originally a permanent glow From 48f397f168ba32965e209c498643413a1533f468 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 3 Dec 2020 21:06:02 +0000 Subject: [PATCH 2/2] Remove existing shader when no longer required --- components/shader/shadervisitor.cpp | 20 ++++++++++++++++++++ components/shader/shadervisitor.hpp | 1 + 2 files changed, 21 insertions(+) diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index 10e9e606e5..e908b6aaa8 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -294,7 +294,10 @@ namespace Shader void ShaderVisitor::createProgram(const ShaderRequirements &reqs) { if (!reqs.mShaderRequired && !mForceShaders) + { + ensureFFP(*reqs.mNode); return; + } osg::Node& node = *reqs.mNode; osg::StateSet* writableStateSet = nullptr; @@ -333,6 +336,19 @@ namespace Shader } } + void ShaderVisitor::ensureFFP(osg::Node& node) + { + if (!node.getStateSet() || !node.getStateSet()->getAttribute(osg::StateAttribute::PROGRAM)) + return; + osg::StateSet* writableStateSet = nullptr; + if (mAllowedToModifyStateSets) + writableStateSet = node.getStateSet(); + else + writableStateSet = getWritableStateSet(node); + + writableStateSet->removeAttribute(osg::StateAttribute::PROGRAM); + } + bool ShaderVisitor::adjustGeometry(osg::Geometry& sourceGeometry, const ShaderRequirements& reqs) { bool useShader = reqs.mShaderRequired || mForceShaders; @@ -380,6 +396,8 @@ namespace Shader createProgram(reqs); } + else + ensureFFP(geometry); if (needPop) popRequirements(); @@ -414,6 +432,8 @@ namespace Shader morph->setSourceGeometry(sourceGeometry); } } + else + ensureFFP(drawable); if (needPop) popRequirements(); diff --git a/components/shader/shadervisitor.hpp b/components/shader/shadervisitor.hpp index 6b2353b662..6031dbfe6c 100644 --- a/components/shader/shadervisitor.hpp +++ b/components/shader/shadervisitor.hpp @@ -94,6 +94,7 @@ namespace Shader std::string mDefaultFsTemplate; void createProgram(const ShaderRequirements& reqs); + void ensureFFP(osg::Node& node); bool adjustGeometry(osg::Geometry& sourceGeometry, const ShaderRequirements& reqs); };