简介

DatabasePager类,也就是常说的数据库分页技术,简单来说,就是在进行数据库查找时,有可能满足条件的数据很多,为了提高相应速度我们进行数据查找时进行分页查找与显示,当点击下一页时才会进行下一次的查找动作。Osg就是把这个原理应用在了三维大场景中,当我们需要加载一个城市级数据时,因为数据量非常大,而我们感兴趣的范围在某一时刻一般都是很小的一部分,所以我们也可以应用数据分页的技术,对大数据进行”分页”查找并显示。

在osg中DatabasePager执行的动作只有一步,就是在每一帧的更新循环中使用updateSceneGraph函数,把过期的数据卸载掉。并将新加入的数据载入到当前scene中。这些数据都是在用户视野中显示的。所以我们就把用户的视野比作”页面”。我们都知道数据的加载都是非常耗时的操作,更何况是三维模型这种大体量的数据,所以osg把DatabasePager的操作放到了另一个独立于渲染线程之外的线程上进行。

那我们就进入osgDB::DatabasePager中查看这个特殊的线程都进行了什么工作。

osgDB::DatabasePager成员介绍

DatabasePager::DatabaseThread::run()。我们在上面一节中介绍过openThread的用法。在进入DatabaseThread::run()之前我们先对DatabasePager中的一些成员变量进行简单的介绍:

1、DatabasePager::DatabaseThread 类:这是分页数据库的核心处理线程,它负责实现场景元素的定期清理,加载以及合并工作;但是让它一直处于检查各个数据列表的循环状态,这未免太过耗费系统资源。因此,这个线程在平常状态下应当被阻塞,需要时再予以唤醒。

2、DatabasePager::DatabaseRequest 结构体:这个结构体保存了用户的单个数据请求,包括数据文件名,请求时间,数据加载后存入的节点,以及要进行合并的父节点等;除此之外还有一个重要的编译映射表_dataToCompileMap,这个映射表负责保存图形设备 ID 与编译对象(几何体显示列表,纹理等)的映射关系。

3、DatabasePager::RequestQueue 结构体:它负责保存和管理一个“数据请求列表”_requestList,也就是由 DatabaseRequest 对象组成的向量组,除此之外还负责对列表中的数据按请求时间排序。上图中所示的_dataToCompileList 和_dataToMergeList 实际上都是RequestQueue 类型的对象,不过它们所保存的“请求列表”事实上是已经完成加载的“待编译/待合并列表”了。

4、DatabasePager::ReadQueue 结构体:这个结构体继承自 RequestQueue,不过还增加了一个“弃用对象列表”_childrenToDeleteList,也就是 osg::Object 对象组成的向量组。它是数据处理线程中最重要的对象之一,除了可以随时向两个列表里追加数据请求和弃用对象之外,这个结构体还包括了一个 updateBlock 函数,负责阻塞或者放行 DatabaseThread 线程,其根据是:列表中是否存在新的数据请求或弃用对象需要处理,以及用户是否通过函数设置暂时不要启用线程(DatabasePager ::setDatabasePagerThreadPause)。

DatabasePager::DatabaseThread::run()

好,那我们就可以进入DatabasePager::DatabaseThread::run()内部进行解剖了。首先osg会对读取数据的模式按照本地数据和网络数据进行划分。划分的目的是osg会根据不同类型创建不同的线程进行处理,并且网络数据还可以设置缓存路径(OSG_FILE_CACHE)缓存到本地。

然后会对线程安全的队列read_queue上锁,以便在判断过期的数据(childrenToDeleteList)进行清空操作。随后,使用 DatabasePager::ReadQueue::takeFirst 函数,从当前线程对应的 ReadQueue 对象(_fileRequestQueue 或_httpRequestQueue)的队列中取出并清除第一个数据加载请求(DatabaseRequest)。并且在DatabasePager::RequestQueue::takeFirst函数中遍历所有的请求列表(_requestList)判断要加载的数据是否过期,得到最上层的要加载的数据。

再往下看,当databaseRequest->_loadOptions是url数据时并且指定了OSG_FILE_CACHE的路径,那么osg就需要进行缓存工作,然后把databaseRequest 保存到将要合并的列表中(_pager->_dataToMergeList->addNoLock(databaseRequest.get());),再剩下的步骤就是对数据进行编译以及合并到scene中。

原文链接 http://www.3wwang.cn/blog/article.ftl?id=26

