Avoid setting DYNAMIC DataVariance on StateSets

c++11
scrawl 10 years ago
parent b0ea51a5c8
commit a0b43f426e

@ -291,7 +291,7 @@ void UVController::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (hasInput())
{
osg::StateSet* stateset = node->getStateSet();
osg::StateSet* stateset = getWritableStateSet(node);
float value = getInputValue(nv);
float uTrans = interpKey(mUTrans->mKeys, value, 0.0f);
float vTrans = interpKey(mVTrans->mKeys, value, 0.0f);
@ -372,7 +372,7 @@ void AlphaController::operator () (osg::Node* node, osg::NodeVisitor* nv)
{
if (hasInput())
{
osg::StateSet* stateset = node->getStateSet();
osg::StateSet* stateset = getWritableStateSet(node);
float value = interpKey(mData->mKeys, getInputValue(nv));
osg::Material* mat = dynamic_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
if (mat)
@ -404,7 +404,7 @@ void MaterialColorController::operator() (osg::Node* node, osg::NodeVisitor* nv)
{
if (hasInput())
{
osg::StateSet* stateset = node->getStateSet();
osg::StateSet* stateset = getWritableStateSet(node);
osg::Vec3f value = interpKey(mData->mKeys, getInputValue(nv));
osg::Material* mat = dynamic_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
if (mat)
@ -441,7 +441,7 @@ void FlipController::operator() (osg::Node* node, osg::NodeVisitor* nv)
{
if (hasInput() && mDelta != 0)
{
osg::StateSet* stateset = node->getStateSet();
osg::StateSet* stateset = getWritableStateSet(node);
int curTexture = int(getInputValue(nv) / mDelta) % mTextures.size();
stateset->setTextureAttribute(mTexSlot, mTextures[curTexture]);
}
@ -507,4 +507,12 @@ void SourcedKeyframeController::operator ()(osg::Node* node, osg::NodeVisitor* n
traverse(node, nv);
}
osg::StateSet *StateSetController::getWritableStateSet(osg::Node *node)
{
osg::StateSet* orig = node->getOrCreateStateSet();
osg::StateSet* cloned = new osg::StateSet(*orig, osg::CopyOp::SHALLOW_COPY);
node->setStateSet(cloned);
return cloned;
}
}

@ -189,8 +189,19 @@ namespace NifOsg
bool mEnabled;
};
class StateSetController
{
protected:
// Clones a StateSet to make it "writable". This is to prevent race conditions when the OSG draw thread of the last frame
// queues up a StateSet that we want to modify. Note, we could also set the StateSet to DYNAMIC data variance but that would
// undo all the benefits of the threading model - having the cull and draw traversals run in parallel can yield up to 200% framerates.
// If the StateSet allocations per frame are proving too much of an overhead we could "reuse" StateSets from previous frames,
// kind of like a double buffering scheme.
osg::StateSet* getWritableStateSet(osg::Node* node);
};
// Note we're using NodeCallback instead of StateSet::Callback because the StateSet callback doesn't support nesting
struct UVController : public osg::NodeCallback, public Controller, public ValueInterpolator
class UVController : public osg::NodeCallback, public Controller, public StateSetController, public ValueInterpolator
{
public:
UVController();
@ -226,7 +237,7 @@ namespace NifOsg
virtual void operator() (osg::Node* node, osg::NodeVisitor* nv);
};
class AlphaController : public osg::NodeCallback, public Controller, public ValueInterpolator
class AlphaController : public osg::NodeCallback, public Controller, public StateSetController, public ValueInterpolator
{
private:
Nif::FloatKeyMapPtr mData;
@ -241,7 +252,7 @@ namespace NifOsg
META_Object(NifOsg, AlphaController)
};
class MaterialColorController : public osg::NodeCallback, public Controller, public ValueInterpolator
class MaterialColorController : public osg::NodeCallback, public Controller, public StateSetController, public ValueInterpolator
{
private:
Nif::Vector3KeyMapPtr mData;
@ -256,7 +267,7 @@ namespace NifOsg
virtual void operator() (osg::Node* node, osg::NodeVisitor* nv);
};
class FlipController : public osg::NodeCallback, public Controller
class FlipController : public osg::NodeCallback, public Controller, public StateSetController
{
private:
int mTexSlot;

@ -881,7 +881,6 @@ namespace NifOsg
osg::ref_ptr<UVController> ctrl = new UVController(uvctrl->data.getPtr(), texUnits);
setupController(uvctrl, ctrl, animflags);
transformNode->getOrCreateStateSet()->setDataVariance(osg::StateSet::DYNAMIC);
transformNode->addUpdateCallback(ctrl);
}
@ -927,7 +926,6 @@ namespace NifOsg
const Nif::NiAlphaController* alphactrl = static_cast<const Nif::NiAlphaController*>(ctrl.getPtr());
osg::ref_ptr<AlphaController> ctrl(new AlphaController(alphactrl->data.getPtr()));
setupController(alphactrl, ctrl, animflags);
stateset->setDataVariance(osg::StateSet::DYNAMIC);
node->addUpdateCallback(ctrl);
}
else if (ctrl->recType == Nif::RC_NiMaterialColorController)
@ -935,7 +933,6 @@ namespace NifOsg
const Nif::NiMaterialColorController* matctrl = static_cast<const Nif::NiMaterialColorController*>(ctrl.getPtr());
osg::ref_ptr<MaterialColorController> ctrl(new MaterialColorController(matctrl->data.getPtr()));
setupController(matctrl, ctrl, animflags);
stateset->setDataVariance(osg::StateSet::DYNAMIC);
node->addUpdateCallback(ctrl);
}
else
@ -975,7 +972,6 @@ namespace NifOsg
}
osg::ref_ptr<FlipController> callback(new FlipController(flipctrl, textures));
setupController(ctrl.getPtr(), callback, animflags);
stateset->setDataVariance(osg::StateSet::DYNAMIC);
node->addUpdateCallback(callback);
}
else

Loading…
Cancel
Save