首页 > 代码库 > OSG立体模式下动态修改相机远近裁剪面的实现
OSG立体模式下动态修改相机远近裁剪面的实现
1. 非立体模式下动态修改相机远近裁剪面
class GLB_DLLCLASS_EXPORT CGlbGlobeClipHandler : public osg::NodeCallback
{
struct CustomProjClamper : public osg::CullSettings::ClampProjectionMatrixCallback
{
template<class matrix_type, class value_type>
bool _clampProjectionMatrix(matrix_type& projection, double& znear, double& zfar, value_type nearFarRatio) const
{....}
...........
}
}
mpr_cliphandler = new CGlbGlobeClipHandler(p_globe);
mpr_p_root->setUpdateCallback((osg::NodeCallback*)mpr_cliphandler);
在根节点回调中mpr_cliphandler计算CustomProjClamper的成员变量double _nearFarRatio的值,然后在_clampProjectionMatrix中使用它来计算最远最近裁剪面.
osg::ref_ptr<osg::CullSettings::ClampProjectionMatrixCallback> clamper = new CGlbGlobeClipHandler::CustomProjClamper();
mpr_cliphandler->mpr_p_clampers[mpr_osgviewer->getCamera()] = clamper;
mpr_osgviewer->getCamera()->setClampProjectionMatrixCallback(clamper.get());
2. 立体模式下动态修改相机远近裁剪面
在osg3.2.1版本上测试发现,红绿立体模式、Quad_Buffer立体模式下以上代码不起作用,不能动态修改远近裁剪面 。
追踪源代码发现在 osgUtil的SceneView类 void SceneView::cull()中以下代码
_cullVisitorLeft->setDatabaseRequestHandler(_cullVisitor->getDatabaseRequestHandler());
_cullVisitorLeft->setClampProjectionMatrixCallback(_cullVisitor->getClampProjectionMatrixCallback());
_cullVisitorLeft->setTraversalMask(_cullMaskLeft);
computeLeftEyeViewport(getViewport());
bool computeNearFar = cullStage(computeLeftEyeProjection(getProjectionMatrix()),computeLeftEyeView(getViewMatrix()),_cullVisitorLeft.get(),_stateGraphLeft.get(),_renderStageLeft.get(),_viewportLeft.get());
// set up the right eye.
_cullVisitorRight->setDatabaseRequestHandler(_cullVisitor->getDatabaseRequestHandler());
_cullVisitorRight->setClampProjectionMatrixCallback(_cullVisitor->getClampProjectionMatrixCallback());
_cullVisitorRight->setTraversalMask(_cullMaskRight);
computeRightEyeViewport(getViewport());
computeNearFar = cullStage(computeRightEyeProjection(getProjectionMatrix()),computeRightEyeView(getViewMatrix()),_cullVisitorRight.get(),_stateGraphRight.get(),_renderStageRight.get(),_viewportRight.get());
if (computeNearFar)
{
CullVisitor::value_type zNear = osg::minimum(_cullVisitorLeft->getCalculatedNearPlane(),_cullVisitorRight->getCalculatedNearPlane());
CullVisitor::value_type zFar = osg::maximum(_cullVisitorLeft->getCalculatedFarPlane(),_cullVisitorRight->getCalculatedFarPlane());
_cullVisitor->clampProjectionMatrix(getProjectionMatrix(),zNear,zFar);
}
跟踪发现_cullVisitor中的_clampProjectionMatrixCallback对象为空,说明对主camera设置ClampProjectionMatrixCallback不能影响到_cullVisitor的_clampProjectionMatrixCallback。
这样解决办法就出来了,将主camera用到的ClampProjectionMatrixCallback对象设置一份给_cullVisitor就可以了!!!!!!!!!!
经测试通过,方法可行............................OK
OSG立体模式下动态修改相机远近裁剪面的实现