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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user