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.
This commit is contained in:
Robert Osfield
2002-09-18 14:57:01 +00:00
parent 4a54b7bdb1
commit f11410928f
6 changed files with 75 additions and 79 deletions

View File

@@ -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<const osg::ClearNode> _clearNode;
TransparencySortMode _tsm;
bool _impostorActive;
bool _depthSortImpostorSprites;

View File

@@ -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;

View File

@@ -43,6 +43,7 @@ class OSGUTIL_EXPORT RenderGraph : public osg::Referenced
LeafList _leaves;
mutable float _averageDistance;
mutable float _minimumDistance;
osg::ref_ptr<osg::Referenced> _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;
}

View File

@@ -15,6 +15,40 @@
#include <osgUtil/Optimizer>
struct SortByAverageDistanceFunctor
{
bool operator() (const osgUtil::RenderGraph* lhs,const osgUtil::RenderGraph* rhs) const
{
return lhs->getAverageDistance()<rhs->getAverageDistance();
}
};
struct SortByMinimumDistanceFunctor
{
bool operator() (const osgUtil::RenderGraph* lhs,const osgUtil::RenderGraph* rhs) const
{
return lhs->getMinimumDistance()<rhs->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();

View File

@@ -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();

View File

@@ -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()