From f11410928f7e231f4f36b010bc7d73d08c827153 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 18 Sep 2002 14:57:01 +0000 Subject: [PATCH] Simplified the depth calculation code in CullVisitor so that it always computes the depth of all drawables, so that it is always safe for RenderBin sort routines can use these values directly. Add an example of a RenderBin::SortCallback to sgv.cpp. --- include/osgUtil/CullVisitor | 9 ------ include/osgUtil/RenderBin | 5 --- include/osgUtil/RenderGraph | 22 +++++++++++++ src/Demos/sgv/sgv.cpp | 49 +++++++++++++++++++++++++++++ src/osgUtil/CullVisitor.cpp | 63 +++---------------------------------- src/osgUtil/RenderBin.cpp | 6 ---- 6 files changed, 75 insertions(+), 79 deletions(-) diff --git a/include/osgUtil/CullVisitor b/include/osgUtil/CullVisitor index 6497bada4..efdb8454a 100644 --- a/include/osgUtil/CullVisitor +++ b/include/osgUtil/CullVisitor @@ -108,13 +108,6 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac void setComputeNearFarMode(ComputeNearFarMode cnfm) { _computeNearFar=cnfm; } ComputeNearFarMode getComputeNearFarMode() const { return _computeNearFar;} - - enum TransparencySortMode { - LOOK_VECTOR_DISTANCE, - OBJECT_EYE_POINT_DISTANCE - }; - - void setTransparencySortMode(TransparencySortMode tsm) { _tsm = tsm; } /** Push state set on the current state group. * If the state exists in a child state group of the current * state group then move the current state group to that child. @@ -244,8 +237,6 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac float _computed_zfar; osg::ref_ptr _clearNode; - - TransparencySortMode _tsm; bool _impostorActive; bool _depthSortImpostorSprites; diff --git a/include/osgUtil/RenderBin b/include/osgUtil/RenderBin index 3b2d35b9a..14575261d 100644 --- a/include/osgUtil/RenderBin +++ b/include/osgUtil/RenderBin @@ -62,10 +62,6 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object { _renderGraphList.push_back(rg); } - - bool getRequiresDepthValueForSort() const { return _requiresDepthValueForSort; } - - void setRequiresDepthValueForSort(bool flag) { _requiresDepthValueForSort=flag; } void sort(); @@ -102,7 +98,6 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object void copyLeavesFromRenderGraphListToRenderLeafList(); - bool _requiresDepthValueForSort; int _binNum; RenderBin* _parent; RenderStage* _stage; diff --git a/include/osgUtil/RenderGraph b/include/osgUtil/RenderGraph index 6f3552ffa..16b0a3e90 100644 --- a/include/osgUtil/RenderGraph +++ b/include/osgUtil/RenderGraph @@ -43,6 +43,7 @@ class OSGUTIL_EXPORT RenderGraph : public osg::Referenced LeafList _leaves; mutable float _averageDistance; + mutable float _minimumDistance; osg::ref_ptr _userData; @@ -52,6 +53,7 @@ class OSGUTIL_EXPORT RenderGraph : public osg::Referenced _stateset(NULL), _depth(0), _averageDistance(0), + _minimumDistance(0), _userData(NULL) { } @@ -61,6 +63,7 @@ class OSGUTIL_EXPORT RenderGraph : public osg::Referenced _stateset(stateset), _depth(0), _averageDistance(0), + _minimumDistance(0), _userData(NULL) { if (_parent) _depth = _parent->_depth + 1; @@ -104,6 +107,24 @@ class OSGUTIL_EXPORT RenderGraph : public osg::Referenced return _averageDistance; } + inline float getMinimumDistance() const + { + if (_minimumDistance==FLT_MAX && !_leaves.empty()) + { + LeafList::const_iterator itr=_leaves.begin(); + _minimumDistance = (*itr)->_depth; + ++itr; + for(; + itr!=_leaves.end(); + ++itr) + { + if ((*itr)->_depth<_minimumDistance) _minimumDistance=(*itr)->_depth; + } + + } + return _minimumDistance; + } + inline void sortFrontToBack() { std::sort(_leaves.begin(),_leaves.end(),LeafDepthSortFunctor()); @@ -139,6 +160,7 @@ class OSGUTIL_EXPORT RenderGraph : public osg::Referenced if (leaf) { _averageDistance = FLT_MAX; // signify dirty. + _minimumDistance = FLT_MAX; // signify dirty. _leaves.push_back(leaf); leaf->_parent = this; } diff --git a/src/Demos/sgv/sgv.cpp b/src/Demos/sgv/sgv.cpp index bef970e5f..b5de87732 100644 --- a/src/Demos/sgv/sgv.cpp +++ b/src/Demos/sgv/sgv.cpp @@ -15,6 +15,40 @@ #include +struct SortByAverageDistanceFunctor +{ + bool operator() (const osgUtil::RenderGraph* lhs,const osgUtil::RenderGraph* rhs) const + { + return lhs->getAverageDistance()getAverageDistance(); + } +}; + +struct SortByMinimumDistanceFunctor +{ + bool operator() (const osgUtil::RenderGraph* lhs,const osgUtil::RenderGraph* rhs) const + { + return lhs->getMinimumDistance()getMinimumDistance(); + } +}; + +struct MySortCallback : public osgUtil::RenderBin::SortCallback +{ + virtual void sort(osgUtil::RenderBin* renderbin) + { + + osgUtil::RenderBin::RenderGraphList& renderGraphList = renderbin->_renderGraphList; + for(osgUtil::RenderBin::RenderGraphList::iterator itr=renderGraphList.begin(); + itr!=renderGraphList.end(); + ++itr) + { + (*itr)->sortFrontToBack(); + } + +// std::sort(renderGraphList.begin(),renderGraphList.end(),SortByAverageDistanceFunctor()); + std::sort(renderGraphList.begin(),renderGraphList.end(),SortByMinimumDistanceFunctor()); + } +}; + void write_usage(std::ostream& out,const std::string& name) { out << std::endl; @@ -96,6 +130,21 @@ int main( int argc, char **argv ) viewer.registerCameraManipulator(new osgGA::TrackballManipulator); viewer.registerCameraManipulator(new osgGA::FlightManipulator); viewer.registerCameraManipulator(new osgGA::DriveManipulator); + +// osgUtil::RenderBin* depth_renderbin = osgUtil::RenderBin::getRenderBinPrototype("DepthSortedBin"); +// if (depth_renderbin) +// { +// depth_renderbin->setSortMode(osgUtil::RenderBin::SORT_BY_STATE); +// } + + osgUtil::RenderStage* renderstage = viewer.getViewportSceneView(0)->getRenderStage(); + if (renderstage) + { + renderstage->setSortLocalCallback(new MySortCallback); +// renderstage->setSortMode(osgUtil::RenderBin::SORT_FRONT_TO_BACK); + } + + // open the viewer window. viewer.open(); diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index 0cfe70c6c..7a51dd875 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -81,7 +81,6 @@ CullVisitor::CullVisitor(): _computeNearFar(COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES), _computed_znear(FLT_MAX), _computed_zfar(-FLT_MAX), - _tsm(OBJECT_EYE_POINT_DISTANCE), _impostorActive(true), _depthSortImpostorSprites(false), _impostorPixelErrorThreshold(4.0f), @@ -268,26 +267,7 @@ void CullVisitor::apply(Geode& node) StateSet* stateset = drawable->getStateSet(); if (stateset) pushStateSet(stateset); - if (_currentRenderBin->getRequiresDepthValueForSort()) - { - - Vec3 center = (drawable->getBound().center())*matrix; - - float depth; - switch(_tsm) - { - case(LOOK_VECTOR_DISTANCE):depth = -center.z();break; - case(OBJECT_EYE_POINT_DISTANCE): - default: depth = center.length2();break; - } - - addDrawableAndDepth(drawable,&matrix,depth); - - } - else - { - addDrawable(drawable,&matrix); - } + addDrawableAndDepth(drawable,&matrix,distance(drawable->getBound().center(),matrix)); if (stateset) popStateSet(); @@ -322,12 +302,10 @@ void CullVisitor::apply(Billboard& node) node.getMatrix(*billboard_matrix,eye_local,pos); - Vec3 center; - center = pos*modelview; + float d = distance(pos,modelview); if (_computeNearFar) { - float d = -center.z(); if (d<_computed_znear) _computed_znear = d; if (d>_computed_zfar) _computed_zfar = d; } @@ -335,23 +313,7 @@ void CullVisitor::apply(Billboard& node) StateSet* stateset = drawable->getStateSet(); if (stateset) pushStateSet(stateset); - if (_currentRenderBin->getRequiresDepthValueForSort()) - { - float depth; - switch(_tsm) - { - case(LOOK_VECTOR_DISTANCE):depth = -center.z();break; - case(OBJECT_EYE_POINT_DISTANCE): - default: depth = center.length2();break; - } - - addDrawableAndDepth(drawable,billboard_matrix,depth); - - } - else - { - addDrawable(drawable,billboard_matrix); - } + addDrawableAndDepth(drawable,billboard_matrix,d); if (stateset) popStateSet(); @@ -649,24 +611,7 @@ void CullVisitor::apply(Impostor& node) if (stateset) pushStateSet(stateset); - if (_depthSortImpostorSprites) - { - Vec3 center = node.getCenter()*matrix; - - float depth; - switch(_tsm) - { - case(LOOK_VECTOR_DISTANCE):depth = -center.z();break; - case(OBJECT_EYE_POINT_DISTANCE): - default: depth = center.length2();break; - } - - addDrawableAndDepth(impostorSprite,&matrix,depth); - } - else - { - addDrawable(impostorSprite,&matrix); - } + addDrawableAndDepth(impostorSprite,&matrix,distance(node.getCenter(),matrix)); if (stateset) popStateSet(); diff --git a/src/osgUtil/RenderBin.cpp b/src/osgUtil/RenderBin.cpp index b20a2d616..2d6bf52ca 100644 --- a/src/osgUtil/RenderBin.cpp +++ b/src/osgUtil/RenderBin.cpp @@ -58,14 +58,10 @@ RenderBin::RenderBin(SortMode mode) _parent = NULL; _stage = NULL; _sortMode = mode; - _requiresDepthValueForSort = (_sortMode==SORT_FRONT_TO_BACK || - _sortMode==SORT_BACK_TO_FRONT); - } RenderBin::RenderBin(const RenderBin& rhs,const CopyOp& copyop): Object(rhs,copyop), - _requiresDepthValueForSort(rhs._requiresDepthValueForSort), _binNum(rhs._binNum), _parent(rhs._parent), _stage(rhs._stage), @@ -107,8 +103,6 @@ void RenderBin::sort() void RenderBin::setSortMode(SortMode mode) { _sortMode = mode; - _requiresDepthValueForSort = (_sortMode==SORT_FRONT_TO_BACK || - _sortMode==SORT_BACK_TO_FRONT); } void RenderBin::sort_local()