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立体模式下动态修改相机远近裁剪面的实现的更多相关文章

  1. 【案例分享】使用ActiveReports报表工具,在.NET MVC模式下动态创建报表

    提起报表,大家会觉得即熟悉又陌生,好像常常在工作中使用,又似乎无法准确描述报表.今天我们来一起了解一下什么是报表,报表的结构.构成元素,以及为什么需要报表. 什么是报表 简单的说:报表就是通过表格.图 ...

  2. ubunut在系统恢复模式下无法修改root密码的分析和解决

    前些日子本猫的ubuntu 14.10貌似出了点问题,想修改下root密码,但是无奈原系统有错正常情况下无法修改啊,这是逼我重装的节奏吗? 在ubuntu开机后立即按住left_shift不放,调出g ...

  3. JMeter命令模式下动态设置线程组和持续时间等动态传参

    背景: 1.当通过JMeter的图像化界面运行性能压测或者场景时候,JMeter界面很容易导致界面卡死或者无响应的情况(20个线程数就会卡死) 现象如下:

  4. Unity3D Editor模式下批量修改prefab

    最经遇到一个需要批量修改已经做好的prefab的问题,查了一些资料最终实现了但是还是不够完美,通过学习也发现unity的编辑器功能还是非常强大的.废话不多说直接上代码: [ExecuteInEditM ...

  5. Vim保存只读模式下的修改

    用 vim 打开没有写权限的文件而忘记用 sudo 时,文件变成 read-only这时候用 :w!, SHIFT+ZZ,或者 qw! 都无法保存 :w !sudo tee % :w : Write ...

  6. linux VI模式下批量修改文件内容

    1.         :s/vivian/sky/ 替换当前行第一个 vivian 为 sky            :s/vivian/sky/g 替换当前行所有 vivian 为 sky 2.   ...

  7. CentOS单用户模式下修改ROOT密码和grub加密

    Linux 系统处于正常状态时,服务器主机开机(或重新启动)后,能够由系统引导器程序自动引导 Linux 系统启动到多用户模式,并提供正常的网络服务.如果系统管理员需要进行系统维护或系统出现启动异常时 ...

  8. 单用户模式下mount -o remount,rw / 有大用途

    我们的Linux系统在无法启动时候,通常需要进入单用户模式下进行修改一些配置文件,或调整一些参数方可.但是在进入单用户模式后,我们的/文件系统是只读模式,无法进行修改,那么这个时候我们就需要用到一条命 ...

  9. Linux Vi/Vim 在插入模式下键盘右边数字键输入异常

    问题:Linux在 Vi/Vim 在编辑文件时遇到一个问题,当我在 Insert 模式下进行修改文件内容的时候,用到了键盘(104键,右边带数字键那种)进行数字输入,当我输入数字 “5” 时,插入的数 ...

随机推荐

  1. pku 2777(经典线段树染色问题)

    Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 41202   Accepted: 12458 Des ...

  2. JSTL <c:if test=“eq ne lt..”></if> 用法

    类别 运算符 算术运算符 + . - . * . / (或 div )和 % (或 mod ) 关系运算符 == (或 eq ). != (或 ne ). < (或 lt ). > (或 ...

  3. 单源点最短路径的Dijkstra算法

    在带权图(网)里,点A到点B所有路径中边的权值之和为最短的那一条路径,称为A,B两点之间的最短路径;并称路径上的第一个顶点为源点(Source),最后一个顶点为终点(Destination).在无权图 ...

  4. Java 创建线程的方法

    为了偷懒少敲几个字这里我写了一个Util类: package test; public class Util { static void println() {System.out.println() ...

  5. 合并区间(LintCode)

    合并区间 给出若干闭合区间,合并所有重叠的部分. 样例 给出的区间列表 => 合并后的区间列表: [ [ [1, 3], [1, 6], [2, 6], => [8, 10], [8, 1 ...

  6. 服务器Tomcat WAS JBoss

    做任何web项目,都离不开服务器,有钱的公司用WebSphere.WebLogic,没钱公司用nginx+tomcat,不要小瞧nginx+tomcat麻雀虽小,五脏俱全. 服务器的知识,在笔试.面试 ...

  7. 理解Python的迭代器(转)

    原文地址: http://python.jobbole.com/81916/ 另外一篇文章: http://www.cnblogs.com/kaituorensheng/p/3826911.html ...

  8. EasyUI学习总结(四)——parser源码分析(转载)

    本文转载自:http://www.cnblogs.com/xdp-gacl/p/4082561.html parser模块是easyloader第一个加载的模块,它的主要作用,就是扫描页面上easyu ...

  9. 安卓 内存泄漏 MemoryAnalyzer

    韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com 需要 获取 root 权限 步骤: 1,使用eclipse 自带的 DDMS 工具分析各线程的内 ...

  10. Manacher算法总结

    部分图片转自:http://www.cnblogs.com/grandyang/p/4475985.html manacher算法(民间称马拉车算法233)是用来找字符串中的最长回文子串的,先来说一下 ...