查看: 4174|回复: 3

setProjectionMatrixAsPerspective()函数中,fovy值与aspectRatio是不是相互关联的

[复制链接]

该用户从未签到

发表于 2012-11-21 21:11:36 | 显示全部楼层 |阅读模式
如题:
不是很明白fovy值与aspectRatio的关系,感觉他们两个是相互关联的,如果我将fovy值设置成90的话,aspectRatio的值也就变化了,不知道能不能单独设置它们两个呢?主要是我想设置fovy的值使得视野变得宽一点,但是这个时候因为影响了宽高比,所以导致用三个投影仪组成的显示屏幕出现的场景存在拉伸变形。但是如果要使场景不存在拉伸变形的话,只有设置正确宽高比,可是设置了正确的宽高比以后,场景是不变形了,可是fovy的值又不起作用了,导致视野又特别的窄。所以就想着,这二者能不能兼顾呢?还请各位高手指点!!!

该用户从未签到

发表于 2012-11-22 17:18:41 | 显示全部楼层
OSG在窗口大小发生改变时会自动重新计算aspectRatio,如果要屏蔽这一特性,需要设置setProjectionResizePolicy为FIXED

该用户从未签到

 楼主| 发表于 2012-11-22 17:52:39 | 显示全部楼层
array 发表于 2012-11-22 17:18
OSG在窗口大小发生改变时会自动重新计算aspectRatio,如果要屏蔽这一特性,需要设置setProjectionResizePol ...

嗯,谢谢array大哥!array大哥,上次那个由于透视投影导致的拉伸形变还是没有解决啊!
给你发个链接的帖子:您帮忙看一下吧,呵呵!
我现在主要在做类似与威力强一样的三屏显示。
我大概描述一下:
外部硬件环境:
三个大的屏幕,中间的屏幕是平的,两边的屏幕与中间的屏幕成一定的夹角,外形类似梯形。每个屏幕对应一个投影仪显示。也就是三个投影仪合成显示出同一个场景。然后三个投影仪都是接在了一个由主机接出来的分屏器上。

目前的问题:
显示出来的场景,两边的投影仪显示的场景存在很大的横向拉伸变形。中间的场景没有。

软件部分:
之前程序中用了一个主相机,没有从相机,使用透视投影,调整fovy值到60度时,变形严重,fovy值愈大,变形越严重。即便调整好宽高比也如此!
我现在的想法是想用三个相机渲染,其中主相机对应的视口是中间的投影仪,从相机用的视口使用的是两边的投影仪的。程序中分别设置好。然后运行程序,偏移矩阵没有问题,三个相机对应响应的投影仪视口确实显示了完整的场景,但是,仍然存在很大的拉伸形变,跟一个相机的时候的渲染情况是一样的。

相关的一些代码:
代码如下:
//创建从相机,设置视口
osg::Camera* createCamera(int x, int y, int w, int h)
{
        osg::ref_ptr<osg::GraphicsContext::Traits> trait = new osg::GraphicsContext::Traits();
        trait->x = x;
        trait->y = y;
        trait->width = w;
        trait->height = h;
        trait->windowDecoration = false;
        trait->doubleBuffer = true;

        osg:isplaySettings *ds = osg:isplaySettings::instance();
        trait->alpha = ds->getMinimumNumAlphaBits();
        trait->stencil = ds->getMinimumNumStencilBits();
        trait->sampleBuffers = ds->getMultiSamples();
        trait->samples = ds->getNumMultiSamples();

        osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(trait.get());
        osg::ref_ptr<osg::Camera> camera = new osg::Camera();
        camera->setGraphicsContext(gc.get());
        camera->setViewport(new osg::Viewport(0,0,w,h));
        //camera->setReferenceFrame(osg::Camera::ReferenceFrame::ABSOLUTE_RF_INHERIT_VIEWPOINT);

        double fov;
        double aspectRatio;
        double nearPlane;
        double farPlane;

        double newAspectRatio;
        camera->setProjectionResizePolicy(osg::Camera:rojectionResizePolicy::FIXED);
        //换取对称视景个参数并显示,每个屏幕都有对应的ratio,所以必须先get在set
        camera->getProjectionMatrixAsPerspective( fov,aspectRatio,nearPlane,farPlane);
        newAspectRatio = double(w)/double(h);
        //double aspectRatiochange = newAspectRatio/aspectRatio;
        //设置视景参数,将yz平面视野角度设为50°
        camera->setProjectionMatrixAsPerspective(60.0f, aspectRatio, 1, 500.0);

        return camera.release();
}

//主相机设置

        //得到窗口的图形环境
        osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
        if (!wsi)
        {
                osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
        }
        unsigned int tileWidth, tileHeight;
        wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), tileWidth ,tileHeight);



        //初始化主相机图形环境
        osg::ref_ptr<osg::GraphicsContext::Traits> mastertrait = new osg::GraphicsContext::Traits();
        mastertrait->x = tileWidth/3;
        mastertrait->y = 0;
        mastertrait->width = tileWidth/3;
        mastertrait->height = tileHeight;
        mastertrait->windowDecoration = false;
        mastertrait->doubleBuffer = true;
        mastertrait->useCursor = false;
        osg:isplaySettings *ds = osg:isplaySettings::instance();
        mastertrait->alpha = ds->getMinimumNumAlphaBits();
        mastertrait->stencil = ds->getMinimumNumStencilBits();
        mastertrait->sampleBuffers = ds->getMultiSamples();
        mastertrait->samples = ds->getNumMultiSamples();

        osg::ref_ptr<osg::GraphicsContext> mastergc = osg::GraphicsContext::createGraphicsContext(mastertrait.get());
        osg::ref_ptr<osg::Camera> masterCamera = new osg::Camera();
        masterCamera = viewer->getCamera();
        masterCamera->setGraphicsContext(mastergc.get());
        masterCamera->setViewport(new osg::Viewport(0,0,mastertrait->width,mastertrait->height));
               
//添加从相机,设置从相机的投影矩阵的偏移矩阵,设置好各个从相机的视口
     viewer->addSlave(createCamera(0,0,tileWidth/3,tileHeight),osg::Matrixd::translate(2,0.0,0.0),osg::Matrixd());
        viewer->addSlave(createCamera(2*tileWidth/3,0,tileWidth/3,tileHeight),osg::Matrixd::translate(-2,0.0,0.0),osg::Matrixd());


        viewer->getCamera()->setProjectionResizePolicy(osg::Camera:rojectionResizePolicy::FIXED);
        
        viewer->getCamera()->getProjectionMatrixAsPerspective( fovy,aspectRatio,nearPlane,farPlane);
        newAspectRatio = double(tileWidth)/double(tileHeight);
        double aspectRatiochange = newAspectRatio/aspectRatio;
        
        viewer->getCamera()->setProjectionMatrixAsPerspective(60.0f, aspectRatio, 1, 500.0);
        if(aspectRatiochange!=1.0)
        {
                viewer->getCamera()->getProjectionMatrix() *= osg::Matrix::scale(1.0/aspectRatiochange,1.0,1.0);
        }

写的比较多,还望array大哥谅解,折腾的时间比较长了,老板催的不行啊,呵呵,各种计算也都试过了,还是不行。恳请array大哥帮忙思考,指点方向!

该用户从未签到

发表于 2012-11-27 10:41:17 | 显示全部楼层
在另一个帖子里已经回答了,您没有把自己的projoffset真正带入到投影计算公式里面去看看结果吧。投影矩阵乘一个平移矩阵并不等于平移,这一点不要搞成想当然了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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