1. 程式人生 > >OSG立體模式下動態修改相機遠近裁剪面的實現

OSG立體模式下動態修改相機遠近裁剪面的實現

void base call struct clam ppr cti llc 源代碼

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立體模式下動態修改相機遠近裁剪面的實現