From Michael Platings and Robert Osfield, added support for controlling,

via StateSet::setNestedRenderBin(bool) whether the new RenderBin should be nested
with the existing RenderBin, or be nested with the enclosing RenderStage.
This commit is contained in:
Robert Osfield 2008-06-19 11:09:20 +00:00
parent 0abf539b60
commit 174f9bbfe0
5 changed files with 50 additions and 8 deletions

View File

@ -1,4 +1,4 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@ -363,6 +363,18 @@ class OSG_EXPORT StateSet : public Object
/** Get the render bin name.*/
inline const std::string& getBinName() const { return _binName; }
/** By default render bins will be nested within each other dependent
* upon where they are set in the scene graph. This can be problematic
* if a transparent render bin is attached to an opaque render bin
* which is attached to another transparent render bin as these render
* bins will be sorted separately, giving the wrong draw ordering for
* back-to-front transparency. Therefore, to prevent render bins being
* nested, call setNestRenderBins(false). */
inline void setNestRenderBins(bool val) { _nestRenderBins = val; }
/** Get whether associated RenderBin should be nested within parents RenderBin.*/
inline bool getNestRenderBins() const { return _nestRenderBins; }
struct Callback : public virtual osg::Object
{
@ -487,6 +499,7 @@ class OSG_EXPORT StateSet : public Object
RenderBinMode _binMode;
int _binNum;
std::string _binName;
bool _nestRenderBins;
ref_ptr<Callback> _updateCallback;
unsigned int _numChildrenRequiringUpdateTraversal;

View File

@ -1,4 +1,4 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@ -103,10 +103,16 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac
inline void pushStateSet(const osg::StateSet* ss)
{
_currentStateGraph = _currentStateGraph->find_or_insert(ss);
if (_numberOfEncloseOverrideRenderBinDetails==0 && ss->useRenderBinDetails() && !ss->getBinName().empty())
{
_currentRenderBin = _currentRenderBin->find_or_insert(ss->getBinNumber(),ss->getBinName());
_renderBinStack.push_back(_currentRenderBin);
_currentRenderBin = ss->getNestRenderBins() ?
_currentRenderBin->find_or_insert(ss->getBinNumber(),ss->getBinName()) :
_currentRenderBin = _currentRenderBin->getStage()->find_or_insert(ss->getBinNumber(),ss->getBinName());
}
if (ss->getRenderBinMode()==osg::StateSet::OVERRIDE_RENDERBIN_DETAILS)
{
++_numberOfEncloseOverrideRenderBinDetails;
@ -126,9 +132,14 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac
}
if (_numberOfEncloseOverrideRenderBinDetails==0 && ss->useRenderBinDetails() && !ss->getBinName().empty())
{
if (_currentRenderBin->getParent())
if (_renderBinStack.empty())
{
_currentRenderBin = _currentRenderBin->getParent();
_currentRenderBin = _currentRenderBin->getStage();
}
else
{
_currentRenderBin = _renderBinStack.back();
_renderBinStack.pop_back();
}
}
_currentStateGraph = _currentStateGraph->_parent;
@ -289,6 +300,7 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac
osg::ref_ptr<RenderStage> _rootRenderStage;
RenderBin* _currentRenderBin;
std::vector<RenderBin*> _renderBinStack;
value_type _computed_znear;

View File

@ -1,4 +1,4 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@ -81,7 +81,8 @@ bool osg::isTextureMode(StateAttribute::GLMode mode)
}
StateSet::StateSet():
Object(true)
Object(true),
_nestRenderBins(true)
{
_renderingHint = DEFAULT_BIN;
@ -91,7 +92,8 @@ StateSet::StateSet():
setRenderBinToInherit();
}
StateSet::StateSet(const StateSet& rhs,const CopyOp& copyop):Object(rhs,copyop)
StateSet::StateSet(const StateSet& rhs,const CopyOp& copyop):Object(rhs,copyop),
_nestRenderBins(rhs._nestRenderBins)
{
_modeList = rhs._modeList;

View File

@ -141,6 +141,8 @@ void CullVisitor::reset()
CullStack::reset();
_renderBinStack.clear();
_numberOfEncloseOverrideRenderBinDetails = 0;
// reset the calculated near far planes.

View File

@ -426,6 +426,16 @@ BEGIN_OBJECT_REFLECTOR(osg::StateSet)
__C5_std_string_R1__getBinName,
"Get the render bin name. ",
"");
I_Method1(void, setNestRenderBins, IN, bool, val,
Properties::NON_VIRTUAL,
__void__setNestRenderBins__bool,
"By default render bins will be nested within each other dependent upon where they are set in the scene graph. ",
"This can be problematic if a transparent render bin is attached to an opaque render bin which is attached to another transparent render bin as these render bins will be sorted separately, giving the wrong draw ordering for back-to-front transparency. Therefore, to prevent render bins being nested, call setNestRenderBins(false). ");
I_Method0(bool, getNestRenderBins,
Properties::NON_VIRTUAL,
__bool__getNestRenderBins,
"Get whether associated RenderBin should be nested within parents RenderBin. ",
"");
I_Method1(void, setUpdateCallback, IN, osg::StateSet::Callback *, ac,
Properties::NON_VIRTUAL,
__void__setUpdateCallback__Callback_P1,
@ -623,6 +633,9 @@ BEGIN_OBJECT_REFLECTOR(osg::StateSet)
I_SimpleProperty(osg::StateSet::ModeList &, ModeList,
__ModeList_R1__getModeList,
__void__setModeList__ModeList_R1);
I_SimpleProperty(bool, NestRenderBins,
__bool__getNestRenderBins,
__void__setNestRenderBins__bool);
I_ArrayProperty(osg::Object *, Parent,
__Object_P1__getParent__unsigned_int,
0,