探索未知种族之osg类生物---呼吸分解之更新循环一
上节总结
前几天我们大体上介绍完成了osg的事件循环的介绍,总结一下osg的时间循环主要就是得到平台(windows)的所有消息,并遍历所有的node的eventCallback,并对他们进行处理。接下来我们就要进入osg的另一个维持生命的循环---更新循环。
更新循环
OSG 更新循环的作用与事件回调有类似之处:由专门的访问器对象_updateVisitor 的负 责场景图形更新遍历;所有的节点和 Drawable 几何体对象都可以使用 setUpdateCallback 设 置更新回调;通过具现 NodeCallback::operator()或者 Drawable::UpdateCallback::update 函数, 可以在回调对象中添加自定义的工作。
但是,更新回调与事件回调不同之处在于:事件循环是在当一个用户交互动作或系统事件产生时,每个节点(以及 Drawable 对象)的事件回调才会被调用一次;而节点(以及 Drawable 对象)的更新回调只会在每帧中被调用一次。这一区别决定了我们应当在什么时候使用事件回调, 以及在什么时候使用更新回调。
osgViewer::Viewer::updateTraversal()
那我们就开始进入osgViewer::Viewer::updateTraversal(),updateTraversal和eventTraversal一样首先都要定义目前处在的时间以及帧数,并进行记录,这样有利于进行统计分析。下面我们就要进入osgViewer::Viewer::updateTraversal()里最重要的函数osgViewer::Scene::updateSceneGraph()函数。
这个函数中我们先介绍一下它的主体功能,再去介绍这里遇到的一些新的概念。主要功能:
1、使用DatabasePager::updateSceneGraph函数更新场景的分页数据库,异步处理在分页数据库处理线程中。
2、ImagePager::updateSceneGraph函数, 更新场景的分页图像库,异步处理在分页数据库处理线程中。
3、设置图片请求的处理器。
我们先介绍一下DatabasePager和ImagePager
DatabasePager:分页数据库。在大型三维场景中采用数据分页的方式进行动态调度。这里“分页”的意思是随着视口范围的变化,场景只加载和渲染当前视口范围内数据,并将离开视口范围内的数据清除内存(可以设定不同的数据卸载策略),不再渲染。保证内存中只有有限的数据量,场景的每一帧也只有有限的数据被送到图形渲染管道,从而提高渲染性能。
ImagePager: 分页图像库。查看ImagePager 的相关内容了。这个类的工作 性质与 DatabasePager 没什么大的区别,它主要负责的是纹理图片文件的运行时加载工作。
DatabasePager和ImagePager都会用到独立的线程进行他们自己的工作。我们想要进入读懂他们代码的内容,首先我们得具备openThread的基本知识。
openThread的基本知识
面向对象的跨平台线程库 OpenThreads 原本是独立的开源工程,OSG 2.x 以后的版本将 其纳入了自己的体系结构当中,成为 OSG 基本库的一份子。 OpenThreads 库包含了以下几个主要的线程处理类: Thread 类:线程实现类。它是一个面向对象的线程实现接口,每定义一个 Thread 类, 就相当于定义了一个共享进程资源,但是可以独立调度的线程。通过重写 run()和 cancel()这 两个成员函数,即可实现线程运行时和取消时的操作;通过调用 start()和 cancel(),可以启 动或中止已经定义的进程对象。 Mutex 类:互斥体接口类。如同 pthread 等常用的线程库那样,OpenThreads 也提供了互 斥体操作的机制,它有效地避免了各个线程对同一资源的相互竞争,即,某一线程欲操作某 一共享资源时,首先使用互斥体成员的 lock()函数加锁,操作完成之后再使用 unlock 函数解锁。一个线程类中可以存在多个 Mutex 成员,用于在不同的地点或情形下为共享区域加锁; 但是一定要在适当的时候解锁,以免造成线程的共享数据无法再访问。 Condition 类:条件量接口类。它依赖于某个 Mutex 互斥体,互斥体加锁时阻塞所在的 线程,解锁或者超过时限则释放此线程,允许其继续运行。 这里涉及了几个线程操作中重要的概念:同步,阻塞以及条件变量。线程同步,简单来 说就是使同一进程的多个线程可以协调工作,例如让它们都在指定的执行点等待对方,直到 全员到期之后才开始同步运行;拥塞,即强制一个线程在某个执行点上等待,直到满足继续 运行的条件为止。例如其它的线程到达同一执行点,某个变量初始化完成等等,可以通过条 件变量来设计各种条件。 Block 类:阻塞器类。顾名思义,这个类的作用就是阻塞线程的执行,使用 block()阻塞 执行它的线程(注意,不一定是定义它的 Thread 线程,而是当前执行了 block 函数的线程, 包括系统主进程),并使用 release()释放之前被阻塞的线程。 下图所示的代码实现了一个简单的线程,并演示了 Block 类的使用方法。运行程序后 可以发现,Block::block()函数将首先阻塞主进程,被释放后再次阻塞的是 TestThread 线程, 这与它是谁的成员变量并无关系。BlockCount 类:计数阻塞器类。它与阻塞器类的使用方法基本相同:block()阻塞线程, release()释放线程;不过除此之外,BlockCount 的构造函数还可以设置一个阻塞计数值。计 数的作用是:每当阻塞器对象的 completed()函数被执行一次,计数器就减一,直至减到零 就释放被阻塞的线程。 Barrier 类:线程栅栏类。这是一个对于线程同步颇为重要的阻塞器接口,它的构造函 数与 BlockCount 类似,可以设置一个整数值,我们可以把这个值理解成栅栏的“强度”。每 个执行了 Barrier::block()函数的线程都将被阻塞;当被阻塞在栅栏处的线程达到指定的数目时,就好比栅栏无法支撑那么大的强度一样,栅栏将被冲开,所有的线程将被释放。重要的 是,这些线程是几乎同时释放的,也就保证了线程执行的同步性。 注意 BlockCount 与 Barrier 的区别,前者是由其它任意线程执行指定次数的 completed() 函数,即可释放被阻塞的线程;而后者则是必须阻塞指定个数的线程之后,所有的线程才会 同时被释放。 ScopedLock 模板:这个模板是与 Mutex 配合出现的,它的作用域之内将对共享资源进 行加锁,作用域之外则自动解锁。
原文链接 http://www.3wwang.cn/blog/article.ftl?id=22
探索未知种族之osg类生物---呼吸分解之更新循环一的更多相关文章
- 探索未知种族之osg类生物---呼吸分解之更新循环二
_scene->updateSceneGraph(*_updateVisitor); 我们用了前面4节才刚刚算是完成对DatabasePager::DatabaseThread::run()函数 ...
- 探索未知种族之osg类生物---呼吸分解之更新循环三
补充 当然细心的你会发现,_scene->updateSceneGraph(*_updateVisitor)中还有一个imagePager::UpdateSceneGraph()还没有进行讲解, ...
- 探索未知种族之osg类生物---呼吸分解之事件循环一
事件循环和更新循环 终于到了我们嘴里经常念叨的事件循环.更新循环以及渲染循环了.首先我们来区分一下事件循环和渲染循环,他们两个首先是两个不同顺序执行的过程,我们有时候会用到任意node的updateC ...
- 探索未知种族之osg类生物---呼吸分解之事件循环二
VPM矩阵 1.V 表示摄像机的观察矩阵(View Matrix),它的作用是把对象从世界坐标系变换到摄像机坐标系.因此,对于世界坐标系下的坐标值 worldCoord(x0, y0, z0),如果希 ...
- 探索未知种族之osg类生物---呼吸分解之事件循环三
那我们就开始处理这些事件中得到的所有的交互事件,首先我们要判断这些事件是否包含osg的退出事件,那什么情况下会触发这个退出事件呢?如果您运行过osg中example中的小例子的,聪明的你一定就会发现当 ...
- 探索未知种族之osg类生物---呼吸分解之渲染遍历二
那么今天我们就正式进入osg整个呼吸动作之中最复杂的一个动作,ViewerBase::renderingTraversals(),我们先介绍renderingTraversals的开头的简单的几步操作 ...
- 探索未知种族之osg类生物---呼吸分解之advance
回顾 我们用了两节的内容才堪堪讲解完ViewerBase::frame()函数中调用的realize()---Viewer:: realize()函数.我们简单的总结就是Viewer:: realiz ...
- 探索未知种族之osg类生物---呼吸分解之渲染遍历一
总结 前面我们基本上已经完成对ViewerBase::frame()函数的探究,只剩下renderingTraversals()渲染遍历的探究,虽然就剩下了一个函数,但是这却是最重要的,不可少的一个步 ...
- 《探索未知种族之osg类生物》目录
精力有限,博客园不在更新<探索未知种族之osg类生物>.在这里列出所有文章目录(持续更新)有兴趣的同学可以看看. 探索未知种族之osg类生物[目录] 前序 探索未知种族之osg类生物--- ...
随机推荐
- WINDOWS NT操作系统的注册表文件
WINDOWS NT操作系统的注册表文件 WINDOWS NT注册表文件分为系统文件和用户文件两类. 系统设置和缺少用户 配置数据存放在系统C:\Windows\System32\config文件夹下 ...
- git 更新远程分支列表
git remote update origin --prune git remote update origin -p
- uCOS-III等RTOS与IoT OS
一.IoT 以百度天工物联网为例,如下图所示: 通过联网设备,将设备连接至云端,并将每个设备的信息进行上传,并在云端进行设备的管理,设备数据的处理计算.存储,可视化的展示和分析.IoT设备较传统的嵌入 ...
- 读完这个我懂了JNDI
转载自:http://私塾在线/forum/blogPost/list/1186.html NDI 是什么 JNDI是 Java 命名与目录接口(Java Naming and Directory I ...
- docker stats监控容器资源消耗
在容器的使用过程中,如果能及时的掌握容器使用的系统资源,无论对开发还是运维工作都是非常有益的.幸运的是 docker 自己就提供了这样的命令:docker stats. 默认输出 docker sta ...
- Python发送微信消息
针对此 需要安装itchat第三方模块 采用pip安装就可以了 pip install itchat import itchatimport time#引入时间函数进行测试time_format= ...
- 关于想通过ros的dstnat实现公网IP nat 公网IP的情况
转发群里大神的“苏州-海豚在跳舞”的图 理论上客户机收到2.2.2.2过来的包应该直接丢弃.因为它并没有给2.2.2.2发过包.这里不知道如果在2.2.2.2上做 src-nat伪装成1.1.1.1回 ...
- 总结:Java 集合进阶精讲1
知识点:Java 集合框架图 总结:Java 集合进阶精讲1 总结:Java 集合进阶精讲2-ArrayList 集合进阶1---为集合指定初始容量 集合在Java编程中使用非常广泛,当容器的量变得非 ...
- 根据日志分析异常:There is already 'XXX' bean method
问题代码: @Slf4j @Api(value = "paymentOrderController", description = "PaymentOrderContro ...
- leetcode7. 整数反转
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1: 输入: 123 输出: 321 示例 2: 输入: -123 输出: -321 示例 3: 输入: 120 输出: ...
