mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-21 09:09:43 +00:00
Avoid setting DYNAMIC DataVariance on StateSets
This commit is contained in:
parent
b0ea51a5c8
commit
a0b43f426e
3 changed files with 27 additions and 12 deletions
|
@ -291,7 +291,7 @@ void UVController::operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||||
{
|
{
|
||||||
if (hasInput())
|
if (hasInput())
|
||||||
{
|
{
|
||||||
osg::StateSet* stateset = node->getStateSet();
|
osg::StateSet* stateset = getWritableStateSet(node);
|
||||||
float value = getInputValue(nv);
|
float value = getInputValue(nv);
|
||||||
float uTrans = interpKey(mUTrans->mKeys, value, 0.0f);
|
float uTrans = interpKey(mUTrans->mKeys, value, 0.0f);
|
||||||
float vTrans = interpKey(mVTrans->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())
|
if (hasInput())
|
||||||
{
|
{
|
||||||
osg::StateSet* stateset = node->getStateSet();
|
osg::StateSet* stateset = getWritableStateSet(node);
|
||||||
float value = interpKey(mData->mKeys, getInputValue(nv));
|
float value = interpKey(mData->mKeys, getInputValue(nv));
|
||||||
osg::Material* mat = dynamic_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
|
osg::Material* mat = dynamic_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
|
||||||
if (mat)
|
if (mat)
|
||||||
|
@ -404,7 +404,7 @@ void MaterialColorController::operator() (osg::Node* node, osg::NodeVisitor* nv)
|
||||||
{
|
{
|
||||||
if (hasInput())
|
if (hasInput())
|
||||||
{
|
{
|
||||||
osg::StateSet* stateset = node->getStateSet();
|
osg::StateSet* stateset = getWritableStateSet(node);
|
||||||
osg::Vec3f value = interpKey(mData->mKeys, getInputValue(nv));
|
osg::Vec3f value = interpKey(mData->mKeys, getInputValue(nv));
|
||||||
osg::Material* mat = dynamic_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
|
osg::Material* mat = dynamic_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
|
||||||
if (mat)
|
if (mat)
|
||||||
|
@ -441,7 +441,7 @@ void FlipController::operator() (osg::Node* node, osg::NodeVisitor* nv)
|
||||||
{
|
{
|
||||||
if (hasInput() && mDelta != 0)
|
if (hasInput() && mDelta != 0)
|
||||||
{
|
{
|
||||||
osg::StateSet* stateset = node->getStateSet();
|
osg::StateSet* stateset = getWritableStateSet(node);
|
||||||
int curTexture = int(getInputValue(nv) / mDelta) % mTextures.size();
|
int curTexture = int(getInputValue(nv) / mDelta) % mTextures.size();
|
||||||
stateset->setTextureAttribute(mTexSlot, mTextures[curTexture]);
|
stateset->setTextureAttribute(mTexSlot, mTextures[curTexture]);
|
||||||
}
|
}
|
||||||
|
@ -507,4 +507,12 @@ void SourcedKeyframeController::operator ()(osg::Node* node, osg::NodeVisitor* n
|
||||||
traverse(node, nv);
|
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;
|
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
|
// 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:
|
public:
|
||||||
UVController();
|
UVController();
|
||||||
|
@ -226,7 +237,7 @@ namespace NifOsg
|
||||||
virtual void operator() (osg::Node* node, osg::NodeVisitor* nv);
|
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:
|
private:
|
||||||
Nif::FloatKeyMapPtr mData;
|
Nif::FloatKeyMapPtr mData;
|
||||||
|
@ -241,7 +252,7 @@ namespace NifOsg
|
||||||
META_Object(NifOsg, AlphaController)
|
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:
|
private:
|
||||||
Nif::Vector3KeyMapPtr mData;
|
Nif::Vector3KeyMapPtr mData;
|
||||||
|
@ -256,7 +267,7 @@ namespace NifOsg
|
||||||
virtual void operator() (osg::Node* node, osg::NodeVisitor* nv);
|
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:
|
private:
|
||||||
int mTexSlot;
|
int mTexSlot;
|
||||||
|
|
|
@ -881,7 +881,6 @@ namespace NifOsg
|
||||||
|
|
||||||
osg::ref_ptr<UVController> ctrl = new UVController(uvctrl->data.getPtr(), texUnits);
|
osg::ref_ptr<UVController> ctrl = new UVController(uvctrl->data.getPtr(), texUnits);
|
||||||
setupController(uvctrl, ctrl, animflags);
|
setupController(uvctrl, ctrl, animflags);
|
||||||
transformNode->getOrCreateStateSet()->setDataVariance(osg::StateSet::DYNAMIC);
|
|
||||||
|
|
||||||
transformNode->addUpdateCallback(ctrl);
|
transformNode->addUpdateCallback(ctrl);
|
||||||
}
|
}
|
||||||
|
@ -927,7 +926,6 @@ namespace NifOsg
|
||||||
const Nif::NiAlphaController* alphactrl = static_cast<const Nif::NiAlphaController*>(ctrl.getPtr());
|
const Nif::NiAlphaController* alphactrl = static_cast<const Nif::NiAlphaController*>(ctrl.getPtr());
|
||||||
osg::ref_ptr<AlphaController> ctrl(new AlphaController(alphactrl->data.getPtr()));
|
osg::ref_ptr<AlphaController> ctrl(new AlphaController(alphactrl->data.getPtr()));
|
||||||
setupController(alphactrl, ctrl, animflags);
|
setupController(alphactrl, ctrl, animflags);
|
||||||
stateset->setDataVariance(osg::StateSet::DYNAMIC);
|
|
||||||
node->addUpdateCallback(ctrl);
|
node->addUpdateCallback(ctrl);
|
||||||
}
|
}
|
||||||
else if (ctrl->recType == Nif::RC_NiMaterialColorController)
|
else if (ctrl->recType == Nif::RC_NiMaterialColorController)
|
||||||
|
@ -935,7 +933,6 @@ namespace NifOsg
|
||||||
const Nif::NiMaterialColorController* matctrl = static_cast<const Nif::NiMaterialColorController*>(ctrl.getPtr());
|
const Nif::NiMaterialColorController* matctrl = static_cast<const Nif::NiMaterialColorController*>(ctrl.getPtr());
|
||||||
osg::ref_ptr<MaterialColorController> ctrl(new MaterialColorController(matctrl->data.getPtr()));
|
osg::ref_ptr<MaterialColorController> ctrl(new MaterialColorController(matctrl->data.getPtr()));
|
||||||
setupController(matctrl, ctrl, animflags);
|
setupController(matctrl, ctrl, animflags);
|
||||||
stateset->setDataVariance(osg::StateSet::DYNAMIC);
|
|
||||||
node->addUpdateCallback(ctrl);
|
node->addUpdateCallback(ctrl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -975,7 +972,6 @@ namespace NifOsg
|
||||||
}
|
}
|
||||||
osg::ref_ptr<FlipController> callback(new FlipController(flipctrl, textures));
|
osg::ref_ptr<FlipController> callback(new FlipController(flipctrl, textures));
|
||||||
setupController(ctrl.getPtr(), callback, animflags);
|
setupController(ctrl.getPtr(), callback, animflags);
|
||||||
stateset->setDataVariance(osg::StateSet::DYNAMIC);
|
|
||||||
node->addUpdateCallback(callback);
|
node->addUpdateCallback(callback);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue