mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2024-12-28 00:15:06 +00:00
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.
This commit is contained in:
parent
aee1edaf9e
commit
ccdb1bf6b7
@ -212,15 +212,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)
|
||||
@ -865,12 +867,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())
|
||||
{
|
||||
@ -889,7 +891,7 @@ namespace Shader
|
||||
|
||||
void ShaderVisitor::apply(osg::Drawable& drawable)
|
||||
{
|
||||
bool needPop = drawable.getStateSet();
|
||||
bool needPop = drawable.getStateSet() || mRequirements.empty();
|
||||
|
||||
if (needPop)
|
||||
{
|
||||
@ -899,36 +901,31 @@ 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))
|
||||
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<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))
|
||||
{
|
||||
sourceOsgaRigGeometry->setSourceGeometry(sourceGeometry);
|
||||
osgaRig->setSourceRigGeometry(sourceOsgaRigGeometry);
|
||||
}
|
||||
sourceOsgaRigGeometry->setSourceGeometry(sourceGeometry);
|
||||
osgaRig->setSourceRigGeometry(sourceOsgaRigGeometry);
|
||||
}
|
||||
}
|
||||
else
|
||||
ensureFFP(drawable);
|
||||
|
||||
if (needPop)
|
||||
popRequirements();
|
||||
|
Loading…
Reference in New Issue
Block a user