Improved the sort callback support in osgUtil::RenderBin, and removed the

now rendundent DepthSortedBin class.
This commit is contained in:
Robert Osfield
2002-09-17 15:47:23 +00:00
parent 91df37b5c8
commit ed43d97ed3
9 changed files with 133 additions and 221 deletions

View File

@@ -1,52 +0,0 @@
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
//Distributed under the terms of the GNU Library General Public License (LGPL)
//as published by the Free Software Foundation.
#ifndef OSGUTIL_DEPTHSORTEDBIN
#define OSGUTIL_DEPTHSORTEDBIN 1
#include <osgUtil/RenderBin>
namespace osgUtil {
class OSGUTIL_EXPORT DepthSortedBin : public RenderBin
{
public:
DepthSortedBin();
virtual osg::Object* cloneType() const { return osgNew DepthSortedBin(); }
virtual osg::Object* clone(const osg::CopyOp&) const { return osgNew DepthSortedBin(); } // note only implements a clone of type.
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const DepthSortedBin*>(obj)!=0L; }
virtual const char* libraryName() const { return "osgUtil"; }
virtual const char* className() const { return "DepthSortedBin"; }
virtual void reset();
virtual void sort_local();
virtual void draw_local(osg::State& state,RenderLeaf*& previous);
enum DrawOrder
{
FRONT_TO_BACK,
BACK_TO_FRONT
};
void setDrawOrder(const DrawOrder drawOrder) { _drawOrder = drawOrder; }
const DrawOrder getDrawOrder() const { return _drawOrder; }
protected:
virtual ~DepthSortedBin();
DrawOrder _drawOrder;
//RenderLeafList _renderLeafList;
};
}
#endif

View File

@@ -31,14 +31,25 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object
// static methods.
static RenderBin* createRenderBin(const std::string& binName);
static void addRenderBinPrototype(RenderBin* proto);
static RenderBin* getRenderBinPrototype(const std::string& binName);
static void addRenderBinPrototype(const std::string& binName,RenderBin* proto);
static void removeRenderBinPrototype(RenderBin* proto);
enum SortMode
{
SORT_BY_STATE,
SORT_FRONT_TO_BACK,
SORT_BACK_TO_FRONT
};
RenderBin();
RenderBin(SortMode mode=SORT_BY_STATE);
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
RenderBin(const RenderBin& rhs,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
virtual osg::Object* cloneType() const { return osgNew RenderBin(); }
virtual osg::Object* clone(const osg::CopyOp&) const { return osgNew RenderBin(); } // note only implements a clone of type.
virtual osg::Object* clone(const osg::CopyOp& copyop) const { return osgNew RenderBin(*this,copyop); } // note only implements a clone of type.
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const RenderBin*>(obj)!=0L; }
virtual const char* libraryName() const { return "osgUtil"; }
virtual const char* className() const { return "RenderBin"; }
@@ -51,18 +62,14 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object
{
_renderGraphList.push_back(rg);
}
bool getRequiresDepthValueForSort() const { return _requiresDepthValueForSort; }
void setRequiresDepthValueForSort(bool flag) { _requiresDepthValueForSort=flag; }
void sort();
enum SortMode
{
SORT_BY_STATE,
SORT_FRONT_TO_BACK,
SORT_BACK_TO_FONT
};
void setSortMode(SortMode mode) { _sortMode = mode; }
void setSortMode(SortMode mode);
SortMode getSortMode() const { return _sortMode; }
virtual void sort_local();
@@ -95,6 +102,7 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object
void copyLeavesFromRenderGraphListToRenderLeafList();
bool _requiresDepthValueForSort;
int _binNum;
RenderBin* _parent;
RenderStage* _stage;
@@ -117,14 +125,13 @@ class OSGUTIL_EXPORT RenderBin : public osg::Object
};
/** Proxy class for automatic registration of renderbins with the RenderBin prototypelist.*/
template<class T>
class RegisterRenderBinProxy
{
public:
RegisterRenderBinProxy()
RegisterRenderBinProxy(const std::string& binName,RenderBin* proto)
{
_rb = osgNew T;
RenderBin::addRenderBinPrototype(_rb.get());
_rb = proto;
RenderBin::addRenderBinPrototype(binName,_rb.get());
}
~RegisterRenderBinProxy()
@@ -133,7 +140,7 @@ class RegisterRenderBinProxy
}
protected:
osg::ref_ptr<T> _rb;
osg::ref_ptr<RenderBin> _rb;
};

View File

