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

 void multiWindowMultipleCameras(osgViewer::Viewer& viewer,bool multipleScreens)
{
osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
if (!wsi)
{
osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
return;
} unsigned int width, height;
osg::GraphicsContext::ScreenIdentifier main_screen_id; main_screen_id.readDISPLAY();
main_screen_id.setUndefinedScreenDetailsToDefaultScreen();
wsi->getScreenResolution(main_screen_id, width, height);
unsigned int numCameras = ;
double aspectRatioScale = (double)numCameras;
double translate_x = double(numCameras)-;
for(unsigned int i=; i<numCameras;++i, translate_x -= 2.0)
{
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->screenNum = multipleScreens ? i / : ;
traits->x = (i*width)/numCameras;
traits->y = ;
traits->width = width/numCameras-;
traits->height = height;
traits->windowDecoration = true;
traits->doubleBuffer = true;
traits->sharedContext = ;
traits->readDISPLAY();
traits->setUndefinedScreenDetailsToDefaultScreen();
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
if (gc.valid())
{
osg::notify(osg::INFO)<<" GraphicsWindow has been created successfully."<<std::endl;
}
else
{
osg::notify(osg::NOTICE)<<" GraphicsWindow has not been created successfully."<<std::endl;
} osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setGraphicsContext(gc.get());
camera->setViewport(new osg::Viewport(,, width/numCameras, height));
GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
camera->setDrawBuffer(buffer);
camera->setReadBuffer(buffer);
viewer.addSlave(camera.get(), osg::Matrix::scale(aspectRatioScale, 1.0, 1.0)*osg::Matrix::translate(translate_x, 0.0, 0.0), osg::Matrix() );
}
}

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

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

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

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

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

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

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

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

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

viewer.addSlave(camera.get(), osg::Matrix::scale(aspectRatioScale, 1.0, 1.0)*osg::Matrix::translate(translate_x, 0.0, 0.0), 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

      ...        ...

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

最新文章

  1. jquery处理json对象
  2. cocos2d-js 3.0rc0加载游戏引擎时长时间黑屏
  3. 第20章 priority_queue优先队列容器
  4. sql server2008企业版和标准版
  5. 从协议VersionedProtocol开始4&mdash;&mdash;AdminOperationsProtocol、InterTrackerProtocol、JobSubmissionProtocol、TaskUmbilicalProtocol
  6. 字符串(马拉车算法,后缀数组,稀疏表):BZOJ 3676 [Apio2014]回文串
  7. postgres中的merge join
  8. js千分位转换
  9. JQuery日记_5.13 Sizzle选择器(六)选择器的效率
  10. [CSS3] 学习笔记-CSS3选择器详解(一)
  11. SpringBoot系列: RestTemplate 快速入门
  12. PHP:产生不反复随机数的方法
  13. JBPM工作流(七)——详解流程图
  14. JustOj 2039: 成绩排名 (结构体排序)
  15. 深入了解JVW
  16. js图片预加载后触发操作
  17. Java 获取并计算程序执行时间
  18. localhost与127.0.0.1及本机ip的区别
  19. 自然语言交流系统 phxnet团队 创新实训 个人博客 (十四)
  20. python将xml转换成json数据

热门文章

  1. python 模块调用的几种方式
  2. vue.js(17)--vue的组件切换
  3. python常用函数 V
  4. Mac sublime 安装包的时候出现 unable to download xxx (_ssl.c:548)
  5. java 继承父类并实现接口、接口之间的多继承
  6. case_when
  7. CSS3弹性盒模型flexbox布局
  8. sed 搜索并替换
  9. B1001. 害死人不偿命的(3n + 1)猜想
  10. 033:DTL常用过滤器(2)