From 45ec1a163c3e1315deab0715b00878ed43819a2b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 27 May 2009 09:54:17 +0000 Subject: [PATCH] Added support for RenderBin::SortMode::TRAVERSAL_ORDER to enable rendering of scene graph drawables in the order that they were traversed in. --- include/osgUtil/CullVisitor | 5 +++-- include/osgUtil/RenderBin | 22 ++++++++++++---------- include/osgUtil/RenderLeaf | 13 +++++++++---- src/osgUtil/CullVisitor.cpp | 4 +++- src/osgUtil/RenderBin.cpp | 23 ++++++++++++++++++++++- 5 files changed, 49 insertions(+), 18 deletions(-) diff --git a/include/osgUtil/CullVisitor b/include/osgUtil/CullVisitor index 2a94533e1..a77fce11f 100644 --- a/include/osgUtil/CullVisitor +++ b/include/osgUtil/CullVisitor @@ -314,6 +314,7 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac RenderBin* _currentRenderBin; std::vector _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; diff --git a/include/osgUtil/RenderBin b/include/osgUtil/RenderBin index 93d032940..ae742e6e7 100644 --- a/include/osgUtil/RenderBin +++ b/include/osgUtil/RenderBin @@ -33,7 +33,7 @@ class Statistics; class OSGUTIL_EXPORT RenderBin : public osg::Object { public: - + typedef std::vector RenderLeafList; typedef std::vector StateGraphList; typedef std::map< int, osg::ref_ptr > 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; diff --git a/include/osgUtil/RenderLeaf b/include/osgUtil/RenderLeaf index a4958050d..0a6f42841 100644 --- a/include/osgUtil/RenderLeaf +++ b/include/osgUtil/RenderLeaf @@ -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 _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) {} diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index a7a8d5bc7..e25f65563 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -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; diff --git a/src/osgUtil/RenderBin.cpp b/src/osgUtil/RenderBin.cpp index 1cf1ddf9e..e63d2763a 100644 --- a/src/osgUtil/RenderBin.cpp +++ b/src/osgUtil/RenderBin.cpp @@ -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"<_traversalNumber_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();