查看: 1450|回复: 3

RTT的问题

[复制链接]

该用户从未签到

发表于 2010-5-18 16:57:24 | 显示全部楼层 |阅读模式
遇到一个非常棘手的矩阵问题:
我做了一个圆盘,放在地形的上面,期望达到“透视镜”的效果,即,透过这个圆盘,可以看到地底下的物体。
我实现的思路简单描述如下:
1、做了一个圆盘的物体,给它贴了一个纹理T。同时,绘制这个圆盘使用的是一个HUD,当然使用Camera节点来实现比较合适。
2、做一个Camera节点,实现RTT,将地底下的物体通过该Camera,渲染到纹理T。
3、做一个CullCallback,挂接到HUD相机上,每一帧都把主相机矩阵的旋转部分设置到HUD的相机里面去。设置RTT相机的矩阵也在这里。

遇到的问题:
圆盘只有在正对着视口的时候,才可以看到内外是拼接好的。否则就拼接不起来。如下图,第一张是正对着的情况,第二张是斜着看的情况。
1.jpg
2.jpg

该用户从未签到

 楼主| 发表于 2010-5-18 16:58:44 | 显示全部楼层
本帖最后由 yin_savage 于 2010-5-18 17:00 编辑

下面是CullCallback中的实现代码,麻烦大家看看,若要完整的源代码,我也可以上传。

// 0、准备工作
        osgUtil::CullVisitor *pCullVisitor = dynamic_cast<osgUtil::CullVisitor *>(pNodeVisitor);
        if(!pCullVisitor)
        {
            traverse(pNode, pNodeVisitor);
                return;
        }

        const osg::RenderInfo &info = pCullVisitor->getRenderInfo();
        const osgViewer::View *pView = dynamic_cast<const osgViewer::View *>(info.getView());
        const osg::Camera *pCamera = pView->getCamera();


        // 1、设置HUD相机的参数
        // 1.1、设置HUD相机的视口
        osg::Camera *pHudCamera = dynamic_cast<osg::Camera *>(pNode);
        const osg::Viewport *pCurViewport = pCamera->getViewport();
        const float fltSize = m_fltScopeSize * (pCurViewport->width() < pCurViewport->height() ? pCurViewport->width() : pCurViewport->height());
        const float fltX = (pCurViewport->width() - fltSize) * 0.5f;
        const float fltY = (pCurViewport->height() - fltSize) * 0.5f;
        pHudCamera->setViewport(int(fltX + 0.5f), int(fltY + 0.5f), int(fltSize + 0.5f), int(fltSize + 0.5f));

        // 1.2、设置HUD相机的模型视图矩阵
        const osg::Matrixd &mtxModelView = pCamera->getViewMatrix();
        const osg:uat                quatRotate = mtxModelView.getRotate();
        pHudCamera->setViewMatrix(osg::Matrixd(quatRotate));


        // 2、设置RTT相机的参数
        // 2.1、设置RTT相机的投影矩阵
        const osg::Matrixd &mtxProjection = pCamera->getProjectionMatrix();
        double dblLeft = -1.0, dblRight = 1.0, dblBottom = -1.0, dblTop = 1.0, dblNear = 1.0, dblFar = 2.0;
        bool bOrthoProj = false, bFrustumProj = false;
        if(mtxProjection.getFrustum(dblLeft, dblRight, dblBottom, dblTop, dblNear, dblFar))
        {
                bFrustumProj = true;
        }
        else if(mtxProjection.getOrtho(dblLeft, dblRight, dblBottom, dblTop, dblNear, dblFar))
        {
                bOrthoProj = true;
        }

        if(bFrustumProj || bOrthoProj)
        {
                const double dblWidth = dblRight - dblLeft;
                const double dblHeight = dblTop - dblBottom;
                const double dblSize = (dblWidth < dblHeight ? dblWidth : dblHeight) * 0.5 * m_fltScopeSize;

                if(bFrustumProj)
                {
                        m_pRttCamera->setProjectionMatrixAsFrustum(-dblSize, dblSize, -dblSize, dblSize, dblNear, dblFar);
                }
                else
                {
                        m_pRttCamera->setProjectionMatrixAsOrtho(-dblSize, dblSize, -dblSize, dblSize, dblNear, dblFar);
                }
        }

        // 2.2、设置RTT相机的模型视图矩阵
        const osg::Matrixd mtxRotate(quatRotate.inverse());
        m_pRttCamera->setViewMatrix(mtxRotate * mtxModelView);

        // 缺省处理
        traverse(pNode, pNodeVisitor);

该用户从未签到

 楼主| 发表于 2010-5-18 17:01:32 | 显示全部楼层
上面是CullCallback的全部实现代码,大家要是需要完整的源代码,我可以上传。
这就是一个简单的控制台应用程序。

该用户从未签到

发表于 2010-5-18 17:10:37 | 显示全部楼层
一个很直接的问题:您是否每帧都在改变您的ViewMatrix,这样才能实现您所说的“圆盘内外是拼接好的”;否则的话,因为您改变了自己的观察角度,而RTT相机的观察角度没有随之改变,就会出现您所看到的问题
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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