探索未知种族之osg类生物---器官初始化三
当判断到viewer中没有一个graphicContext可用时,osg就会默认的进行一次对viewer的实现操作,这样可以保证osg以后可以安心的在屏幕上进行作画。那我们就来看看这个osgViewer::Viewer::realize()函数到底具备什么样神奇的功能。
osgViewer::Viewer::realize()
osgViewer::Viewer::realize()的最要作用可以总结为激活设置窗口以及初始化关联线程。Viewer::getContexts()上一节以及进行了详细的介绍,就是得到所有相机上关联的图形设备器。当contexts为空时就代表不存在一个窗口set up,所以osg开启默认一个的视图。读取环境变量OSG_CONFIG_FILE,如果设置了OSG_CONFIG_FILE指向一个.view后缀的文件,可以创建该文件描述的窗口,格式如下:(在openscenegraph-data目录中的configuration目录下有.view类型的文件)
1
2
3
4
|
osgViewer::Viewer { setUpViewInWindow 100 200 600 400 0 } |
如果设置了OSG_CONFIG_FILE环境变量,但是环境变量所对应的文件解析有错,那么整个程序就会退出。
如果没有设置OSG_CONFIG_FILE环境变量,那么程序会检查 OSG_SCREEN和OSG_WINDOW这两个环境变量的值,OSG_SCREEN对应窗口的个数(值是一个整型数)OSG_WINDOW对应窗口的大小和位置,格式是(x, y, w, h) 分别是窗口左上角点坐标(x, y)以及窗口的长和宽(w, h),具体来说是以下情况:
当窗口设置完成之后,osg会再次调用getContexts(contexts) 搜集目前可用的设备渲染上下文,如果这时候还没有窗口产生,也就是说设置窗口的各种方式都失败了,那么程序就会退出,如果成功,那么会针对已经常见的窗口进行一些设置,完成后续的操作
接下来我们先简单的介绍一个表格中三个函数
这些函数调用了osgViewer命名空间中的三个窗口配置类,它们的关系如下图所示:
基类osgViewer::ViewConfig提供了一个虚函数 virtual void configure (osgViewer::View &) const,在子类中通过实现该函数来配置渲染的窗口大小和位置。
这里我们只对一个类的configure函数进行讲解,其他两个请大家自行了解。
AcrossAllScreens::configure(osgViewer::View& view)函数,首先调用osg::GraphicsContext的静态函数getWindowSystemInterface用于获得系统的api接口,至于这个api接口是怎么被创建的,我们需要在src/osg/GraphicsContext.cpp中找到setWindowSytemInterface函数,这里就是进行系统api的设置,他的作用是指定操作平台所使用的视窗 API 接口,也就是在特定的系统平台上创建图形窗口的时候,将会使用到哪些本地 API 函数。当然,Windows 系统要使用 Win32 API,而Linux 系统要使用 X11 API,Apple 系统则使用 Carbon。由于现在实在ubuntu16.04系统上,所以cmake只会把GraphicsWindowX11.cpp进行编译,所以想知道怎么指定的系统api接口在GraphicsContext中,我们需要进入GraphicsWindowX11.cpp的2136行的WindowingSystemInterface 结构体,这个结构体在初始化的时候就会调用。用于设置系统api接口。还 有 注 意 那 个 紧 跟 着 结 构 体 的 全 局 变 量(GraphicsWindowX11.cpp,2159 行),这就是osg设置系统api的基本流程,如果想深入了解,请自行查看。
回到AcrossAllScreens::configure(osgViewer::View& view)函数
osg::DisplaySettings
我们得到了系统api的指针,然后将尝试获取osg::DisplaySettings的指针,它保存了 OSG 目前用到的,与图形显示,尤其是立体显示有关的所有信息,
主要包括:
_displayType:显示器类型,默认为 MONITOR(监视器),此外还支持 POWERWALL(威力墙),REALITY_CENTER(虚拟实境中心)和 HEAD_MOUNTED_DISPLAY(头盔显示器)。
_stereoMode : 立 体 显 示 模 式 , 默 认 为 ANAGLYPHIC ( 互 补 色 ), 此 外 还 支 持QUAD_BUFFER (四方体缓冲), HORIZONTAL_SPLIT (水平分割), VERTICAL_SPLIT (垂直分割),LEFT_EYE(左眼用),RIGHT_EYE(右眼用),HORIZONTAL_INTERLACE(水平交错),VERTICAL_INTERLACE(垂直交错),CHECKERBOARD(棋盘式交错,用于DLP 显示器)。
_eyeSeparation:双眼的物理距离,默认为 0.05。
_screenWidth,_screenHeight:屏幕的实际宽度和高度,分别默认设置为 0.325 和 0.26,
目前它们影响的仅仅是视图采用透视投影时的宽高比。
_screenDistance:人眼到屏幕的距离,默认为 0.5。
_splitStereoHorizontalEyeMapping:默认为 LEFT_EYE_LEFT_VIEWPORT(左眼渲染左视口),也可设为 LEFT_EYE_RIGHT_VIEWPORT(左眼渲染右视口)。
_splitStereoHorizontalSeparation:左视口和右视口之间的距离(像素数),默认为 0。
_splitStereoVerticalEyeMapping:默认为 LEFT_EYE_TOP_VIEWPORT(左眼渲染顶视口),也可设为 LEFT_EYE_BOTTOM_VIEWPORT(左眼渲染底视口)。
_splitStereoVerticalSeparation:顶视口和底视口之间的距离(像素数),默认为 0。
_splitStereoAutoAdjustAspectRatio:默认为 true,用于屏幕分割之后对其宽高比进行补偿。
_maxNumOfGraphicsContexts:用户程序中最多可用的 GraphicsContext(图形设备上下文)数目,默认为 32 个。
_numMultiSamples:多重采样的子像素样本数,默认为 0。如果显示卡支持的话,打开多重采样可以大幅改善反走样(anti-aliasing)的效果。此外还有很多可以设置的类变量,如_minimumNumberStencilBits(模板缓存的最小位数)等,其默认设置均在 osg::DisplaySettings::setDefaults 函数中完成,其中有些变量可能还没有作用。要注意的是,DisplaySettings 的作用仅仅是保存所有可能在系统显示中用到的数据,这个类本身并不会据此改变任何系统设置和渲染方式。
再此回到AcrossAllScreens::configure(osgViewer::View& view)函数,我们上一节总结了一下osg::DisplaySettings的作用,我们继续看看配置一个osg内置的screen需要哪些设置。通过相机得到视椎体的一些信息(包含:fovy俯仰角,aspectRatio纵横比,zNear近平面, zFar远平面,其中这里用到的属性是aspectRatio,主要是用来确定当osg默认的与图形设备中设置的screen数目的相同的从相机中每一个从相机的视口的大小)。然后再通过ScreenIdentifier平面初始化器得到screenNum,displayNum,hostName的值。其中如果screenNum或displayNum未定义则设定为-1,这三个变量的最主要的作用是给GraphicsContext中的某些属性赋值。当displayNum的值是1,也就相当于创建一个SingleScreen,所以直接可以调用昨天提到的SingleScreen的configure函数,创建一个单独的屏幕来渲染三维世界就可以了,但是当displayNum的值大于1时,就需要用到分屏技术,通过创建多个从相机,来得到场景中的某一部分的视图,最后拼接成一个大的三维场景的方式。所以else(src\osgViewer\config\AcrossAllScreens.cpp\ AcrossAllScreens::configure 函数的第50行之后都是在创建多个GraphicsContext并付给相应的从相机。)
这样我们就介绍完了osg创建一种AcrossAllScreens的方式。
欢迎大家来我的新家看一看 3wwang个人博客-记录走过的技术之路
探索未知种族之osg类生物---器官初始化三的更多相关文章
- 探索未知种族之osg类生物---器官初始化一
我们把ViewerBase::frame()比作osg这类生物的肺,首先我们先来大概的看一下‘肺’长什么样子,有哪几部分组成.在这之前得对一些固定的零件进行说明,例如_done代表osg的viewer ...
- 探索未知种族之osg类生物---器官初始化四
上一节我们对完成了对osg生物内部非常重要器官graphicsContext的初始化工作.这样就可保证我们场景中至少有一个graphicContext存在,不至于刚出生就面临夭折.我们根据上一节中os ...
- 探索未知种族之osg类生物---器官初始化二
那我们回到ViewerBase::frame函数中来,继续看看为什么osg生命刚刚出生的时候会大哭,除了初始化了eventQuene和cameraManipulator之外还对那些器官进行了初始化.在 ...
- 《探索未知种族之osg类生物》目录
精力有限,博客园不在更新<探索未知种族之osg类生物>.在这里列出所有文章目录(持续更新)有兴趣的同学可以看看. 探索未知种族之osg类生物[目录] 前序 探索未知种族之osg类生物--- ...
- [转][osg]探索未知种族之osg类生物【目录】
作者:3wwang 原文链接:http://www.3wwang.cn/html/article_58.html 前序 探索未知种族之osg类生物---起源 ViewBase::frame函数中的Vi ...
- 探索未知种族之osg类生物---状态树与渲染树以及节点树之间的关系
节点树 首先我们来看一个场景构建的实例,并通过它来了解一下“状态节点”StateGraph 和“渲染叶”RenderLeaf 所构成的状态树,“渲染台”RenderStage 和“渲染元”Render ...
- 探索未知种族之osg类生物---起源
任何程序都是有生命的,是生命就需要呼吸.例如普通的windows程序,当运行完main()函数后,就需要进入消息循环,来监听用户的各种操作,以便做出及时的回应.这样的每次循环就像生命的每次呼吸,来维持 ...
- 探索未知种族之osg类生物---渲染遍历之器官协作
好了,现在我们经过三节的介绍我们已经大体上明确了单线程模型(SingleThreaded)下 OSG 渲染遍历的工作流程.事实上无论是场景的筛选render还是绘制cull工作,最后都要归结到场景视图 ...
- 探索未知种族之osg类生物---呼吸分解之事件循环一
事件循环和更新循环 终于到了我们嘴里经常念叨的事件循环.更新循环以及渲染循环了.首先我们来区分一下事件循环和渲染循环,他们两个首先是两个不同顺序执行的过程,我们有时候会用到任意node的updateC ...
随机推荐
- eclipse 访问GitHub 问题
- /src/log4j.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration S ...
- kafka 删除topic
两种方法: 一.修改配置文件server.properties 添加如下配置: delete.topic.enable=true 说明:官方给的文档说明“Enables delete topic. D ...
- java 基础-思维导图
思维导图的好处 最近看了一些文章的思维导图,发现思维导图真是个强大的工具.了解了思维导图的作用之后,觉得把它运用到java上应该是个不错的想法,这样回顾知识点的时候一目了然,快速知道自己的短板. 思维 ...
- camstar --调用自定义的CDO报帐号没有执行权限的错误
解决: 访问站点--〉modeling-->role-->Default Modeling-->筛选(如:modeling or Inquiry) 在右边找到自己定义的CDO(ser ...
- pinyin4j 中文转拼音
- ORACLE 如何产生一个随机数
1.select dbms_random.string('x', 3) from dual ; x是类型,3是长度. /* opt可取值如下: 'u','U' : 大写字母 'l','L' ...
- linux安装zookeeper及使用
一.安装条件 想要安装zookeeper,必须先在linux中安装好jdk.安装步骤见: https://www.cnblogs.com/expiator/p/9987351.html 二.下载并解压 ...
- YouTube Cobalt 浏览器支持
Cobalt介绍: Cobalt浏览器是YouTube公司定制的一款专用浏览器,Cobalt的使命,是在电视机端,使用灵活多变web形式实现流畅的交互操作,从而替代Android,与普通浏览器不同,C ...
- python爬虫相关基础概念
什么是爬虫 爬虫就是通过编写程序模拟浏览器上网,然后让其去互联网上抓取数据的过程. 哪些语言可以实现爬虫 1.php:可以实现爬虫.但是php在实现爬虫中支持多线程和多进程方面做得不好. 2.java ...