2001-09-20 05:19:47 +08:00
|
|
|
#include <osgUtil/RenderBin>
|
|
|
|
#include <osgUtil/RenderStage>
|
|
|
|
|
2001-10-04 22:35:42 +08:00
|
|
|
#include <algorithm>
|
|
|
|
|
2001-09-20 05:19:47 +08:00
|
|
|
using namespace osg;
|
|
|
|
using namespace osgUtil;
|
|
|
|
|
|
|
|
|
|
|
|
// register a RenderStage prototype with the RenderBin prototype list.
|
|
|
|
RegisterRenderBinProxy<RenderBin> s_registerRenderBinProxy;
|
|
|
|
|
|
|
|
typedef std::map< std::string, osg::ref_ptr<RenderBin> > RenderBinPrototypeList;
|
|
|
|
|
|
|
|
RenderBinPrototypeList* renderBinPrototypeList()
|
|
|
|
{
|
|
|
|
static RenderBinPrototypeList s_renderBinPrototypeList;
|
|
|
|
return &s_renderBinPrototypeList;
|
|
|
|
}
|
|
|
|
|
|
|
|
RenderBin* RenderBin::createRenderBin(const std::string& binName)
|
|
|
|
{
|
|
|
|
// cout << "creating RB "<<binName<<endl;
|
|
|
|
|
|
|
|
RenderBinPrototypeList::iterator itr = renderBinPrototypeList()->find(binName);
|
|
|
|
if (itr != renderBinPrototypeList()->end()) return dynamic_cast<RenderBin*>(itr->second->clone());
|
|
|
|
else return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RenderBin::addRenderBinPrototype(RenderBin* proto)
|
|
|
|
{
|
|
|
|
if (proto)
|
|
|
|
{
|
|
|
|
(*renderBinPrototypeList())[proto->className()] = proto;
|
|
|
|
// cout << "Adding RB "<<proto->className()<<endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void RenderBin::removeRenderBinPrototype(RenderBin* proto)
|
|
|
|
{
|
|
|
|
if (proto)
|
|
|
|
{
|
|
|
|
RenderBinPrototypeList::iterator itr = renderBinPrototypeList()->find(proto->className());
|
|
|
|
if (itr != renderBinPrototypeList()->end()) renderBinPrototypeList()->erase(itr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RenderBin::RenderBin()
|
|
|
|
{
|
|
|
|
_binNum = 0;
|
|
|
|
_parent = NULL;
|
|
|
|
_stage = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
RenderBin::~RenderBin()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void RenderBin::reset()
|
|
|
|
{
|
|
|
|
_renderGraphList.clear();
|
|
|
|
_bins.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void RenderBin::sort()
|
|
|
|
{
|
|
|
|
for(RenderBinList::iterator itr = _bins.begin();
|
|
|
|
itr!=_bins.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
itr->second->sort();
|
|
|
|
}
|
|
|
|
sort_local();
|
|
|
|
}
|
|
|
|
|
2001-10-04 22:35:42 +08:00
|
|
|
|
|
|
|
struct StateSortFunctor
|
|
|
|
{
|
|
|
|
const bool operator() (const RenderGraph* lhs,const RenderGraph* rhs)
|
|
|
|
{
|
|
|
|
return (*(lhs->_stateset)<*(rhs->_stateset));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void RenderBin::sort_local()
|
|
|
|
{
|
|
|
|
// now sort the list into acending depth order.
|
|
|
|
// std::sort(_renderGraphList.begin(),_renderGraphList.end(),StateSortFunctor());
|
|
|
|
}
|
|
|
|
|
2001-09-20 05:19:47 +08:00
|
|
|
RenderBin* RenderBin::find_or_insert(int binNum,const std::string& binName)
|
|
|
|
{
|
|
|
|
// search for appropriate bin.
|
|
|
|
RenderBinList::iterator itr = _bins.find(binNum);
|
|
|
|
if (itr!=_bins.end()) return itr->second.get();
|
|
|
|
|
|
|
|
// create a renderin bin and insert into bin list.
|
|
|
|
RenderBin* rb = RenderBin::createRenderBin(binName);
|
|
|
|
if (rb)
|
|
|
|
{
|
|
|
|
|
|
|
|
RenderStage* rs = dynamic_cast<RenderStage*>(rb);
|
|
|
|
if (rs)
|
|
|
|
{
|
|
|
|
rs->_binNum = binNum;
|
|
|
|
rs->_parent = NULL;
|
|
|
|
rs->_stage = rs;
|
|
|
|
_stage->addToDependencyList(rs);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rb->_binNum = binNum;
|
|
|
|
rb->_parent = this;
|
|
|
|
rb->_stage = _stage;
|
|
|
|
_bins[binNum] = rb;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return rb;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RenderBin::draw(osg::State& state,RenderLeaf*& previous)
|
|
|
|
{
|
|
|
|
// draw first set of draw bins.
|
|
|
|
RenderBinList::iterator itr;
|
|
|
|
for(itr = _bins.begin();
|
|
|
|
itr->first<0 && itr!=_bins.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
itr->second->draw(state,previous);
|
|
|
|
}
|
|
|
|
|
|
|
|
draw_local(state,previous);
|
|
|
|
|
|
|
|
for(;
|
|
|
|
itr!=_bins.end();
|
|
|
|
++itr)
|
|
|
|
{
|
|
|
|
itr->second->draw(state,previous);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void RenderBin::draw_local(osg::State& state,RenderLeaf*& previous)
|
|
|
|
{
|
|
|
|
// draw local bin.
|
|
|
|
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;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-10-23 06:02:47 +08:00
|
|
|
|
2001-09-20 05:19:47 +08:00
|
|
|
// stats
|
2001-10-23 06:02:47 +08:00
|
|
|
void RenderBin::getStats(Statistics& primStats)
|
2001-09-20 05:19:47 +08:00
|
|
|
{
|
|
|
|
for(RenderBinList::iterator itr = _bins.begin();
|
|
|
|
itr!=_bins.end();
|
|
|
|
++itr)
|
|
|
|
{
|
2001-10-23 06:02:47 +08:00
|
|
|
primStats.nbins++;
|
|
|
|
itr->second->getStats(primStats); // gwm 19.08.01 - multi-pass rendering uses these bins too.
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
|
|
|
Drawable* dw= rl->_drawable;
|
2001-10-23 06:02:47 +08:00
|
|
|
primStats.numOpaque++; // number of geosets
|
|
|
|
if (rl->_matrix.get()) primStats.nummat++; // number of matrices
|
2001-09-20 05:19:47 +08:00
|
|
|
if (dw) { // then tot up the types 1-14
|
2001-10-23 06:02:47 +08:00
|
|
|
dw->getStats(primStats); // use sub-class to find the stats for each drawable
|
2001-09-20 05:19:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|