allow statesetupdater as cullcallback = faster + works in paging

Signed-off-by: Bret Curtis <psi29a@gmail.com>
pull/2911/head
bzzt lost a hitlab login 5 years ago committed by Bret Curtis
parent 4238fbccdf
commit f12879a04c

@ -513,6 +513,9 @@ namespace MWRender
if (mShadowUniform)
stateset->addUniform(mShadowUniform);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
stateset->setRenderBinMode(osg::StateSet::OVERRIDE_RENDERBIN_DETAILS);
// FIXME: overriding diffuse/ambient/emissive colors
osg::Material* material = new osg::Material;
material->setColorMode(osg::Material::OFF);
@ -1741,31 +1744,16 @@ namespace MWRender
if (mTransparencyUpdater == nullptr)
{
mTransparencyUpdater = new TransparencyUpdater(alpha, mResourceSystem->getSceneManager()->getShaderManager().getShadowMapAlphaTestEnableUniform());
mObjectRoot->addUpdateCallback(mTransparencyUpdater);
mObjectRoot->addCullCallback(mTransparencyUpdater);
}
else
mTransparencyUpdater->setAlpha(alpha);
}
else
{
mObjectRoot->removeUpdateCallback(mTransparencyUpdater);
mObjectRoot->removeCullCallback(mTransparencyUpdater);
mTransparencyUpdater = nullptr;
mObjectRoot->setStateSet(nullptr);
}
setRenderBin();
}
void Animation::setRenderBin()
{
if (mAlpha != 1.f)
{
osg::StateSet* stateset = mObjectRoot->getOrCreateStateSet();
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
stateset->setRenderBinMode(osg::StateSet::OVERRIDE_RENDERBIN_DETAILS);
}
else if (osg::StateSet* stateset = mObjectRoot->getStateSet())
stateset->setRenderBinToInherit();
}
void Animation::setLightEffect(float effect)

@ -336,9 +336,6 @@ protected:
*/
virtual void addControllers();
/// Set the render bin for this animation's object root. May be customized by subclasses.
virtual void setRenderBin();
public:
Animation(const MWWorld::Ptr &ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem);

@ -435,12 +435,10 @@ void NpcAnimation::setRenderBin()
osgUtil::RenderBin::addRenderBinPrototype("DepthClear", depthClearBin);
prototypeAdded = true;
}
osg::StateSet* stateset = mObjectRoot->getOrCreateStateSet();
stateset->setRenderBinDetails(RenderBin_FirstPerson, "DepthClear", osg::StateSet::OVERRIDE_RENDERBIN_DETAILS);
mObjectRoot->getOrCreateStateSet()->setRenderBinDetails(RenderBin_FirstPerson, "DepthClear", osg::StateSet::OVERRIDE_RENDERBIN_DETAILS);
}
else
Animation::setRenderBin();
else if (osg::StateSet* stateset = mObjectRoot->getStateSet())
stateset->setRenderBinToInherit();
}
void NpcAnimation::rebuild()

@ -88,7 +88,7 @@ private:
void addPartGroup(int group, int priority, const std::vector<ESM::PartReference> &parts,
bool enchantedGlow=false, osg::Vec4f* glowColor=nullptr);
virtual void setRenderBin();
void setRenderBin();
osg::ref_ptr<NeckController> mFirstPersonNeckController;

@ -162,6 +162,17 @@ namespace MWRender
{
if (callback->className() == std::string("BillboardCallback"))
handleBillboard(cloned);
else
{
if (node->getCullCallback()->getNestedCallback())
{
osg::Callback *clonedCallback = osg::clone(callback, osg::CopyOp::SHALLOW_COPY);
clonedCallback->setNestedCallback(nullptr);
cloned->addCullCallback(clonedCallback);
}
else
cloned->addCullCallback(const_cast<osg::Callback*>(callback));
}
callback = callback->getNestedCallback();
}
}

