加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

Learning OSG programing---Multi Camera in Multi window 在多

发布时间:2020-12-14 02:47:34 所属栏目:Windows 来源:网络整理
导读:这个例子演示了在多个窗口中创建多个相机,函数的代码如下: 1 void multiWindowMultipleCameras(osgViewer::Viewer viewer, bool multipleScreens) 2 { 3 osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystem

  这个例子演示了在多个窗口中创建多个相机,函数的代码如下:

 1 void multiWindowMultipleCameras(osgViewer::Viewer& viewer,bool multipleScreens)
 2 {
 3     osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
 4     if (!wsi)
 5     {   
 6         osg::notify(osg::NOTICE)<<"Error,no WindowSystemInterface available,cannot create windows."<<std::endl;
 7         return;
 8     }
 9 
10     unsigned int width,height;
11     osg::GraphicsContext::ScreenIdentifier main_screen_id;
12 
13     main_screen_id.readDISPLAY();
14     main_screen_id.setUndefinedScreenDetailsToDefaultScreen();
15     wsi->getScreenResolution(main_screen_id,width,height);
16     unsigned int numCameras = 3;
17     double aspectRatioScale = (double)numCameras;
18     double translate_x = double(numCameras)-1;
19     for(unsigned int i=0; i<numCameras;++i,translate_x -= 2.0)
20     {
21         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
22         traits->screenNum = multipleScreens ? i / 3 : 0;
23         traits->x = (i*width)/numCameras;
24         traits->y = 0;
25         traits->width = width/numCameras-1;
26         traits->height = height;
27         traits->windowDecoration = true;
28         traits->doubleBuffer = true;
29         traits->sharedContext = 0;
30         traits->readDISPLAY();
31         traits->setUndefinedScreenDetailsToDefaultScreen();
32         osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
33         if (gc.valid())
34         {
35             osg::notify(osg::INFO)<<"  GraphicsWindow has been created successfully."<<std::endl;
36         }
37         else
38         {
39             osg::notify(osg::NOTICE)<<"  GraphicsWindow has not been created successfully."<<std::endl;
40         }
41 
42         osg::ref_ptr<osg::Camera> camera = new osg::Camera;
43         camera->setGraphicsContext(gc.get());
44         camera->setViewport(new osg::Viewport(0,0,width/numCameras,height));
45         GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
46         camera->setDrawBuffer(buffer);
47         camera->setReadBuffer(buffer);
48 viewer.addSlave(camera.get(),osg::Matrix::scale(aspectRatioScale,1.0,1.0)*osg::Matrix::translate(translate_x,0.0,0.0),osg::Matrix() );
49     }
50 }

  程序中用到了addSlave函数,此函数接受三个参数,分别为摄像机地址,投影偏移矩阵,视图偏移矩阵。由48行可知,每次向观察器中添加从相机时,都对相机的投影偏移矩阵进行设置(第二个参数)。

  在这里做一个实验,验证addSlave函数第二个参数的作用。将multiWindowMultipleCameras函数中最后一行代码改为:

?

viewer.addSlave(camera.get(),osg::Matrix(),osg::Matrix() );

?

  即将函数的投影偏移矩阵设为单位矩阵。运行程序,产生的结果如下:

由上图可知,由于没有对投影矩阵进行变换,将在三个窗口中分别产生相同的模型,而没有产生共屏效果。若想达到共屏的效果,需要对投影偏移矩阵进行设置。

  首先设置投影偏移矩阵为平移,函数中有变量translate_x,其初始值为numCameras-1,在本例中即为2,随着每次循环,其值都将减少2。因此三次循环后,translate_x产生的序列为2,-2。为此,将添加从相机的语句改为:

viewer.addSlave(camera.get(),osg::Matrix::translate(translate_x,0.0),osg::Matrix() );

  运行修改后的程序,得到以下结果:

  从上图可以看到,三块屏幕之间产生联系了,模型可以跨窗口显示了。但是仍存在明显缺陷:模型在水平方向被压缩了。可能是由于每个小窗口在水平方向上被压缩,导致模型被压缩。为此考虑对模型进行水平方向上的拉伸。由于原有的整块屏幕现在被平均分割为三块,因此考虑将模型在水平方向上拉伸三倍(即屏幕数量倍)。仍然修改投影偏移矩阵:

viewer.addSlave(camera.get(),osg::Matrix() );

运行程序,出现如下效果:

可以看到,达到了预期效果,只是模型相比于普通的用osgviewer cow.osg命令时在水平方向上略显拉伸。

  这里还有一个问题,为什么translate_x的初始值要设为numCameras-1,并且每次循环都要减少2?略加思考,就能得到答案,为了产生左右对称的偏移量:

  numCameras    translate_x

     3        2? 0? -2

     ? 4        3? 1? -1? -3

    ?? 5        4? 2? 0? -2? -4

    ? ...        ...

以此类推。此外,还可以修改视图偏移矩阵来设置从不同的角度观察。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读