Make it possible to reinstate FFP state easily

pull/593/head
AnyOldName3 4 years ago
parent b8ee32e317
commit 9be258d260

@ -258,6 +258,8 @@ namespace MWRender
// Keep link to original mesh to keep it in cache
group->getOrCreateUserDataContainer()->addUserObject(new Resource::TemplateRef(temp));
mSceneManager->reinstateRemovedState(node);
InstancingVisitor visitor(pair.second, worldCenter);
node->accept(visitor);
group->addChild(node);

@ -257,6 +257,12 @@ namespace Resource
node->accept(*shaderVisitor);
}
void SceneManager::reinstateRemovedState(osg::ref_ptr<osg::Node> node)
{
osg::ref_ptr<Shader::ReinstateRemovedStateVisitor> reinstateRemovedStateVisitor = new Shader::ReinstateRemovedStateVisitor(false);
node->accept(*reinstateRemovedStateVisitor);
}
void SceneManager::setClampLighting(bool clamp)
{
mClampLighting = clamp;

@ -75,9 +75,14 @@ namespace Resource
Shader::ShaderManager& getShaderManager();
/// Re-create shaders for this node, need to call this if texture stages or vertex color mode have changed.
/// Re-create shaders for this node, need to call this if alpha testing, texture stages or vertex color mode have changed.
void recreateShaders(osg::ref_ptr<osg::Node> node, const std::string& shaderPrefix = "objects", bool translucentFramebuffer = false, bool forceShadersForNode = false);
/// Applying shaders to a node may replace some fixed-function state.
/// This restores it.
/// When editing such state, it should be reinstated before the edits, and shaders should be recreated afterwards.
void reinstateRemovedState(osg::ref_ptr<osg::Node> node);
/// @see ShaderVisitor::setForceShaders
void setForceShaders(bool force);
bool getForceShaders() const;

@ -614,4 +614,43 @@ namespace Shader
mTranslucentFramebuffer = translucent;
}
ReinstateRemovedStateVisitor::ReinstateRemovedStateVisitor(bool allowedToModifyStateSets)
: osg::NodeVisitor(TRAVERSE_ALL_CHILDREN)
, mAllowedToModifyStateSets(allowedToModifyStateSets)
{
}
void ReinstateRemovedStateVisitor::apply(osg::Node& node)
{
if (node.getStateSet())
{
osg::ref_ptr<osg::StateSet> removedState = getRemovedState(*node.getStateSet());
if (removedState)
{
osg::ref_ptr<osg::StateSet> writableStateSet;
if (mAllowedToModifyStateSets)
writableStateSet = node.getStateSet();
else
writableStateSet = getWritableStateSet(node);
// user data is normally shallow copied so shared with the original stateset
osg::ref_ptr<osg::UserDataContainer> writableUserData;
if (mAllowedToModifyStateSets)
writableUserData = writableStateSet->getUserDataContainer();
else
writableUserData = getWritableUserDataContainer(*writableStateSet);
unsigned int index = writableUserData->getUserObjectIndex("removedState");
writableUserData->removeUserObject(index);
for (const auto&[mode, value] : removedState->getModeList())
writableStateSet->setMode(mode, value);
for (const auto& attribute : removedState->getAttributeList())
writableStateSet->setAttribute(attribute.second.first, attribute.second.second);
}
}
traverse(node);
}
}

@ -112,6 +112,17 @@ namespace Shader
bool adjustGeometry(osg::Geometry& sourceGeometry, const ShaderRequirements& reqs);
};
class ReinstateRemovedStateVisitor : public osg::NodeVisitor
{
public:
ReinstateRemovedStateVisitor(bool allowedToModifyStateSets);
void apply(osg::Node& node) override;
private:
bool mAllowedToModifyStateSets;
};
}
#endif

Loading…
Cancel
Save