探索未知种族之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类生物--- ...
随机推荐
- php执行系统命令的四个函数shell_exec, exec, passthru, system分别的使用场景
shell_exec() 通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回.也就是说, PHP先运行一个shell环境, 然后让shell进程运行你的命令, 并且把所有输出已字符串形 ...
- c++11 关于typelist的foreach
建好一个typelist,其中都是类型信息而已,很重要的一个应用,循环迭代干些事情. 看了下boost的for_each实现,用我自己的typelist,大概代码如下: template<typ ...
- linux上静态库和动态库的编译和使用(附外部符号错误浅谈)
主要参考博客gcc创建和使用静态库和动态库 对于熟悉windows的同学,linux上的静态库.a相当于win的.lib,动态库.so相当于win的.dll. 首先简要地解释下这两种函数库的区别,参考 ...
- 数据恢复工具--extundelete的安装与使用
1.extundelete的恢复原理 extundelete恢复文件时并不依赖特定文件格式,首先extundelete会通过文件系统的inode信息,来获得当前文件系统下所有文件的信息,包括存在的和已 ...
- HTTP请求中 request payload 和 formData 区别?
原文地址: http://www.cnblogs.com/tugenhua0707/p/8975615.html FormData和Payload是浏览器传输给接口的两种格式,这两种方式浏览器是通过C ...
- centos7安装elasticsearch6.3.x集群并破解安装x-pack
一.环境信息及安装前准备 主机角色(内存不要小于1G): 软件及版本(百度网盘链接地址和密码:链接: https://pan.baidu.com/s/17bYc8MRw54GWCQCXR6pKjg 提 ...
- SQL Server事务
事务全部是关于原子性的.原子性的概念是指可以把一些事情当做一个单元来看待.从数据库的角度看,它是指应全部执行或全部都不执行的一条或多条语句的最小组合.为了理解事务的概念,需要能够定义非常明确的边界.事 ...
- 学习笔记:Stage.js(又叫Cut.js)——2D canvas 开发库,游戏方面的
http://piqnt.com/stage.js/ http://www.bootcdn.cn/stage.js/ Stage.js(可能又叫Cut.js)是一个2D HTML5 JavaScrip ...
- django 开发之前后端分离开发模式
1. 什么是前后端分离开发的概念: 前端页面运行前端服务器上,负责页面的渲染(静态文件的加载)与跳转 后端代码运行在后端服务器上, 负责数据的处理(提供数据请求的接口) 2. 前后端分离开发碰到的问题 ...
- Eurekalog
Eurekalog E:\Program Files (x86)\Neos Eureka S.r.l\EurekaLog 7\Packages\Studio25\EurekaLogComponent ...
