Added support for RenderBin::SortMode::TRAVERSAL_ORDER to enable rendering of scene graph drawables in the order that they were traversed in.

This commit is contained in:
Robert Osfield 2009-05-27 09:54:17 +00:00
parent f845b6790a
commit 45ec1a163c
5 changed files with 49 additions and 18 deletions

View File

@ -314,6 +314,7 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac
RenderBin* _currentRenderBin;
std::vector<RenderBin*> _renderBinStack;
unsigned int _traversalNumber;
value_type _computed_znear;
value_type _computed_zfar;
@ -424,12 +425,12 @@ inline RenderLeaf* CullVisitor::createOrReuseRenderLeaf(osg::Drawable* drawable,
if (_currentReuseRenderLeafIndex<_reuseRenderLeafList.size())
{
RenderLeaf* renderleaf = _reuseRenderLeafList[_currentReuseRenderLeafIndex++].get();
renderleaf->set(drawable,projection,matrix,depth);
renderleaf->set(drawable,projection,matrix,depth,_traversalNumber++);
return renderleaf;
}
// Otherwise need to create new renderleaf.
RenderLeaf* renderleaf = new RenderLeaf(drawable,projection,matrix,depth);
RenderLeaf* renderleaf = new RenderLeaf(drawable,projection,matrix,depth,_traversalNumber++);
_reuseRenderLeafList.push_back(renderleaf);
++_currentReuseRenderLeafIndex;
return renderleaf;

View File

@ -33,7 +33,7 @@ class Statistics;
class OSGUTIL_EXPORT RenderBin : public osg::Object
{
public:
typedef std::vector<RenderLeaf*> RenderLeafList;
typedef std::vector<StateGraph*> StateGraphList;
typedef std::map< int, osg::ref_ptr<RenderBin> > RenderBinList;
@ -43,7 +43,8 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object
SORT_BY_STATE,
SORT_BY_STATE_THEN_FRONT_TO_BACK,
SORT_FRONT_TO_BACK,
SORT_BACK_TO_FRONT
SORT_BACK_TO_FRONT,
TRAVERSAL_ORDER
};
// static methods.
@ -51,14 +52,14 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object
static RenderBin* getRenderBinPrototype(const std::string& binName);
static void addRenderBinPrototype(const std::string& binName,RenderBin* proto);
static void removeRenderBinPrototype(RenderBin* proto);
static void setDefaultRenderBinSortMode(SortMode mode);
static SortMode getDefaultRenderBinSortMode();
RenderBin();
RenderBin(SortMode mode);
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
@ -71,12 +72,12 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object
virtual const char* className() const { return "RenderBin"; }
virtual void reset();
void setStateSet(osg::StateSet* stateset) { _stateset = stateset; }
osg::StateSet* getStateSet() { return _stateset.get(); }
const osg::StateSet* getStateSet() const { return _stateset.get(); }
RenderBin* getParent() { return _parent; }
const RenderBin* getParent() const { return _parent; }
@ -105,7 +106,7 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object
virtual void sort();
virtual void sortImplementation();
void setSortMode(SortMode mode);
SortMode getSortMode() const { return _sortMode; }
@ -113,7 +114,8 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object
virtual void sortByStateThenFrontToBack();
virtual void sortFrontToBack();
virtual void sortBackToFront();
virtual void sortTraversalOrder();
struct SortCallback : public osg::Referenced
{
virtual void sortImplementation(RenderBin*) = 0;
@ -140,7 +142,7 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object
/** Extract stats for current draw list. */
bool getStats(Statistics& primStats) const;
/** Compute the number of dynamic RenderLeaves.*/
virtual unsigned int computeNumberOfDynamicRenderLeaves() const;

View File

@ -35,19 +35,20 @@ class OSGUTIL_EXPORT RenderLeaf : public osg::Referenced
public:
inline RenderLeaf(osg::Drawable* drawable,osg::RefMatrix* projection,osg::RefMatrix* modelview, float depth=0.0f):
inline RenderLeaf(osg::Drawable* drawable,osg::RefMatrix* projection,osg::RefMatrix* modelview, float depth=0.0f, unsigned int traversalNumber=0):
osg::Referenced(false),
_parent(0),
_drawable(drawable),
_projection(projection),
_modelview(modelview),
_depth(depth)
_depth(depth),
_traversalNumber(traversalNumber)
{
_dynamic = (drawable->getDataVariance()==osg::Object::DYNAMIC);
}
inline void set(osg::Drawable* drawable,osg::RefMatrix* projection,osg::RefMatrix* modelview, float depth=0.0f)
inline void set(osg::Drawable* drawable,osg::RefMatrix* projection,osg::RefMatrix* modelview, float depth=0.0f, unsigned int traversalNumber=0)
{
_parent = 0;
_drawable = drawable;
@ -55,6 +56,7 @@ class OSGUTIL_EXPORT RenderLeaf : public osg::Referenced
_modelview = modelview,
_depth = depth;
_dynamic = (drawable->getDataVariance()==osg::Object::DYNAMIC);
_traversalNumber = traversalNumber;
}
inline void reset()
@ -65,6 +67,7 @@ class OSGUTIL_EXPORT RenderLeaf : public osg::Referenced
_modelview = 0;
_depth = 0.0f;
_dynamic = false;
_traversalNumber = 0;
}
virtual void render(osg::RenderInfo& renderInfo,RenderLeaf* previous);
@ -89,6 +92,7 @@ class OSGUTIL_EXPORT RenderLeaf : public osg::Referenced
osg::ref_ptr<osg::RefMatrix> _modelview;
float _depth;
bool _dynamic;
unsigned int _traversalNumber;
private:
@ -99,7 +103,8 @@ class OSGUTIL_EXPORT RenderLeaf : public osg::Referenced
_drawable(0),
_projection(0),
_modelview(0),
_depth(0.0f) {}
_depth(0.0f),
_traversalNumber(0) {}
/// disallow copy construction.
RenderLeaf(const RenderLeaf&):osg::Referenced(false) {}

View File

@ -88,7 +88,6 @@ CullVisitor* CullVisitor::create()
void CullVisitor::reset()
{
//
// first unref all referenced objects and then empty the containers.
//
@ -99,6 +98,9 @@ void CullVisitor::reset()
_numberOfEncloseOverrideRenderBinDetails = 0;
// reset the traversal number
_traversalNumber = 0;
// reset the calculated near far planes.
_computed_znear = FLT_MAX;
_computed_zfar = -FLT_MAX;

View File

@ -36,7 +36,9 @@ class RenderBinPrototypeList : public osg::Referenced, public std::map< std::str
// register a RenderStage prototype with the RenderBin prototype list.
RegisterRenderBinProxy s_registerRenderBinProxy("RenderBin",new RenderBin(RenderBin::getDefaultRenderBinSortMode()));
RegisterRenderBinProxy s_registerStateSortedBinProxy("StateSortedBin",new RenderBin(RenderBin::SORT_BY_STATE));
RegisterRenderBinProxy s_registerDepthSortedBinProxy("DepthSortedBin",new RenderBin(RenderBin::SORT_BACK_TO_FRONT));
RegisterRenderBinProxy s_registerTraversalOrderProxy("TraversalOrderBin",new RenderBin(RenderBin::TRAVERSAL_ORDER));
static RenderBinPrototypeList* renderBinPrototypeList()
@ -122,6 +124,7 @@ RenderBin::SortMode RenderBin::getDefaultRenderBinSortMode()
else if (strcmp(str,"SORT_BY_STATE_THEN_FRONT_TO_BACK")==0) s_defaultBinSortMode = RenderBin::SORT_BY_STATE_THEN_FRONT_TO_BACK;
else if (strcmp(str,"SORT_FRONT_TO_BACK")==0) s_defaultBinSortMode = RenderBin::SORT_FRONT_TO_BACK;
else if (strcmp(str,"SORT_BACK_TO_FRONT")==0) s_defaultBinSortMode = RenderBin::SORT_BACK_TO_FRONT;
else if (strcmp(str,"TRAVERSAL_ORDER")==0) s_defaultBinSortMode = RenderBin::TRAVERSAL_ORDER;
}
}
@ -231,7 +234,8 @@ void RenderBin::sortImplementation()
case(SORT_BACK_TO_FRONT):
sortBackToFront();
break;
default:
case(TRAVERSAL_ORDER):
sortTraversalOrder();
break;
}
}
@ -312,6 +316,23 @@ void RenderBin::sortBackToFront()
// cout << "sort back to front"<<endl;
}
struct TraversalOrderFunctor
{
bool operator() (const RenderLeaf* lhs,const RenderLeaf* rhs) const
{
return (lhs->_traversalNumber<rhs->_traversalNumber);
}
};
void RenderBin::sortTraversalOrder()
{
copyLeavesFromStateGraphListToRenderLeafList();
// now sort the list into acending depth order.
std::sort(_renderLeafList.begin(),_renderLeafList.end(),TraversalOrderFunctor());
}
void RenderBin::copyLeavesFromStateGraphListToRenderLeafList()
{
_renderLeafList.clear();