@ -352,8 +352,9 @@ void RollController::operator() (osg::Node* node, osg::NodeVisitor* nv)
}
}
AlphaController::AlphaController(const Nif::NiFloatData *data)
AlphaController::AlphaController(const Nif::NiFloatData *data, const osg::Material* baseMaterial)
: mData(data->mKeyList, 1.f)
, mBaseMaterial(baseMaterial)
{
}
@ -365,14 +366,13 @@ AlphaController::AlphaController()
AlphaController::AlphaController(const AlphaController &copy, const osg::CopyOp &copyop)
: StateSetUpdater(copy, copyop), Controller(copy)
, mData(copy.mData)
, mBaseMaterial(copy.mBaseMaterial)
{
}
void AlphaController::setDefaults(osg::StateSet *stateset)
{
// need to create a deep copy of StateAttributes we will modify
osg::Material* mat = static_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
stateset->setAttribute(osg::clone(mat, osg::CopyOp::DEEP_COPY_ALL), osg::StateAttribute::ON);
stateset->setAttribute(osg::clone(mBaseMaterial.get(), osg::CopyOp::DEEP_COPY_ALL), osg::StateAttribute::ON);
}
void AlphaController::apply(osg::StateSet *stateset, osg::NodeVisitor *nv)
@ -387,9 +387,10 @@ void AlphaController::apply(osg::StateSet *stateset, osg::NodeVisitor *nv)
}
}
MaterialColorController::MaterialColorController(const Nif::NiPosData *data, TargetColor color)
MaterialColorController::MaterialColorController(const Nif::NiPosData *data, TargetColor color, const osg::Material* baseMaterial)
: mData(data->mKeyList, osg::Vec3f(1,1,1))
, mTargetColor(color)
, mBaseMaterial(baseMaterial)
{
}
@ -401,14 +402,13 @@ MaterialColorController::MaterialColorController(const MaterialColorController &
: StateSetUpdater(copy, copyop), Controller(copy)
, mData(copy.mData)
, mTargetColor(copy.mTargetColor)
, mBaseMaterial(copy.mBaseMaterial)
{
}
void MaterialColorController::setDefaults(osg::StateSet *stateset)
{
// need to create a deep copy of StateAttributes we will modify
osg::Material* mat = static_cast<osg::Material*>(stateset->getAttribute(osg::StateAttribute::MATERIAL));
stateset->setAttribute(osg::clone(mat, osg::CopyOp::DEEP_COPY_ALL), osg::StateAttribute::ON);
stateset->setAttribute(osg::clone(mBaseMaterial.get(), osg::CopyOp::DEEP_COPY_ALL), osg::StateAttribute::ON);
}
void MaterialColorController::apply(osg::StateSet *stateset, osg::NodeVisitor *nv)

@ -24,6 +24,7 @@ namespace osg
{
class Node;
class StateSet;
class Material;
}
namespace osgParticle
@ -268,9 +269,9 @@ namespace NifOsg
{
private:
FloatInterpolator mData;
osg::ref_ptr<const osg::Material> mBaseMaterial;
public:
AlphaController(const Nif::NiFloatData *data);
AlphaController(const Nif::NiFloatData *data, const osg::Material* baseMaterial);
AlphaController();
AlphaController(const AlphaController& copy, const osg::CopyOp& copyop);
@ -291,7 +292,7 @@ namespace NifOsg
Specular = 2,
Emissive = 3
};
MaterialColorController(const Nif::NiPosData *data, TargetColor color);
MaterialColorController(const Nif::NiPosData *data, TargetColor color, const osg::Material* baseMaterial);
MaterialColorController();
MaterialColorController(const MaterialColorController& copy, const osg::CopyOp& copyop);
@ -304,6 +305,7 @@ namespace NifOsg
private:
Vec3Interpolator mData;
TargetColor mTargetColor = Ambient;
osg::ref_ptr<const osg::Material> mBaseMaterial;
};
class FlipController : public SceneUtil::StateSetUpdater, public SceneUtil::Controller

