diff --git a/components/shader/shadervisitor.cpp b/components/shader/shadervisitor.cpp index e904e4b75a..06f246e9bc 100644 --- a/components/shader/shadervisitor.cpp +++ b/components/shader/shadervisitor.cpp @@ -865,51 +865,73 @@ namespace Shader void ShaderVisitor::apply(osg::Geometry& geometry) { - pushRequirements(geometry); + bool needPop = (geometry.getStateSet() != nullptr); if (geometry.getStateSet()) // TODO: check if stateset affects shader permutation before pushing it + { + pushRequirements(geometry); applyStateSet(geometry.getStateSet(), geometry); + } - const ShaderRequirements& reqs = mRequirements.back(); - adjustGeometry(geometry, reqs); - createProgram(reqs); + if (!mRequirements.empty()) + { + const ShaderRequirements& reqs = mRequirements.back(); - popRequirements(); + adjustGeometry(geometry, reqs); + + createProgram(reqs); + } + else + ensureFFP(geometry); + + if (needPop) + popRequirements(); } void ShaderVisitor::apply(osg::Drawable& drawable) { - pushRequirements(drawable); + bool needPop = drawable.getStateSet(); - if (drawable.getStateSet()) - applyStateSet(drawable.getStateSet(), drawable); - - const ShaderRequirements& reqs = mRequirements.back(); - createProgram(reqs); - - if (auto rig = dynamic_cast(&drawable)) + if (needPop) { - osg::ref_ptr sourceGeometry = rig->getSourceGeometry(); - if (sourceGeometry && adjustGeometry(*sourceGeometry, reqs)) - rig->setSourceGeometry(sourceGeometry); + pushRequirements(drawable); + + if (drawable.getStateSet()) + applyStateSet(drawable.getStateSet(), drawable); } - else if (auto morph = dynamic_cast(&drawable)) + + if (!mRequirements.empty()) { - 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)) + const ShaderRequirements& reqs = mRequirements.back(); + createProgram(reqs); + + if (auto rig = dynamic_cast(&drawable)) { - sourceOsgaRigGeometry->setSourceGeometry(sourceGeometry); - osgaRig->setSourceRigGeometry(sourceOsgaRigGeometry); + 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); + } } } + else + ensureFFP(drawable); - popRequirements(); + if (needPop) + popRequirements(); } void ShaderVisitor::setAllowedToModifyStateSets(bool allowed)