查看: 3101|回复: 12

RTT中camera的设置

[复制链接]

该用户从未签到

发表于 2009-2-20 10:19:28 | 显示全部楼层 |阅读模式
我要做一个模型的RTT,按照如下步骤:
首先,我从文件中Load一个模型:      osg::ref_ptr<osg::Node>        node = osgDB::readNodeFile("D:/osg/13.osg");
然后,我要将该模型渲染到纹理对象(FBO),那么我需要创建一张纹理,作为RTT的输出纹理,同时要创建一个摄像机节点,如下:
osg::ref_ptr<osg::Texture*> texture = createFBO(tex_width, tex_height);
osg::ref_ptr<osg::Camera>  camera = setUpCamera(node, texture);
这里有几个个问题:
(1)该摄像机的投影矩阵应当如何设置,从而可以保证node中的几何体都能渲染到texture上
(2)在osg中如何获得屏幕尺寸,从而可以指定texture的尺寸为电脑屏幕大小

该用户从未签到

发表于 2009-2-20 10:42:21 | 显示全部楼层
投影矩阵的设置可以参看OpenGL红宝书中的相关内容

获取屏幕尺寸的话
caemra->graphicsContext();
然后动态转换GC设备为GraphiscWindow指针
gw->getWindowRectangle(x,y,w,h);
应该可以。

该用户从未签到

 楼主| 发表于 2009-2-20 10:48:04 | 显示全部楼层
问题是如何保证这个camera与场景的主camera的设置一致,因为我要做的相当于将场景图像原封不动的绘制到FBO,所以投影矩阵应该和场景的主camera设置完全一致才可以的,那怎样做才能保持一致呢?

该用户从未签到

 楼主| 发表于 2009-2-20 12:05:58 | 显示全部楼层
我的意思就是当我将模型读入并绘制的时候,并不需要我手动的去设置投影矩阵,osg会自动的把场景绘制出来,代码如下:
        osg::ref_ptr<osg::Node>                scenenode= osgDB::readNodeFile("D:/osg/13.osg");
        osg::ref_ptr<osg::Group>        root = new osg::Group;

        // render to target
        unsigned int tex_width = 1024;
        unsigned int tex_height = 512;
        root->addChild(createPreRenderSubGraph(scenenode, tex_width, tex_height)); //问题是在这里如何设置相机的投影矩阵参数?从而保证FBO中的内容与下面所绘制的内容相同因为我    也不知道在下面的绘制中投影矩阵是如何设置的

       //render the model in the file "13.osg"
        root->addChild(scenenode.get());

        viewer.setCameraManipulator(new osgGA::TrackballManipulator());

        viewer.setSceneData( root );

        viewer.realize();

        while( !viewer.done() )
        {
                viewer.frame();
        }

该用户从未签到

发表于 2009-2-20 12:47:54 | 显示全部楼层
如果您想和主摄像机保持一致,那么方法很多。例如您可以派生一个新的摄像机对象,并把主摄像机的指针传递为它的成员,再随时进行同步。或者派生一个摄像机对象并重写traverse函数,从输入参数中得到CullVisitor指针以后从中取出当前的模型视点矩阵和投影矩阵

该用户从未签到

 楼主| 发表于 2009-2-20 13:05:05 | 显示全部楼层
如何派生?又如何进行同步?RTT摄像机也要setCameraManipulator吗?

该用户从未签到

发表于 2009-2-20 13:16:01 | 显示全部楼层
派生是C++的概念,就是自己继承Camera写一个新的类,例如命名为FboCamera,然后把主摄像机的指针传给它就可以了;不过我个人更喜欢重载traverse函数。不要拘泥于例子中的做法,那只是做示范用的,真正做工程的时候要大量派生OSG类库并重写代码的。

该用户从未签到

 楼主| 发表于 2009-2-20 13:21:51 | 显示全部楼层
哪个例子里面有摄像机派生的例子,或者重载traverse函数的程序,我去研究一下,我对Camera这个类还不熟悉。谢谢

该用户从未签到

发表于 2009-2-20 13:42:48 | 显示全部楼层
摄像机类本身就是派生自Group节点的,其它很多类也重载了Group的traverse函数,可以直接看OSG的源代码。

该用户从未签到

 楼主| 发表于 2009-2-23 14:06:16 | 显示全部楼层
但是我的主场景里面加入了TrackballManipulator对象来进行交互操作,如何使得RTT摄像机与主摄像机保持同步?
TrackballManipulator是否是通过改变Camera的ModelView matrix来旋转视点的,他会对投影矩阵产生影响吗?
那个这个TrackballManipulator的矩阵是怎么样作用到Camera的矩阵呢?是preMult还是postMult?还是其他的方法?

[ 本帖最后由 panbin 于 2009-2-23 14:12 编辑 ]

该用户从未签到

发表于 2009-2-23 14:49:42 | 显示全部楼层
TrackballManipulator是不影响投影矩阵的,只影响摄像机的观察矩阵(VIewMatrix)。实现机制也很简单,就是假设摄像机是场景中的一个物体,使用漫游器控制它移动到世界的某个位置,旋转某个角度,然后将摄像机的位置姿态矩阵求逆,这个逆矩阵就是摄像机的观察矩阵,直接设置给Camera::setViewMatrix即可,不需要preMult或postMult。

该用户从未签到

 楼主| 发表于 2009-2-23 15:16:27 | 显示全部楼层
谢谢楼主,搞定了!这个Trackballmanipulator的机制就是操纵摄像机绕经过裁剪得到视景体进行变换(平移,放缩,旋转),而实际的三维场景是不动的。
那为什么还要求逆呢?

该用户从未签到

发表于 2009-2-23 16:12:37 | 显示全部楼层
对于摄像机来说,观察矩阵 = 位置姿态矩阵的逆矩阵。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表