Implement a custom RenderBin for first person models (Fixes #1612)

openmw-37
scrawl 9 years ago
parent 2ee6b41887
commit 6ef139e1d7

@ -1275,15 +1275,26 @@ namespace MWRender
material->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1));
stateset->setAttributeAndModes(material, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
stateset->setRenderBinMode(osg::StateSet::OVERRIDE_RENDERBIN_DETAILS);
stateset->setNestRenderBins(false);
mObjectRoot->setStateSet(stateset);
}
else
{
mObjectRoot->setStateSet(NULL);
}
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)

@ -307,6 +307,9 @@ protected:
void addGlow(osg::ref_ptr<osg::Node> node, osg::Vec4f glowColor);
/// 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);

@ -2,6 +2,9 @@
#include <osg/UserDataContainer>
#include <osg/MatrixTransform>
#include <osg/Depth>
#include <osgUtil/RenderBin>
#include <components/misc/rng.hpp>
@ -28,6 +31,7 @@
#include "camera.hpp"
#include "rotatecontroller.hpp"
#include "renderbin.hpp"
namespace
{
@ -303,6 +307,50 @@ void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode)
mViewMode = viewMode;
rebuild();
setRenderBin();
}
/// @brief A RenderBin callback to clear the depth buffer before rendering.
class DepthClearCallback : public osgUtil::RenderBin::DrawCallback
{
public:
DepthClearCallback()
{
mDepth = new osg::Depth;
mDepth->setWriteMask(true);
}
virtual void drawImplementation(osgUtil::RenderBin* bin, osg::RenderInfo& renderInfo, osgUtil::RenderLeaf*& previous)
{
renderInfo.getState()->applyAttribute(mDepth);
glClear(GL_DEPTH_BUFFER_BIT);
bin->drawImplementation(renderInfo, previous);
}
osg::ref_ptr<osg::Depth> mDepth;
};
void NpcAnimation::setRenderBin()
{
if (mViewMode == VM_FirstPerson)
{
static bool prototypeAdded = false;
if (!prototypeAdded)
{
osg::ref_ptr<osgUtil::RenderBin> depthClearBin (new osgUtil::RenderBin);
depthClearBin->setDrawCallback(new DepthClearCallback);
osgUtil::RenderBin::addRenderBinPrototype("DepthClear", depthClearBin);
prototypeAdded = true;
}
osg::StateSet* stateset = mObjectRoot->getOrCreateStateSet();
stateset->setRenderBinDetails(RenderBin_FirstPerson, "DepthClear", osg::StateSet::OVERRIDE_RENDERBIN_DETAILS);
}
else
Animation::setRenderBin();
}
void NpcAnimation::rebuild()

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

@ -5,14 +5,15 @@ namespace MWRender
{
/// Defines the render bin numbers used in the OpenMW scene graph. The bin with the lowest number is rendered first.
/// Beware of RenderBin nesting, in most cases you will want to use setNestRenderBins(false).
enum RenderBins
{
RenderBin_Sky = -1,
RenderBin_Default = 0,
RenderBin_Default = 0, // osg::StateSet::OPAQUE_BIN
RenderBin_Water = 9,
RenderBin_OcclusionQuery = 10,
RenderBin_SunGlare = 11
RenderBin_DepthSorted = 10, // osg::StateSet::TRANSPARENT_BIN
RenderBin_OcclusionQuery = 11,
RenderBin_FirstPerson = 12,
RenderBin_SunGlare = 13
};
}

Loading…
Cancel
Save