From 681026ba1c2bbeca29a0ff2a9671fb509d689706 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 8 Mar 2023 00:28:48 +0000 Subject: [PATCH] Ensure shader requirements are pushed at least once for subgraph Shaders, if deemed necessary, get attached to the node mentioned by the top of the requirements stack. Previously an empty stack was incorrectly assumed to mean no shaders were required, but we found out that was wrong. We need to put shaders *somewhere*, and the root of the subgraph we're modifying should be the best place. --- components/shader/shadervisitor.cpp | 71 ++++++++++++++--------------- 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index 7a949aac80..18ba0e6569 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -185,15 +185,17 @@ namespace Shader void ShaderVisitor::apply(osg::Node& node) { - if (node.getStateSet()) + bool needPop = false; + if (node.getStateSet() || mRequirements.empty()) { + needPop = true; pushRequirements(node); - applyStateSet(node.getStateSet(), node); - traverse(node); - popRequirements(); + if (node.getStateSet()) + applyStateSet(node.getStateSet(), node); } - else - traverse(node); + traverse(node); + if (needPop) + popRequirements(); } osg::StateSet* getWritableStateSet(osg::Node& node) @@ -820,12 +822,12 @@ namespace Shader void ShaderVisitor::apply(osg::Geometry& geometry) { - bool needPop = (geometry.getStateSet() != nullptr); - if (geometry.getStateSet()) // TODO: check if stateset affects shader permutation before pushing it - { + bool needPop = geometry.getStateSet() || mRequirements.empty(); + if (needPop) pushRequirements(geometry); + + if (geometry.getStateSet()) // TODO: check if stateset affects shader permutation before pushing it applyStateSet(geometry.getStateSet(), geometry); - } if (!mRequirements.empty()) { @@ -844,7 +846,7 @@ namespace Shader void ShaderVisitor::apply(osg::Drawable& drawable) { - bool needPop = drawable.getStateSet(); + bool needPop = drawable.getStateSet() || mRequirements.empty(); if (needPop) { @@ -854,37 +856,32 @@ namespace Shader applyStateSet(drawable.getStateSet(), drawable); } - if (!mRequirements.empty()) - { - const ShaderRequirements& reqs = mRequirements.back(); - createProgram(reqs); + const ShaderRequirements& reqs = mRequirements.back(); + createProgram(reqs); - if (auto rig = dynamic_cast(&drawable)) + if (auto rig = dynamic_cast(&drawable)) + { + osg::ref_ptr sourceGeometry = rig->getSourceGeometry(); + if (sourceGeometry && adjustGeometry(*sourceGeometry, reqs)) + rig->setSourceGeometry(sourceGeometry); + } + else if (auto morph = dynamic_cast(&drawable)) + { + osg::ref_ptr sourceGeometry = morph->getSourceGeometry(); + if (sourceGeometry && adjustGeometry(*sourceGeometry, reqs)) + morph->setSourceGeometry(sourceGeometry); + } + else if (auto osgaRig = dynamic_cast(&drawable)) + { + osg::ref_ptr sourceOsgaRigGeometry = osgaRig->getSourceRigGeometry(); + osg::ref_ptr sourceGeometry = sourceOsgaRigGeometry->getSourceGeometry(); + if (sourceGeometry && adjustGeometry(*sourceGeometry, reqs)) { - osg::ref_ptr sourceGeometry = rig->getSourceGeometry(); - if (sourceGeometry && adjustGeometry(*sourceGeometry, reqs)) - rig->setSourceGeometry(sourceGeometry); - } - else if (auto morph = dynamic_cast(&drawable)) - { - osg::ref_ptr sourceGeometry = morph->getSourceGeometry(); - if (sourceGeometry && adjustGeometry(*sourceGeometry, reqs)) - morph->setSourceGeometry(sourceGeometry); - } - else if (auto osgaRig = dynamic_cast(&drawable)) - { - osg::ref_ptr sourceOsgaRigGeometry = osgaRig->getSourceRigGeometry(); - osg::ref_ptr sourceGeometry = sourceOsgaRigGeometry->getSourceGeometry(); - if (sourceGeometry && adjustGeometry(*sourceGeometry, reqs)) - { - sourceOsgaRigGeometry->setSourceGeometry(sourceGeometry); - osgaRig->setSourceRigGeometry(sourceOsgaRigGeometry); - } + sourceOsgaRigGeometry->setSourceGeometry(sourceGeometry); + osgaRig->setSourceRigGeometry(sourceOsgaRigGeometry); } } - else - ensureFFP(drawable); if (needPop) popRequirements();