@@ -27,9 +27,12 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin
public:
RenderStage();
RenderStage(SortMode mode=SORT_BY_STATE);
RenderStage(const RenderStage& rhs,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
virtual osg::Object* cloneType() const { return osgNew RenderStage(); }
virtual osg::Object* clone(const osg::CopyOp&) const { return osgNew RenderStage(); } // note only implements a clone of type.
virtual osg::Object* clone(const osg::CopyOp& copyop) const { return osgNew RenderStage(*this,copyop); } // note only implements a clone of type.
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const RenderStage*>(obj)!=0L; }
virtual const char* className() const { return "RenderStage"; }

View File

@@ -266,9 +266,9 @@ void CullVisitor::apply(Geode& node)
// push the geoset's state on the geostate stack.
StateSet* stateset = drawable->getStateSet();
if (stateset) pushStateSet(stateset);
bool isTransparent = stateset && stateset->getRenderingHint()==osg::StateSet::TRANSPARENT_BIN;
if (isTransparent)
if (_currentRenderBin->getRequiresDepthValueForSort())
{
Vec3 center = (drawable->getBound().center())*matrix;
@@ -281,18 +281,16 @@ void CullVisitor::apply(Geode& node)
default: depth = center.length2();break;
}
if (stateset) pushStateSet(stateset);
addDrawableAndDepth(drawable,&matrix,depth);
if (stateset) popStateSet();
}
else
{
if (stateset) pushStateSet(stateset);
addDrawable(drawable,&matrix);
if (stateset) popStateSet();
}
if (stateset) popStateSet();
}
// pop the node's state off the geostate stack.
@@ -335,12 +333,10 @@ void CullVisitor::apply(Billboard& node)
}
StateSet* stateset = drawable->getStateSet();
if (stateset) pushStateSet(stateset);
bool isTransparent = stateset && stateset->getRenderingHint()==osg::StateSet::TRANSPARENT_BIN;
if (isTransparent)
if (_currentRenderBin->getRequiresDepthValueForSort())
{
float depth;
switch(_tsm)
{
@@ -349,18 +345,16 @@ void CullVisitor::apply(Billboard& node)
default: depth = center.length2();break;
}
if (stateset) pushStateSet(stateset);
addDrawableAndDepth(drawable,billboard_matrix,depth);
if (stateset) popStateSet();
}
else
{
if (stateset) pushStateSet(stateset);
addDrawable(drawable,billboard_matrix);
if (stateset) popStateSet();
}
if (stateset) popStateSet();
}
// pop the node's state off the geostate stack.

View File

@@ -1,104 +0,0 @@
#include <osgUtil/DepthSortedBin>
#include <osgUtil/RenderStage>
#include <algorithm>
using namespace osg;
using namespace osgUtil;
#ifndef __DARWIN_OSX__
// this is a hack to test OS X ....
// register a RenderStage prototype with the RenderBin prototype list.
RegisterRenderBinProxy<DepthSortedBin> s_registerDepthSortedBinProxy;
#endif
DepthSortedBin::DepthSortedBin()
{
_drawOrder = BACK_TO_FRONT;
}
DepthSortedBin::~DepthSortedBin()
{
}
void DepthSortedBin::reset()
{
RenderBin::reset();
_renderLeafList.clear();
}
struct DepthSortFunctor2
{
bool operator() (const RenderLeaf* lhs,const RenderLeaf* rhs)
{
return (lhs->_depth<rhs->_depth);
}
};
void DepthSortedBin::sort_local()
{
_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());
}
}
// now sort the list into acending depth order.
std::sort(_renderLeafList.begin(),_renderLeafList.end(),DepthSortFunctor2());
}
void DepthSortedBin::draw_local(osg::State& state,RenderLeaf*& previous)
{
sort_local();
if (_drawOrder==BACK_TO_FRONT)
{
// render the bin from back to front.
for(RenderLeafList::reverse_iterator itr= _renderLeafList.rbegin();
itr!= _renderLeafList.rend();
++itr)
{
RenderLeaf* rl = *itr;
rl->render(state,previous);
previous = rl;
}
}
else
{
// render the from front to back.
for(RenderLeafList::iterator itr= _renderLeafList.begin();
itr!= _renderLeafList.end();
++itr)
{
RenderLeaf* rl = *itr;
rl->render(state,previous);
previous = rl;
}
}
}

View File

