struct DrawableCullCallback : public osg::Drawable::CullCallback//自定义裁剪回调节点
{
/** do customized cull code.*/
virtual bool cull(osg::NodeVisitor*, osg::Drawable* drawable, osg::State* /*state*/) const
{
std::cout<<"Drawable cull callback "<<drawable<<std::endl;
return false;
}
};
geode.getDrawable(i)->setCullCallback(new DrawableCullCallback());//为节点设置裁剪回调
void ViewerBase::frame(double simulationTime)
{
renderingTraversals();//从渲染回调更新开始
}
void ViewerBase::renderingTraversals()
{
for(Cameras::iterator camItr = cameras.begin();
camItr != cameras.end();
++camItr)
{
osg::Camera* camera = *camItr;
Renderer* renderer = dynamic_cast<Renderer*>(camera->getRenderer());
if (renderer)
{
if (!renderer->getGraphicsThreadDoesCull() && !(camera->getCameraThread()))
{
renderer->cull();
}
}
}
} void Renderer::cull()
{
sceneView->cull();// osgUtil::SceneView* sceneView
} void SceneView::cull()
{
bool computeNearFar = cullStage(
getProjectionMatrix(),
getViewMatrix(),
_cullVisitor.get(),
_stateGraph.get(),
_renderStage.get(),
getViewport());
}
bool SceneView::cullStage(const osg::Matrixd& projection,const osg::Matrixd& modelview,
osgUtil::CullVisitor* cullVisitor, osgUtil::StateGraph* rendergraph,
osgUtil::RenderStage* renderStage, osg::Viewport *viewport)
{
// traverse the scene graph to generate the rendergraph.
// If the camera has a cullCallback execute the callback which has the
// requirement that it must traverse the camera's children.
{
osg::NodeCallback* callback = _camera->getCullCallback();
if (callback) (*callback)(_camera.get(), cullVisitor);
else cullVisitor->traverse(*_camera);
}
} inline void NodeVistor:: traverse(Node& node)//裁剪回调的Vistor
{
if (_traversalMode==TRAVERSE_PARENTS) node.ascend(*this);
else if (_traversalMode!=TRAVERSE_NONE) node.traverse(*this);
}
inline void CullVisitor:: handle_cull_callbacks_and_traverse(osg::Node& node)
{
osg::NodeCallback* callback = node.getCullCallback();
//调用的Node的Callback,再经过一系列的过程,调用Node下Drawable的callback,如下
if (callback) (*callback)(&node,this);
else traverse(node);
} void CullVisitor::apply(Geode& node)
{
for(unsigned int i=0;i<node.getNumDrawables();++i)
{
Drawable* drawable = node.getDrawable(i);
const BoundingBox &bb =drawable->getBound();
if( drawable->getCullCallback() )
{
if( drawable->getCullCallback()->cull( this, drawable, &_renderInfo ) == true )
continue;
}
}
}
virtual bool Drawable::cull(osg::NodeVisitor* nv, osg::Drawable* drawable, osg::RenderInfo* renderInfo) const
{ return cull(nv, drawable, renderInfo? renderInfo->getState():0); }