@ -639,7 +639,15 @@ namespace NifOsg
handleParticleSystem(nifNode, node, composite, animflags, rootNode);
if (composite->getNumControllers() > 0)
node->addUpdateCallback(composite);
{
osg::Callback *cb = composite;
if (composite->getNumControllers() == 1)
cb = composite->getController(0);
if (animflags & Nif::NiNode::AnimFlag_AutoPlay)
node->addCullCallback(cb);
else
node->addUpdateCallback(cb); // have to remain as UpdateCallback so AssignControllerSourcesVisitor can find it.
}
bool isAnimated = false;
handleNodeControllers(nifNode, node, animflags, isAnimated);
@ -778,7 +786,7 @@ namespace NifOsg
}
}
void handleMaterialControllers(const Nif::Property *materialProperty, SceneUtil::CompositeStateSetUpdater* composite, int animflags)
void handleMaterialControllers(const Nif::Property *materialProperty, SceneUtil::CompositeStateSetUpdater* composite, int animflags, const osg::Material* baseMaterial)
{
for (Nif::ControllerPtr ctrl = materialProperty->controller; !ctrl.empty(); ctrl = ctrl->next)
{
@ -789,7 +797,7 @@ namespace NifOsg
const Nif::NiAlphaController* alphactrl = static_cast<const Nif::NiAlphaController*>(ctrl.getPtr());
if (alphactrl->data.empty())
continue;
osg::ref_ptr<AlphaController> osgctrl(new AlphaController(alphactrl->data.getPtr()));
osg::ref_ptr<AlphaController> osgctrl(new AlphaController(alphactrl->data.getPtr(), baseMaterial));
setupController(alphactrl, osgctrl, animflags);
composite->addController(osgctrl);
}
@ -799,7 +807,7 @@ namespace NifOsg
if (matctrl->data.empty())
continue;
auto targetColor = static_cast<MaterialColorController::TargetColor>(matctrl->targetColor);
osg::ref_ptr<MaterialColorController> osgctrl(new MaterialColorController(matctrl->data.getPtr(), targetColor));
osg::ref_ptr<MaterialColorController> osgctrl(new MaterialColorController(matctrl->data.getPtr(), targetColor, baseMaterial));
setupController(matctrl, osgctrl, animflags);
composite->addController(osgctrl);
}
@ -1767,7 +1775,7 @@ namespace NifOsg
if (!matprop->controller.empty())
{
hasMatCtrl = true;
handleMaterialControllers(matprop, composite, animflags);
handleMaterialControllers(matprop, composite, animflags, mat);
}
break;

@ -2,30 +2,38 @@
#include <osg/Node>
#include <osg/NodeVisitor>
#include <osgUtil/CullVisitor>
namespace SceneUtil
{
void StateSetUpdater::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
bool isCullVisitor = nv->getVisitorType() == osg::NodeVisitor::CULL_VISITOR;
if (!mStateSets[0])
{
// first time setup
osg::StateSet* src = node->getOrCreateStateSet();
for (int i=0; i<2; ++i) // Using SHALLOW_COPY for StateAttributes, if users want to modify it is their responsibility to set a non-shared one first
// This can be done conveniently in user implementations of the setDefaults() method
for (int i=0; i<2; ++i)
{
mStateSets[i] = new osg::StateSet(*src, osg::CopyOp::SHALLOW_COPY);
if (!isCullVisitor)
mStateSets[i] = new osg::StateSet(*node->getOrCreateStateSet(), osg::CopyOp::SHALLOW_COPY); // Using SHALLOW_COPY for StateAttributes, if users want to modify it is their responsibility to set a non-shared one first in setDefaults
else
mStateSets[i] = new osg::StateSet;
setDefaults(mStateSets[i]);
}
}
osg::StateSet* stateset = mStateSets[nv->getTraversalNumber()%2];
node->setStateSet(stateset);
apply(stateset, nv);
if (!isCullVisitor)
node->setStateSet(stateset);
else
static_cast<osgUtil::CullVisitor*>(nv)->pushStateSet(stateset);
traverse(node, nv);
if (isCullVisitor)
static_cast<osgUtil::CullVisitor*>(nv)->popStateSet();
}
void StateSetUpdater::reset()

@ -13,7 +13,7 @@ namespace SceneUtil
/// traversals run in parallel can yield up to 200% framerates.
/// @par Race conditions are prevented using a "double buffering" scheme - we have two StateSets that take turns,
/// one StateSet we can write to, the second one is currently in use by the draw traversal of the last frame.
/// @par Must be set as UpdateCallback on a Node.
/// @par Must be set as UpdateCallback or CullCallback on a Node. If set as a CullCallback, the StateSetUpdater operates on an empty StateSet, otherwise it operates on a clone of the node's existing StateSet.
/// @note Do not add the same StateSetUpdater to multiple nodes.
/// @note Do not add multiple StateSetControllers on the same Node as they will conflict - instead use the CompositeStateSetUpdater.
class StateSetUpdater : public osg::NodeCallback

Loading…
Cancel
Save