探索未知种族之osg类生物---器官初始化四
上一节我们对完成了对osg生物内部非常重要器官graphicsContext的初始化工作。这样就可保证我们场景中至少有一个graphicContext存在,不至于刚出生就面临夭折。我们根据上一节中osg代码的研究也就知道了,在我们正常使用osg时,是怎么完成对camera以及graphicContext的创建的了。
回到Viewer::realize()中我们继续向下看,现在我们对osg::DisplaySettings以及osg::GraphicsContext::WindowingSystemInterface,有了新的认识,我在这里再补充一张camera,graphicContext以及windowingSystemInterface的关系图有利于大家进一步了解osg的内部组成。
回到Viewer::realize()中我们继续向下看,得到所有的GraphicsContext,遍历所有的GraphicsContext,然后判断是否设置了同步交换缓冲区(这一般是渲染的最后一步),这是osg提供的多机同步swapbuffer机制,他会默认调用内置的swapbuffer的回调函数(osg::SyncSwapBuffersCallback中,作用主要是等待client端的同步锁,实现多机同步执行swapbuffer)。如果developer想干预的话 可以调用 osg::GraphicsContext::setSwapCallback(SwapCallback* rc)来设置自定义的缓存交换回调。自定义的回调必须调用GraphicsContext::swapBuffersImplementation()函数.
再根据所依据的平台(windows,linux,mac等)默认制定的,或者用户后期修改的最大纹理池和最大对象缓冲池的大小,进一步对各个graphicsContext的相应属性值进行设置。然后正式完成对graphicsContext的初始化定义,下一步就是通过调用gc.realize()来使graphicsContext处于可用的状态。Osg::GraphicsContext::realize()函数的实现都是在它的继承类中通过realizeImplementation()函数完成的。
特别是windows平台的实现,使用windows+opengl的同学对这一段GraphicsWindowWin32::realizeImplementation()函数肯定非常了解,因为这里会涉及到很多windows平台特有的一些属性,就不做过多的介绍了,以后有机会我会再写一份opengl的入门教程,其中肯定会提到函数中涉及的东西。敬请期待。
当GraphicsContext可用了,就需要更新上下文gc->makeCurrent()。那我们就看看GraphicsContext::makeCurrent()完成了什么工作。
gc->makeCurrent()
GraphicsContext::makeCurrent()首先判断opengl与osg是否是同一个线程,(使用qt5+osg3.x的同学一定遇到过osg的threadmode只能设置singlethread。其他三种threadmode都会报一个同样的错误,错误的原因就是这里。至于怎么完美的结合qt5与osg3,请移步到我的github下 https://github.com/JimmieKJ/osgQTWidget 有具体的实现细节)。其实GraphicsContext::makeCurrent()的根本是通过调用子类的makeCurrentImplementation()实现。
当我们移步到bool GraphicsWindowWin32::makeCurrentImplementation()同样会发现,这里和使用opengl的程序有很大的相同之处,其实就是把dc和rc进行绑定。当makeCurrentImplementation返回true的时候,就代表graphicsContext更新成功。然后就是opengl的思路,需要解绑hc和rc防止资源浪费,这就需要调用gc->releaseContext(),其实就是调用子类的releaseContextImplementation()函数。
再次聚焦到realize函数上(/src/osgViewer/Viewer.cpp::realize()函数),_incrementalCompileOperation,用于预编译GraphicContext,主要作用是,想在程序运行开始时就加在一个资源文件但是又不想或者没有到显示到界面的时机,则会用到这个预加载操作。具体的用法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
//从Viewer获取 osgUtil::IncrementalCompileOperation的指针: osgUtil::IncrementalCompileOperation* pIcompOperation = viewer.getIncrementalCompileOperation(); //从Viewer获取 osgUtil::IncrementalCompileOperation的指针: // 创建compileSet: osg::ref_ptr compileSet = osgUtil::IncrementalCompileOperation::CompileSet(NODE, true ); //从CompileCompletedCallback派生新类,然后重写Completed函数,在内部隐藏节点: //将 派生类 绑定到 compileSet。 compileSet->compileSet->_compileCompletedCallback = newCompileCompletedCallback; //设置 IncrementalCompileOperation 过期策略 pIcompOperation->setCompileAllTillFrameNumber(50); 再往下就是使鼠标聚焦到osg的绘制窗口上这个一个功能。 // initialize the global timer to be relative to the current time. osg::Timer::instance()->setStartTick(); // pass on the start tick to all the associated event queues setStartTick(osg::Timer::instance()->getStartTick()); // configure threading. setUpThreading(); |
首先调用 osg::Timer::setStartTick 函数,启动 OSG 内部定时器并开始计时。
随后, Viewer::setStartTick 函数的工作是找到当前视景器和所有 GraphicsContext 设备的事件队列_eventQueue,并设定它们的启动时刻为当前时间。下一行是调用 ViewerBase::setUpThreading 函数(这个多线程问题我们以后再深入讨论)
请回到 realize 函数,现在这个函数的执行已经接近了尾声,不过我们又遇到了一个问题:编译上下文(也就是 Compile Contexts,)如果要启用它的话并不困难,只需要在调用 realize 之前执行:osg::DisplaySettings::instance()->setCompileContextsHint(true);随后,正如您在 realize 函数的 最后一个for循环看到的,系统将设法遍历所有可能的GraphicsContext 设备,针对它们分别再各自添加一个新的 GraphicsContext 设备(也就是说如果系统中已经有了数个图形上下文,那么现在又将新增同样数量的图形上下文与之对应),所用的函数为 GraphicsContext::getOrCreateCompileContext。
这之后,分别执行了创建图形线程,设置 CPU 依赖性,以及启动图形线程的工作,具体的实现内容可以暂时忽略。观察 getOrCreateCompileContext 函数的内容,很快我们就可以发现其中的重点:这些新增的 GraphicsContext 对象使用了 pBuffer 的特性,并与对应的已有对象共享同一个图形上下文(Traits::sharedContext 特性)。事实上,这是 OSG 利用 OpenGL 的像素缓存(Pixel Buffer)技术,为图形上下文的后台编译提供的一种新的解决方案。这样不仅可以提高图形刷新的速度,还可以方便用户为某一特定的 GraphicsContext 设备添加特殊的处理动作,方法是使用osg::GraphicsContext::getCompileContext 获取后台图形上下文,再使用 GraphicsContext::add函数向其中追加 osg::Operation 对象,类似的例子可以参看 osgterrain。
欢迎大家来我的新家看一看 3wwang个人博客-记录走过的技术之路
探索未知种族之osg类生物---器官初始化四的更多相关文章
- 探索未知种族之osg类生物---器官初始化一
我们把ViewerBase::frame()比作osg这类生物的肺,首先我们先来大概的看一下‘肺’长什么样子,有哪几部分组成.在这之前得对一些固定的零件进行说明,例如_done代表osg的viewer ...
- 探索未知种族之osg类生物---器官初始化三
当判断到viewer中没有一个graphicContext可用时,osg就会默认的进行一次对viewer的实现操作,这样可以保证osg以后可以安心的在屏幕上进行作画.那我们就来看看这个osgViewe ...
- 探索未知种族之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 ...
随机推荐
- 学习JS的心路历程-范围Scope和提升(Hoisting)
在上一篇提到了JS有三种声明变量的方式,分别是var.const及let,var和const let最大区别就是范围(scope)的限制.所以在这一篇我们会详谈何谓范围链及他们的复写优先级. 范围Sc ...
- web访问命令行
https://github.com/yudai/gotty go get github.com/yudai/gotty gotty -p 8000 -w kubectl exec -it mysql ...
- room 二分图最大匹配KM
#include<bits/stdc++.h> #define fi first #define se second #define INF 0x3f3f3f3f #define fio ...
- 1.2、CDH 搭建Hadoop在安装之前(CDH基于包的安装所需的权限)
CDH基于包的安装所需的权限 以下部分描述了使用Cloudera Manager进行基于软件包的CDH安装的用户权限要求.这些要求是安装和管理包和服务的标准UNIX系统要求. 所需特权 sudo由Cl ...
- dropload插件的使用(上拉下滑加载数据)
.导入 js dropload.min. js zepto.min.js <!-- jQuery1.7以上 或者 Zepto 二选一,不要同时都引用 --> $(function(){ ...
- JS导出网页数据到EXCEL
想得到的效果是,在网页上点击导出按钮,弹出文件保存框,输入文件名并选择路径后保存.可能是由于浏览器的安全机制,一直没能找到合适的解决方案,就采用了其它的一些替代方案. 思路是:后台一般处理程序查询数据 ...
- 【Scheme】cons的过程性实现
(define (cons x y) (define (dispatch m) (cond ((= m 0) x) ((= m 1) y))) dispatch) (define (car z) (z ...
- python计算两个数的百分比
a和b是整数,计算a/b的百分比 a=3 b=7 a=float(a) b=float(b) 保留百分比后2位小数 print "%.2f%%" % (a/b*100) '42. ...
- HDU-1074.DoingHomework(撞鸭dp二进制压缩版)
之前做过一道二进制压缩的题目,感觉也不是很难吧,但是由于见少识窄,这道题一看就知道是撞鸭dp,却总是无从下手....最后看了一眼博客,才顿悟,本次做这道题的作用知识让自己更多的认识二进制压缩,并无其它 ...
- 导入Unity插件时出现Failed to import package with error: Couldn't decompress package
导入Unity插件时出现Failed to import package with error: Couldn't decompress package 一开始以为压缩包本身有问题,坏了 后来发现在父 ...