|
楼主 |
发表于 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大哥帮忙思考,指点方向! |
|