mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-30 09:15:38 +00:00
allow statesetupdater as cullcallback = faster + works in paging
Signed-off-by: Bret Curtis <psi29a@gmail.com>
This commit is contained in:
parent
4238fbccdf
commit
f12879a04c
10 changed files with 62 additions and 50 deletions
|
@ -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 ©, const osg::CopyOp ©op)
|
||||
: 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…
Reference in a new issue