zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    多线程、事件驱动与推荐引擎框架选型
    Protobuf协议应用干货
    集群选举算法实现
    基于OpenSSL的HTTPS通信C++实现
    通过UNIX域套接字传递描述符的应用
    我的博客即将入驻“云栖社区”,诚邀技术同仁一同入驻。
    C++反射机制:可变参数模板实现C++反射
    git多个远程仓库
    设计模式—模板方法的C++实现
    Java中的运算符
  • 原文地址:https://www.cnblogs.com/mazhenyu/p/7054087.html
Copyright © 2011-2022 走看看