From 1ba901cf6471e882d4b9e43ef88ceb98feaf1eb4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 3 Aug 2002 16:49:42 +0000 Subject: [PATCH] Added support for a sort callback in RenderBin. --- include/osgUtil/RenderBin | 42 ++++++++++++++--- src/osgUtil/RenderBin.cpp | 97 +++++++++++++++++++++++++++++++++++---- 2 files changed, 125 insertions(+), 14 deletions(-) diff --git a/include/osgUtil/RenderBin b/include/osgUtil/RenderBin index 29d127f55..f0ef762cc 100644 --- a/include/osgUtil/RenderBin +++ b/include/osgUtil/RenderBin @@ -55,7 +55,30 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object void sort(); + enum SortMode + { + SORT_BY_STATE, + SORT_FRONT_TO_BACK, + SORT_BACK_TO_FONT + }; + + void setSortMode(SortMode mode) { _sortMode = mode; } + SortMode getSortMode() const { return _sortMode; } + virtual void sort_local(); + virtual void sort_local_by_state(); + virtual void sort_local_front_to_back(); + virtual void sort_local_back_to_front(); + + struct SortCallback : public osg::Referenced + { + virtual void sort(RenderBin* bin) {}; + }; + + void setSortLocalCallback(SortCallback* sortCallback) { _sortLocalCallback = sortCallback; } + SortCallback* getSortLocalCallback() { return _sortLocalCallback.get(); } + const SortCallback* getSortLocalCallback() const { return _sortLocalCallback.get(); } + virtual void draw(osg::State& state,RenderLeaf*& previous); @@ -69,14 +92,21 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object public: + + void copyLeavesFromRenderGraphListToRenderLeafList(); - int _binNum; - RenderBin* _parent; - RenderStage* _stage; - RenderBinList _bins; - RenderGraphList _renderGraphList; - RenderLeafList _renderLeafList; + int _binNum; + RenderBin* _parent; + RenderStage* _stage; + RenderBinList _bins; + RenderGraphList _renderGraphList; + RenderLeafList _renderLeafList; + + SortMode _sortMode; + osg::ref_ptr _sortLocalCallback; + + typedef std::map< std::string, osg::ref_ptr > RenderBinPrototypeList; static RenderBinPrototypeList s_renderBinPrototypeList; diff --git a/src/osgUtil/RenderBin.cpp b/src/osgUtil/RenderBin.cpp index e07fa79dd..404781547 100644 --- a/src/osgUtil/RenderBin.cpp +++ b/src/osgUtil/RenderBin.cpp @@ -78,24 +78,105 @@ void RenderBin::sort() { itr->second->sort(); } - sort_local(); + + if (_sortLocalCallback.valid()) _sortLocalCallback->sort(this); + else sort_local(); } - -struct StateSortFunctor +void RenderBin::sort_local() { - const bool operator() (const RenderGraph* lhs,const RenderGraph* rhs) + switch(_sortMode) + { + case(SORT_BY_STATE): + sort_local_by_state(); + break; + case(SORT_FRONT_TO_BACK): + sort_local_front_to_back(); + break; + case(SORT_BACK_TO_FONT): + sort_local_back_to_front(); + break; + default: + break; + } +} + +struct SortByStateFunctor +{ + const bool operator() (const RenderGraph* lhs,const RenderGraph* rhs) const { return (*(lhs->_stateset)<*(rhs->_stateset)); } }; - - -void RenderBin::sort_local() +void RenderBin::sort_local_by_state() { + // actually we'll do nothing right now, as fine grained sorting by state + // appears to cost more to do than it saves in draw. The contents of + // the RenderGraph leaves is already coasrse grained sorted, this + // sorting is as a function of the cull traversal. +} + +struct FrontToBackSortFunctor +{ + bool operator() (const RenderLeaf* lhs,const RenderLeaf* rhs) const + { + return (lhs->_depth_depth); + } +}; + + +void RenderBin::sort_local_front_to_back() +{ + copyLeavesFromRenderGraphListToRenderLeafList(); + // now sort the list into acending depth order. -// std::sort(_renderGraphList.begin(),_renderGraphList.end(),StateSortFunctor()); + std::sort(_renderLeafList.begin(),_renderLeafList.end(),FrontToBackSortFunctor()); +} + +struct BackToFrontSortFunctor +{ + const bool operator() (const RenderLeaf* lhs,const RenderLeaf* rhs) const + { + return (rhs->_depth_depth); + } +}; + +void RenderBin::sort_local_back_to_front() +{ + copyLeavesFromRenderGraphListToRenderLeafList(); + + // now sort the list into acending depth order. + std::sort(_renderLeafList.begin(),_renderLeafList.end(),BackToFrontSortFunctor()); +} + +void RenderBin::copyLeavesFromRenderGraphListToRenderLeafList() +{ + _renderLeafList.clear(); + + int totalsize=0; + RenderGraphList::iterator itr; + for(itr=_renderGraphList.begin(); + itr!=_renderGraphList.end(); + ++itr) + { + totalsize += (*itr)->_leaves.size(); + } + + _renderLeafList.reserve(totalsize); + + // first copy all the leaves from the render graphs into the leaf list. + for(itr=_renderGraphList.begin(); + itr!=_renderGraphList.end(); + ++itr) + { + for(RenderGraph::LeafList::iterator dw_itr = (*itr)->_leaves.begin(); + dw_itr != (*itr)->_leaves.end(); + ++dw_itr) + { + _renderLeafList.push_back(dw_itr->get()); + } + } } RenderBin* RenderBin::find_or_insert(int binNum,const std::string& binName)