osg探究补充:DatabasePager类简介的更多相关文章

  1. osg探究补充:osg数据加载原理(插件机制简介)

    前言 我们接着昨天的继续,昨天主要是讲解了DatabasePager类中的特定的成员变量以及run函数的第一部分,对所要请求加载的数据按照是否是网络数据进行分类加载模式.今天我们就看看数据是怎们加载到 ...

  2. osg探究补充:Node::accept(NodeVisitor& nv)及NodeVisitor简介

    前言 在前几节中,我自己觉得讲的比较粗糙,因为实在是时间上不是很充足,今天我想弥补一下,希望不是亡羊补牢.我们在osgViewer::Viewer::eventTraversal()函数中经常看到这么 ...

  3. OSG中的示例程序简介

    OSG中的示例程序简介 转自:http://www.cnblogs.com/indif/archive/2011/05/13/2045136.html 1.example_osganimate一)演示 ...

  4. OSG中的示例程序简介(转)

    OSG中的示例程序简介 1.example_osganimate一)演示了路径动画的使用 (AnimationPath.AnimationPathCallback),路径动画回调可以作用在Camera ...

  5. ImageView类简介

    4.8  图片控件 本节将要介绍的是图片控件ImageView,首先对ImageView类进行简单介绍,然后通过一个案例来说明ImageView的用法. 4.8.1  ImageView类简介 Ima ...

  6. Spring Security——核心类简介——获得登录用户的相关信息

    核心类简介 目录 1.1     Authentication 1.2     SecurityContextHolder 1.3     AuthenticationManager和Authenti ...

  7. DriverManager 驱动管理器类简介 JDBC简介(三)

    驱动程序管理器是负责管理驱动程序的,驱动注册以后,会保存在DriverManager中的已注册列表中 后续的处理就可以对这个列表进行操作 简言之,驱动管理器,就是字面含义,主要负责就是管理 驱动 概述 ...

  8. Java基础-日期格式化DateFormat类简介

    Java基础-日期格式化DateFormat类简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.DateFormat类概述 DateFormat 是日期/时间格式化子类的抽象 ...

  9. Java基础-StringBuffer类与StringBuilder类简介

    Java基础-StringBuffer类与StringBuilder类简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.StringBuffer类 在学习过String类之后 ...

随机推荐

  1. LiveBindings如何绑定一个对象(转)

    原文 http://www.malcolmgroves.com/blog/?p=1084 一.新建VCL工程加入TAdapterBingSource控件 二.定一个TPerson类 MyPerson ...

  2. Windows不要使用记事本编辑文本文件

    摘自:廖雪峰 千万不要使用Windows自带的记事本编辑任何文本文件.原因是Microsoft开发记事本的团队使用了一个非常弱智的行为来保存UTF-8编码的文件,他们自作聪明地在每个文件开头添加了0x ...

  3. linux6下源码安装mysql5.6

    概述:CentOS 6.4下通过yum安装的MySQL是5.1版的,比较老,所以就想通过源代码安装高版本的5.6.14.正文:一:卸载旧版本使用下面的命令检查是否安装有MySQL Serverrpm ...

  4. 刘志梅201771010115.《面向对象程序设计(java)》第四周学习总结

    实验四 类与对象的定义及使用 实验时间 2018-9-20 1.实验目的 (1)预定义类:(不是所有类都具有面向对象特征) 构造器的类名和方法名相同,是一种特殊的方法,用来构造并初始化对象. (2)用 ...

  5. cenos 7.2 网卡设置静态ip

    1.vi /etc/sysconfig/network-scripts/ifcfg-ens32 (网卡名称可能不一样)vi 编辑 TYPE="Ethernet" BOOTPROTO ...

  6. Vue非父子组件之间的传值

    1.新建一个js文件  然后引入vue 实例化vue 最后暴露这个实例:实例化Vue对象的时候名称要小写,大写控制台报错,我也不知道什么原因: 2.在要广播的地方引入刚才定义的实例: 3通过VueEm ...

  7. tkinter 写一个简易的ide

    简易IDE 基于tkinter的简易ide,参考文档和Baidu的资料制作的,过程中遇到了很多问题,也学到了很多知识. 功能: 1.菜单栏 2.编辑功能 open save... 3.快捷键  ctr ...

  8. 在HTML中显示base64 img 图片

    base64的图片可以直接显示在网页上面 <img src=“data:image/png;base64,******************************************** ...

  9. CSS样式学习-3、轮廓、伪类/元素、display-flex布局

    一.轮廓 outline绘制于元素周围的一条线,位于边框边缘外围. 属性规定元素轮廓的样式.颜色.宽度. outline-width轮廓宽度,属性:thin细轮廓.medium中等(默认值).thic ...

  10. Linux网络编程学习(二) ----- 进程控制(第三章)

    1.进程和程序 程序是一个可执行文件,而一个进程是一个执行中的程序实例.一个进程对应于一个程序的执行,进程是动态的,程序是静态的,多个进程可以并发执行同一个程序.比如几个用户可以同时运行一个编辑程序, ...