探索未知种族之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 ...
随机推荐
- WinForm textbox 全选
原地址:忘了 textBox1.KeyPress += anyTextBox_KeyPress; private void anyTextBox_KeyPress(object sender, Sys ...
- 给RabbitMQ发送消息时,设置请求头Header。
消费者的请求头 生产者设置请求头 由于消费者那里,@Payload是接受的消息体,使用了@Header注解,需要请求头,生产者这边就要设置请求头,然后rabbitTemplate再调用convertA ...
- spring-boot-starter-data-elasticsearch 整合elasticsearch 5.x详解
1.使用原因 近期公司在开发新的项目用到了elasticsearch ,因为项目框架用的spring Cloud所以依赖全用的是starter,从网上找的信息比较旧,并没有整合elasticsearc ...
- GO注释
1.GO资源简介 由于生物系统的惊人复杂性和需要分析的数据集的不断增加,生物医学研究越来越依赖于以可计算的形式存储的知识.基因本体论(GO)项目为基因功能和基因产物的可计算知识提供了目前最全面的资源. ...
- ORACLE 把不是SYS用户下的所有JOB删除掉
BEGIN FOR job_id in(select job,log_user,priv_user,schema_user from dba_jobs) LOOP IF(job_id.lo ...
- oracle 中更新update不成功的原因
oracle 中执行insert into 与delete 都正常,但是执行update 却没有反应. 原因: 是因为记录锁.这种只有update无法执行其他语句可以执行的其实是因为记录锁导致的,在o ...
- chattr 和 lsattr 命令介绍---案例:修改passwd文件
chattr命令的作用很大,其中一些功能是由Linux内核版本来支持的,如果Linux内核版本低于2.2,那么许多 功能不能实现.同样-D检查压缩文件中的错误的功能,需要2.5.19以上内核才能支持. ...
- jggrid应用,后台c#
参考网址: 1.https://www.cnblogs.com/miro/p/jqGrid.html 2.https://blog.csdn.net/ainuser/article/details/6 ...
- stm32GPIO的8种工作模式
推挽输出:可以输出高.低电平,连接数字器件:推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止.高低电平由IC的电源决定. 推挽电路是两个参数相同的三极管或MOS ...
- vue 使用a+ router.push的形式跳转时,地址栏不显示参数
解决办法: a链接不要写href 属性