`
u014177758
  • 浏览: 6933 次
社区版块
存档分类
最新评论

探索未知种族之osg类生物---呼吸分解之更新循环二

    博客分类:
  • osg
阅读更多

updateSceneGraph

_scene->updateSceneGraph(*_updateVisitor);

我们用了前面4节才刚刚算是完成对DatabasePager::DatabaseThread::run()函数的探究,也就是了解了osg究竟是怎么完成对数据的加载的。那么我们现在要回到DatabasePager::updateSceneGraph的工作中,它是在osgViewer::Viewer:: updateTraversal()函数中遇到的

_scene->updateSceneGraph(*_updateVisitor);中被调用的。

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
34
35
36
37
void DatabasePager::updateSceneGraph(const osg::FrameStamp& frameStamp)
{
 
#define UPDATE_TIMING 0
#if UPDATE_TIMING
    osg::ElapsedTime timer;
    double timeFor_removeExpiredSubgraphs, timeFor_addLoadedDataToSceneGraph;
#endif
 
    {
        <span style="color: #ff6600;">removeExpiredSubgraphs(frameStamp);</span>
 
#if UPDATE_TIMING
        timeFor_removeExpiredSubgraphs = timer.elapsedTime_m();
#endif
 
        <span style="color: #ff6600;">addLoadedDataToSceneGraph(frameStamp);</span>
 
#if UPDATE_TIMING
        timeFor_addLoadedDataToSceneGraph = timer.elapsedTime_m() - timeFor_removeExpiredSubgraphs;
#endif
 
    }
 
#if UPDATE_TIMING
    double elapsedTime = timer.elapsedTime_m();
    if (elapsedTime>0.4)
    {
        OSG_NOTICE<<"DatabasePager::updateSceneGraph() total time = "<<elapsedTime<<"ms"<<std::endl;
        OSG_NOTICE<<"   timeFor_removeExpiredSubgraphs    = "<<timeFor_removeExpiredSubgraphs<<"ms"<<std::endl;
        OSG_NOTICE<<"   timeFor_addLoadedDataToSceneGraph = "<<timeFor_addLoadedDataToSceneGraph<<"ms"<<std::endl;
        OSG_NOTICE<<"   _activePagedLODList.size()        = "<size()<<std::endl;
        OSG_NOTICE<<"   _inactivePagedLODList.size()      = "<size()<<std::endl;
        OSG_NOTICE<<"   total                             = "<size() + _inactivePagedLODList->size()<<std::endl;
    }
#endif
}
      • DatabasePager::removeExpiredSubgraphs()函数的主要作用是通过目前正在使用的PagedLOD节点移除到指定定时间时间以来未访问过(过期的)的子节点。 注意,这段操作应该只从更新循环中调用。探究这个DatabasePager::removeExpiredSubgraphs()函数的内容,发现函数的开头还是对这个删除过程的记录,最后保存到osg的log中。遇到第一个if语句就是跳过第一帧,因为这个时候没有任何过期的数据。记录一下当前_ activePagedLODList的大小numPagedLODs,当numPagedLODs没有达到最大lod数(_targetMaximumNumberOfPageLOD)就不用进行清理工作。我们要记录超过的我们约定的最大的_targetMaximumNumberOfPageLOD,的数量,这样我们就知道删除多少过期的lodpage数量(numToPrune),然后我们就是_activePagedLODList->removeExpiredChildren()来便利现在所有的pagelod,从存在时间最长的也就是_activePagedLODList最先加入的成员开始,删除子节点,直到numToPrune为0为止。这样我们就完成了对过期的pageLod的删除工作。
      • DatabasePager::addLoadedDataToSceneGraph: 向场景图中添加新的数据。还记得我们在DatabasePager::run函数中介绍到_dataToMergeList吗?这个时候就要排上用场了。函数的开头依然是要对下面的添加数据的操作进行记录。把dataToMergeList中的数据转移到localFileLoadedList中,遍历localFileLoadedList首先取得“待合并列表”_dataToMergeList,并遍历其中每一个 DatabaseRequest 对象。遍历过程中,首先执行 SharedStateManager::share 函数,将新加载节点_loadedModel 的渲染属性保存到 SharedStateManager 管理器中。然后用来判断node是否为osg::PagedLOD或者osg::ProxyNode,也就是说DatabasePager只会在指定为osg::PagedLOD或者osg::ProxyNode才会启用。然后就是得到DatabaseRequest对象使用getDatabaseRequest(plod->getNumChildren())或者是 proxyNode->getDatabaseRequest(proxyNode->getNumChildren())函数,随后执行 DatabasePager::registerPagedLODs,在加载的节点及其子树中搜索 PagedLOD节点,并添加到刚刚提到的_pagedLODList 列表中。

根据上面我们提到的,DatabasePager只有在使用 osg::PagedLOD 和 osg::ProxyNode 节点的时候才会有用。所以我们需要了解一下osg::PagedLOD和 osg::ProxyNode。

osg::PagedLOD我们先看一下类结构

pagedlod

Osg::Lod(level of detail)的意思就是按照用户的可视范围,将多个子节点作为同一场景的多个细节层次。这样可以在视点靠近物体时呈现较多的物体细节,而在远离时则仅仅呈现一个简化的模型,从而降低了运算和绘制的负担。但是osg::Lod节点可以其内部包含的子节点内容很多,这个时候无论加载哪一个层级都会消耗大量的计算机资源,为了解决这个问题,osg提出了pageLod这么一个类,目的就是运用了分页数据库的功能,将多个模型数据分批加载到场景图形中(作为 PagedLOD 的子节点);并根据用户当前的可视范围,将那些一段时间内均无法被看到的 PagedLOD 子节点剔除出场景图形,以节约系统资源;当然,如果用户移动了视点之后,被剔除的节点又重新进入视野,那么 OSG 的分页数据库线程将重新加载它。

Osg::ProxyNode我们还是先看看他的继承情况,再功能分析

proxynode

ProxyNode就是代理节点的意思,也就是他可以看作一个node的另一个名称,这样我们在特定的时候加载模型时,就不需要进行查找工作,直接对ProxyNode进行操作就可以了。例如:当我们希望在场景仿真循环开始之后才加载某个模型文件时,可以使用ProxyNode 节点来指定要加载的文件名,并在场景筛选(Cull)的过程中加载模型,加载后的新节点将作为 ProxyNode 节点的子节点:

1
2
3
osg::ProxyNode* proxyNode = new osg:: ProxyNode;
 
proxyNode->setFileName(0, “nodefile.osg”);

 

这里 setFileName 的两个参数分别是新载入的子节点在 ProxyNode 下的位置,以及对应模型文件的名称。我们还可以使用 ProxyNode::setLoadingExternalReferenceMode 来设置加载的时机,例如首先设置为不自动加载(NO_AUTOMATIC_LOADING),在适当的时候再设置为立即加载(LOAD_IMMEDIATELY)。

这样我们就大概讲述完成了DataPager的使用时机,以及完成了对_scene->updateSceneGraph(*_updateVisitor);函数的主要功能的讲解。

原文链接  

http://www.3wwang.cn/blog/article.ftl?id=30

分享到:
评论

相关推荐

    osg3.6.4-osgEarth2.10.2-x86-x64-VS2019开发库

    截止到2020/03/10最新版本的osg和osgEarth开发库,osg版本为3.6.4,osgEarth版本为2.10.2,之前编译了VS2017版本的开发库,有网友反映需要32位的开发库,当时确实没时间专门编译32位的开发库,最近正好有个项目需要...

    osg3.4-osgearth2.8-2015-x64.7z

    标题 "osg3.4-osgearth2.8-2015-x64.7z" 暗示了这是一个针对64位Windows系统(x64)的软件包,包含了OpenSceneGraph(osg)3.4版本和osgEarth 2.8版本的相关组件。OpenSceneGraph是一个开源的3D图形库,而osgEarth则...

    osg-windows-binaries-master.zip

    【osg-windows-binaries-master.zip】是一个包含osg285版本的OpenSceneGraph(简称OSG)库的压缩包,特别针对Windows平台进行了优化。OpenSceneGraph是一个开源的高性能图形库,广泛用于3D图形应用程序开发,如游戏...

    osg-data-master.zip

    【osg-data-master.zip】是一个包含osgEarth相关数据的压缩包,这个名字暗示了它与开源图形库OpenSceneGraph(OSG)的扩展模块osgEarth有关。OpenSceneGraph是一个强大的3D图形编程库,主要用C++编写,广泛应用于...

    osg同心球-osg同心球-osg同心球

    【osg同心球】是OpenSceneGraph(简称osg)库中的一个特定概念,它涉及3D图形编程和场景图管理。OpenSceneGraph是一个开源的高性能3D图形库,用于创建交互式实时应用程序。在这个上下文中,"同心球"可能指的是一个...

    OSGEARTH210-OSG3.6.5.zip(OSGEarth2.10二进制预编译包)

    1、OSGEarth2.10源码预编译好的二进制开发包(64位) 2、基于OSG3.6.5版本 3、基于Visual Studio2019编译的64位版本

    gwaldron-osgearth-osgearth-2.8-0-g449e80a

    《gwaldron-osgearth-osgearth-2.8-0-g449e80a:探索OSGEarth的2.8.0版本》 在IT领域,尤其是在三维地理信息系统(GIS)的世界中,osgEarth是一个备受瞩目的开源项目。这个名为“gwaldron-osgearth-osgearth-2.8-0-...

    osg2cesiumApp-V1.10.zip

    《OSG2CesiumApp-V1.10:将倾斜摄影osgb数据转换为3DTiles的实用工具》 在现代地理信息系统(GIS)和虚拟现实应用中,3DTiles是一种广泛采用的数据格式,它允许高效地在Web浏览器中加载和展示大规模三维地形和建筑...

    编译osgearth-osgearth-2.5所需要的依赖包

    编译osgearth-osgearth-2.5所需要的依赖包 包括以下资源: 3rdParty_VC10_x86_x64.zip curl-7.25.0.zip expat-win32bin-2.0.1.rar gdal181.zip geos-3.2.3.tar.bz2 libzip(vs10).rar OpenSceneGraph-3.0.1.zip ...

    OSGEarth-2.10.2.rar

    osgEarth是基于三维引擎osg开发的三维数字地球引擎库,在osg基础上实现了瓦片调度插件,可选的四叉树调度插件,更多的地理数据加载插件(包括GDAL,ogr,WMS,TMS,VPB,filesystem等),再结合一套地理投影转换插件...

    gwaldron-osgearth-osgearth-2.7-0-g25ce0e1.zip

    描述中的“gwaldron-osgearth-osgearth-2.7”是对标题的简洁重申,进一步强调了这是osgEarth的2.7版本,可能由开发者gwaldron维护或贡献。 【osgEarth知识详解】 osgEarth是一个强大的C++库,它利用OpenSceneGraph...

    osg3.6.4-osgEarth2.10.2-x86-x64-VS2019-VS2017-VS2015.zip

    截止到2020/03/10最新版本的osg和osgEarth开发库,osg版本为3.6.4,osgEarth版本为2.10.2,之前编译了VS2017版本的开发库,有网友反映需要32位的开发库,当时确实没时间专门编译32位的开发库,最近正好有个项目需要...

    VS2019-OSG3.6.5-OsgEarth3.0.4-Debug-Release-X64

    在网上看了很多个版本的编译库,感觉不是很符合需求,有些库太老,有些依赖库版本不一致,我特意根据osg3.6.5和gdal3.0.4编译了VS2019版本的osgearth3.1,O基于GL2版本,适用性较强,亲测可用,无异常,同时提交了...

    osgearth-osgearth-3.0.rar

    在“osgearth-osgearth-3.0.rar”这个压缩包中,包含了osgEarth的源码工程和相关库,这对于开发者来说是一份宝贵的资源,可以深入理解其工作原理并进行二次开发。 一、OpenSceneGraph(osg)基础 OpenSceneGraph...

    OSG转osgb-obj-ive格式工具.rar

    2. **osgb**:这是OSG的二进制版本,相比osg格式,osgb文件更小,加载速度更快,但不那么直观,因为它们不是人类可读的文本格式。osgb通常用于在内存有限或者性能要求高的环境中使用。 3. **obj**:Wavefront OBJ是...

    osg3.4-2015-x64.7z

    《osg3.4.0在Windows x64平台上的应用详解》 osg3.4-2015-x64.7z这个压缩包文件,是针对OpenSceneGraph(简称osg)3.4.0版本的Windows x64平台编译优化后的库文件集合。OpenSceneGraph是一个开源的3D图形库,它提供...

    OSG-Dragger-Dragger.zip_osg_osg dragger

    在`OSG-Dragger-Dragger.pdf`文档中,读者可以期待找到更多关于`osg::Dragger`类的详细信息,包括如何创建和使用自定义的Dragger,以及如何结合`PointInfo`进行更复杂的交互设计。这份资料将帮助开发者深入理解如何...

    osg-wpf-master.zip

    【osg三维图形库】 osg(OpenSceneGraph)是一个开源的高性能3D图形库,它基于OpenGL,用于构建复杂的实时3D应用。osg的核心是场景图模型,它允许开发者以树形结构组织3D对象和图形状态,使得渲染、动画和交互操作...

    osgearth-osgearth-2.3.zip

    OSGEARTH是一个开源的地球可视化库,它基于OpenSceneGraph(OSG)构建,用于创建交互式的3D地球应用程序。OSGEarth 2.3版本是这个项目的其中一个稳定发行版,提供了许多增强的功能和改进。在了解这个压缩包的内容...

    osg-water-reflect.rar_osg_osg ocean_osg reflect_water_water in o

    【压缩包子文件】包括 "osg-实现真实反射水面",这可能是一个包含了源代码、文档或预编译二进制的文件,展示了如何在osg中实现反射水面的技术细节。"data" 文件夹可能包含了纹理、模型或其他数据,用于测试或演示...

Global site tag (gtag.js) - Google Analytics