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

 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

      ...        ...

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

Learning OSG programing---Multi Camera in Multi window 在多窗口中创建多相机的更多相关文章

  1. Learning OSG programing---Multi Camera in one window 在单窗口中创建多相机

    在学习OSG提供的例子osgCamera中,由于例子很长,涉及很多细节,考虑将其分解为几个小例子.本文介绍实现在一个窗口中添加多个相机的功能. 此函数接受一个Viewer引用类型参数,设置图形上下文的 ...

  2. 让一个表单以post的方式在window.open的窗口中打开

    我们都知道window.open(url)是最基本的用法,很多人都在url里用?xx=11&yy=22的方式拼接参数,但是其实我们不愿意让使用者看到后面的参数,这时我们可以如下方法 JS如下: ...

  3. 从window 的cmd窗口中下载linux 服务器上文件

    下载linux 服务器上的文件 down.php 格式为  pscp linux服务器上用户名@linux 服务器ip  文件在windows系统上的绝对路径 如果是下载服务器上的某个目录,只要在ps ...

  4. Learning OSG programing---osgScribe

    Learning OSG programing---osgScribe Scribe可以翻译为素描,抄写等.本例通过在模型表面添加一层素描,来显示模型的骨架. 关键代码: osg::ref_ptr&l ...

  5. JS判断鼠标进入容器方向的方法和分析window.open新窗口被拦截的问题

    1.鼠标进入容器方向的判定 判断鼠标从哪个方向进入元素容器是一个经常碰到的问题,如何来判断呢?首先想到的是:获取鼠标的位置,然后经过一大堆的if..else逻辑来确定.这样的做法比较繁琐,下面介绍两种 ...

  6. [LeetCode] Sliding Window Maximum 滑动窗口最大值

    Given an array nums, there is a sliding window of size k which is moving from the very left of the a ...

  7. nw.js FrameLess Window下的窗口拖拽与窗口大小控制

    nw.js FrameLess Window下的窗口拖拽与窗口大小控制 很多时候,我们觉得系统的Frame框很难看,于是想自定义. 自定义Frame的第一步是在package.config文件中将fr ...

  8. 在Window的IIS中创建FTP的Site并用C#进行文件的上传下载

    文件传输协议 (FTP) 是一个标准协议,可用来通过 Internet 将文件从一台计算机移到另一台计算机. 这些文件存储在运行 FTP 服务器软件的服务器计算机上. 然后,远程计算机可以使用 FTP ...

  9. JavaScript(Iframe、window.open、window.showModalDialog)父窗口与子窗口之间的操作

    一.Iframe 篇 公共部分 //父对象得到子窗口的值 //ObjectID是窗口标识,ContentID是元素ID function GetValue(ObjectID,ContentID) { ...

随机推荐

  1. wxpython模板程序,包括各个实例

    #coding=utf-8 import wx import time import os class MyApp(wx.App): def __init__(self): wx.App.__init ...

  2. ES6——Promise

    异步和同步 异步,操作之间没有关系,同时执行多个操作, 代码复杂 同步,同时只能做一件事,代码简单 Promise 对象 用同步的方式来书写异步代码 Promise 让异步操作写起来,像在写同步操作的 ...

  3. C++宽字符串转字符串

    这文章是更改别人代码 #include <string> #include <iostream> #include <stdlib.h> #include < ...

  4. Python2视频教程

    目录 1. 说明 1.1. 马哥视频_修复v1 1.2. 马哥视频_修复v2 2. 目录 3. 下载链接 1. 说明 Python从入门到精通视频(全60集)马哥教育视频(已修复部分视频无声音的问题+ ...

  5. 【转】DDR3和eMMC区别

    转自:https://www.cnblogs.com/debruyne/p/9186619.html DDR3内存条和eMMC存储器区别: 1. 存储性质不同:2. 存储容量不同:3. 运行速度不同: ...

  6. 【LeetCode】二分 binary_search(共58题)

    [4]Median of Two Sorted Arrays [29]Divide Two Integers [33]Search in Rotated Sorted Array [34]Find F ...

  7. dsu on tree 学习笔记

    这是一个黑科技,考虑树链剖分后,每个点只会在轻重链之间转化\(log\)次. 考虑暴力是怎么写的,每次枚举一个点,再暴力把子树全部扫一边. \(dsu\ on\ tree.\)的思想就是保留重儿子不清 ...

  8. 转Serial,Parallel,CMS,G1四大GC收集器特点小结

    转 https://blog.csdn.net/u013812939/article/details/48782343 1.Serial收集器 一个单线程的收集器,在进行垃圾收集时候,必须暂停其他所有 ...

  9. windows下zookeeper集群安装

    windows下zookeeper单机版安装,见:https://www.cnblogs.com/lbky/p/9867899.html 一:zookeeper节点为什么是奇数个? 单机模式的zk进程 ...

  10. man mkfs

    ---恢复内容开始--- MKFS(8)                                                                MKFS(8) NAME/名称  ...