@@ -5,7 +5,6 @@ include $(TOPDIR)/Make/makedefs
CXXFILES = \
AppVisitor.cpp\
CullVisitor.cpp\
DepthSortedBin.cpp\
DisplayListVisitor.cpp\
DisplayRequirementsVisitor.cpp\
InsertImpostorsVisitor.cpp\

View File

@@ -10,14 +10,8 @@ using namespace osg;
using namespace osgUtil;
// register a RenderStage prototype with the RenderBin prototype list.
RegisterRenderBinProxy<RenderBin> s_registerRenderBinProxy;
#ifdef __DARWIN_OSX__
// PJA 10/1/02 - this is a hack to get OS X to build, if this code is included in DepthSortedBin.cpp it isnt executed
// register a RenderStage prototype with the RenderBin prototype list.
#include <osgUtil/DepthSortedBin>
RegisterRenderBinProxy<DepthSortedBin> s_registerDepthSortedBinProxy;
#endif
RegisterRenderBinProxy s_registerRenderBinProxy("RenderBin",osgNew RenderBin(RenderBin::SORT_BY_STATE));
RegisterRenderBinProxy s_registerDepthSortedBinProxy("DepthSortedBin",osgNew RenderBin(RenderBin::SORT_BACK_TO_FRONT));
typedef std::map< std::string, osg::ref_ptr<RenderBin> > RenderBinPrototypeList;
@@ -27,21 +21,25 @@ RenderBinPrototypeList* renderBinPrototypeList()
return &s_renderBinPrototypeList;
}
RenderBin* RenderBin::createRenderBin(const std::string& binName)
RenderBin* RenderBin::getRenderBinPrototype(const std::string& binName)
{
// cout << "creating RB "<<binName<<std::endl;
RenderBinPrototypeList::iterator itr = renderBinPrototypeList()->find(binName);
if (itr != renderBinPrototypeList()->end()) return dynamic_cast<RenderBin*>(itr->second->cloneType());
if (itr != renderBinPrototypeList()->end()) return itr->second.get();
else return NULL;
}
void RenderBin::addRenderBinPrototype(RenderBin* proto)
RenderBin* RenderBin::createRenderBin(const std::string& binName)
{
RenderBin* prototype = getRenderBinPrototype(binName);
if (prototype) return dynamic_cast<RenderBin*>(prototype->clone(osg::CopyOp::DEEP_COPY_ALL));
else return NULL;
}
void RenderBin::addRenderBinPrototype(const std::string& binName,RenderBin* proto)
{
if (proto)
{
(*renderBinPrototypeList())[proto->className()] = proto;
// cout << "Adding RB "<<proto->className()<<std::endl;
(*renderBinPrototypeList())[binName] = proto;
}
}
@@ -54,12 +52,30 @@ void RenderBin::removeRenderBinPrototype(RenderBin* proto)
}
}
RenderBin::RenderBin()
RenderBin::RenderBin(SortMode mode)
{
_binNum = 0;
_parent = NULL;
_stage = NULL;
_sortMode = SORT_BY_STATE;
_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),
_bins(rhs._bins),
_renderGraphList(rhs._renderGraphList),
_renderLeafList(rhs._renderLeafList),
_sortMode(rhs._sortMode),
_sortLocalCallback(rhs._sortLocalCallback)
{
}
RenderBin::~RenderBin()
@@ -81,10 +97,20 @@ void RenderBin::sort()
itr->second->sort();
}
if (_sortLocalCallback.valid()) _sortLocalCallback->sort(this);
if (_sortLocalCallback.valid())
{
_sortLocalCallback->sort(this);
}
else sort_local();
}
void RenderBin::setSortMode(SortMode mode)
{
_sortMode = mode;
_requiresDepthValueForSort = (_sortMode==SORT_FRONT_TO_BACK ||
_sortMode==SORT_BACK_TO_FRONT);
}
void RenderBin::sort_local()
{
switch(_sortMode)
@@ -95,7 +121,7 @@ void RenderBin::sort_local()
case(SORT_FRONT_TO_BACK):
sort_local_front_to_back();
break;
case(SORT_BACK_TO_FONT):
case(SORT_BACK_TO_FRONT):
sort_local_back_to_front();
break;
default:
@@ -117,6 +143,7 @@ void RenderBin::sort_local_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.
// cout << "doing sort_local_by_state "<<this<<endl;
}
struct FrontToBackSortFunctor
@@ -134,6 +161,8 @@ void RenderBin::sort_local_front_to_back()
// now sort the list into acending depth order.
std::sort(_renderLeafList.begin(),_renderLeafList.end(),FrontToBackSortFunctor());
// cout << "sort front to back"<<endl;
}
struct BackToFrontSortFunctor
@@ -150,6 +179,8 @@ void RenderBin::sort_local_back_to_front()
// now sort the list into acending depth order.
std::sort(_renderLeafList.begin(),_renderLeafList.end(),BackToFrontSortFunctor());
// cout << "sort back to front"<<endl;
}
void RenderBin::copyLeavesFromRenderGraphListToRenderLeafList()
@@ -234,22 +265,37 @@ void RenderBin::draw(osg::State& state,RenderLeaf*& previous)
void RenderBin::draw_local(osg::State& state,RenderLeaf*& previous)
{
sort_local();
// draw local bin.
for(RenderGraphList::iterator oitr=_renderGraphList.begin();
oitr!=_renderGraphList.end();
++oitr)
if (!_renderLeafList.empty())
{
for(RenderGraph::LeafList::iterator dw_itr = (*oitr)->_leaves.begin();
dw_itr != (*oitr)->_leaves.end();
++dw_itr)
// draw fine grained ordering.
for(RenderLeafList::iterator itr= _renderLeafList.begin();
itr!= _renderLeafList.end();
++itr)
{
RenderLeaf* rl = dw_itr->get();
RenderLeaf* rl = *itr;
rl->render(state,previous);
previous = rl;
}
}
else
{
// draw coarse grained ordering.
for(RenderGraphList::iterator oitr=_renderGraphList.begin();
oitr!=_renderGraphList.end();
++oitr)
{
for(RenderGraph::LeafList::iterator dw_itr = (*oitr)->_leaves.begin();
dw_itr != (*oitr)->_leaves.end();
++dw_itr)
{
RenderLeaf* rl = dw_itr->get();
rl->render(state,previous);
previous = rl;
}
}
}
}

