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.
backport_gl_clamp_removal
AnyOldName3 1 year ago
parent c223b214bd
commit 681026ba1c

@ -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<SceneUtil::RigGeometry*>(&drawable))
{
osg::ref_ptr<osg::Geometry> sourceGeometry = rig->getSourceGeometry();
if (sourceGeometry && adjustGeometry(*sourceGeometry, reqs))
rig->setSourceGeometry(sourceGeometry);
}
else if (auto morph = dynamic_cast<SceneUtil::MorphGeometry*>(&drawable))
{
osg::ref_ptr<osg::Geometry> sourceGeometry = morph->getSourceGeometry();
if (sourceGeometry && adjustGeometry(*sourceGeometry, reqs))
morph->setSourceGeometry(sourceGeometry);
}
else if (auto osgaRig = dynamic_cast<SceneUtil::RigGeometryHolder*>(&drawable))
if (auto rig = dynamic_cast<SceneUtil::RigGeometry*>(&drawable))
{
osg::ref_ptr<osg::Geometry> sourceGeometry = rig->getSourceGeometry();
if (sourceGeometry && adjustGeometry(*sourceGeometry, reqs))
rig->setSourceGeometry(sourceGeometry);
}
else if (auto morph = dynamic_cast<SceneUtil::MorphGeometry*>(&drawable))
{
osg::ref_ptr<osg::Geometry> sourceGeometry = morph->getSourceGeometry();
if (sourceGeometry && adjustGeometry(*sourceGeometry, reqs))
morph->setSourceGeometry(sourceGeometry);
}
else if (auto osgaRig = dynamic_cast<SceneUtil::RigGeometryHolder*>(&drawable))
{
osg::ref_ptr<SceneUtil::OsgaRigGeometry> sourceOsgaRigGeometry = osgaRig->getSourceRigGeometry();
osg::ref_ptr<osg::Geometry> sourceGeometry = sourceOsgaRigGeometry->getSourceGeometry();
if (sourceGeometry && adjustGeometry(*sourceGeometry, reqs))
{
osg::ref_ptr<SceneUtil::OsgaRigGeometry> sourceOsgaRigGeometry = osgaRig->getSourceRigGeometry();
osg::ref_ptr<osg::Geometry> 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();

Loading…
Cancel
Save