View File

@@ -11,7 +11,8 @@ using namespace osgUtil;
// register a RenderStage prototype with the RenderBin prototype list.
//RegisterRenderBinProxy<RenderStage> s_registerRenderStageProxy;
RenderStage::RenderStage()
RenderStage::RenderStage(SortMode mode):
RenderBin(mode)
{
// point RenderBin's _stage to this to ensure that references to
// stage don't go tempted away to any other stage.
@@ -27,6 +28,23 @@ RenderStage::RenderStage()
}
RenderStage::RenderStage(const RenderStage& rhs,const osg::CopyOp& copyop):
RenderBin(rhs,copyop),
_stageDrawnThisFrame(false),
_dependencyList(rhs._dependencyList),
_viewport(rhs._viewport),
_clearMask(rhs._clearMask),
_colorMask(rhs._colorMask),
_clearColor(rhs._clearColor),
_clearAccum(rhs._clearAccum),
_clearDepth(rhs._clearDepth),
_clearStencil(rhs._clearStencil),
_renderStageLighting(rhs._renderStageLighting)
{
}
RenderStage::~RenderStage()
{
}

View File

@@ -242,11 +242,11 @@ void SceneView::cull()
if (!_cullVisitorLeft.valid()) _cullVisitorLeft = dynamic_cast<CullVisitor*>(_cullVisitor->cloneType());
if (!_rendergraphLeft.valid()) _rendergraphLeft = dynamic_cast<RenderGraph*>(_rendergraph->cloneType());
if (!_renderStageLeft.valid()) _renderStageLeft = dynamic_cast<RenderStage*>(_renderStage->cloneType());
if (!_renderStageLeft.valid()) _renderStageLeft = dynamic_cast<RenderStage*>(_renderStage->clone(osg::CopyOp::DEEP_COPY_ALL));
if (!_cullVisitorRight.valid()) _cullVisitorRight = dynamic_cast<CullVisitor*>(_cullVisitor->cloneType());
if (!_rendergraphRight.valid()) _rendergraphRight = dynamic_cast<RenderGraph*>(_rendergraph->cloneType());
if (!_renderStageRight.valid()) _renderStageRight = dynamic_cast<RenderStage*>(_renderStage->cloneType());
if (!_renderStageRight.valid()) _renderStageRight = dynamic_cast<RenderStage*>(_renderStage->clone(osg::CopyOp::DEEP_COPY_ALL));
// set up the left eye.
@@ -456,6 +456,7 @@ void SceneView::cullStage(osg::Matrix* projection,osg::Matrix* modelview,osgUtil
}
}
renderStage->sort();
// prune out any empty RenderGraph children.
// note, this would be not required if the rendergraph had been