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

探索未知种族之osg类生物---起源

阅读更多

qiyuan

任何程序都是有生命的,是生命就需要呼吸。例如普通的windows程序,当运行完main()函数后,就需要进入消息循环,来监听用户的各种操作,以便做出及时的回应。这样的每次循环就像生命的每次呼吸,来维持生命体征。

osg的程序不仅仅需要消息循环来监听用户的鼠标、键盘等操作,同时也得具备了渲染循环。当然随着我们的对osg的深入了解会发现,osg的事件监听和渲染循环是串行的。但是当我们把osg与MFC(QT)等结合时,相应UI上的鼠标,键盘事件的同时也要兼顾可能发生在osg中的效果,所以一般的osg程序起码需要两个并行的线程(例如osg与qt结合使用,为了保持足够灵敏的相应速度就需要把QTUI和osg渲染看成两种生命,分为两个线程)来维持它的正常运行。我们今天就是要解读osg程序赖以生存的每次呼吸。

首先我们得找到osg是用什么呼吸的,就想地球上的一般生物都是用鼻子呼吸,我们又大概得知道鼻子长在生物的那个位置。这样我们才可以开始我们的研究。当然我们肯定得有osg的源码,就像我们研究生物的呼吸先得有这种生物的身体。有了身体我们还得持续的观察一个有生命的生物,所以我们最先得到osg的可运行的程序就是example中的各种程序。其中大部分的程序main()函数的最后部分都是调用一下viewer.run()。

osgtext

所以我们可以有一个模糊的判断这一类的通过调用viewer类的run函数的程序,他的呼吸系统可能是通过run完成的。但是run()函数是一个单独的一行,按说他执行完毕以后程序就会结束了,所以我们有了新的判断osg的每一帧的调用的入口是在run()函数中的。这是osg程序存在的一种形式(或者叫独立运行模式)。Osg还有另一种存在形式,就是和各种UI混合使用,例如qt与osg结合使用,MFC与osg结合使用等等。我们可以从examples/osgviewerQt 的例子,可以根据上一个的思路,呼吸不是一次性的动作,是只要存活就会一直存在的。所以从osgviewerQt.cpp中根据以前的经验定位到timer (计时器),他每次timeout触发时调用的函数update()中一定包含了osg的每一帧的调用的入口。

osgviewer

根据上面两种osg的存活形式,可以进行进一步的确认,究竟哪里才是维持osg生命体征的位置。Viewer.run()函数(OSG Core/osgViewer/Viewer.cpp)最后会继续调用ViewerBase::run()函数(OSG Core/osgViewer/ViewerBase.cpp),

1
2
3
4
5
6
7
8
9
10
11
int Viewer::run()
{
    if (!getCameraManipulator() && getCamera()->getAllowEventFocus())
    {
        setCameraManipulator(new osgGA::TrackballManipulator());
    }
 
    setReleaseContextAtEndOfFrameHint(false);
 
    return ViewerBase::run();
}
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
38
39
40
41
int ViewerBase::run()
{
    if (!isRealized())
    {
        realize();
    }
 
    const char* run_frame_count_str = getenv("OSG_RUN_FRAME_COUNT");
    unsigned int runTillFrameNumber = run_frame_count_str==0 ? osg::UNINITIALIZED_FRAME_NUMBER : atoi(run_frame_count_str);
 
    while(!done() && (run_frame_count_str==0 || getViewerFrameStamp()->getFrameNumber()<runTillFrameNumber))
    {
        double minFrameTime = _runMaxFrameRate>0.0 ? 1.0/_runMaxFrameRate : 0.0;
        osg::Timer_t startFrameTick = osg::Timer::instance()->tick();
        if (_runFrameScheme==ON_DEMAND)
        {
            if (checkNeedToDoFrame())
            {
                frame();
            }
            else
            {
                // we don't need to render a frame but we don't want to spin the run loop so make sure the minimum
                // loop time is 1/100th of second, if not otherwise set, so enabling the frame microSleep below to
                // avoid consume excessive CPU resources.
                if (minFrameTime==0.0) minFrameTime=0.01;
            }
        }
        else
        {
            frame();
        }
 
        // work out if we need to force a sleep to hold back the frame rate
        osg::Timer_t endFrameTick = osg::Timer::instance()->tick();
        double frameTime = osg::Timer::instance()->delta_s(startFrameTick, endFrameTick);
        if (frameTime < minFrameTime) OpenThreads::Thread::microSleep(static_cast(1000000.0*(minFrameTime-frameTime)));
    }
 
    return 0;
}

我们在ViewerBase::run()中继续耐心的寻找就会发现有一个特殊的函数frame(),为什么特殊呢?因为frame的英文的意思就是’帧’,而我们学渲染都知道’帧’代表屏幕上一幅画,这和osg库的本质就联系在了一起。Osg就是一个库,一个在计算机屏幕上作画的库。所以ViewerBase::frame()就是我们要找的osg中会呼吸的地方。同样我们在examples/osgviewerQt中也会发现,timer每到设定事件就会调用update()函数,而qt的update()函数在内部就会调用paintEvent()函数,我们在osgviewerQt.cpp的paintEvent()函数中也会发现osg::CompositeViewer的update函数,而osg::CompositeViewer继承自ViewerBase,所以最后也会定位到ViewerBase::frame()。这样我们就可以确定osg这类生物的呼吸的入口是ViewerBase::frame()函数。终于我们打开了通往新世界的大门,下一步就是经历轮回,看看osg这类生物是怎么生存的。

欢迎大家来我的新家看一看 3wwang个人博客-记录走过的技术之路

0
0
分享到:
评论

相关推荐

    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同心球

    1. 类定义:定义一个名为`TongXinQiu`的类,可能继承自osg的基类,如`osg::Node`,以便集成到场景图中。 2. 数据成员:存储同心球的属性,如球体数量、半径、中心坐标等。 3. 构造函数:初始化同心球的参数。 4. ...

    编译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 ...

    osg2cesiumApp-V1.10.zip

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

    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-...

    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...

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

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

    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位的开发库,最近正好有个项目需要...

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

    "OSG转osgb-obj-ive格式工具.rar"是一个专门用于3D模型格式转换的实用程序,主要服务于倾斜摄影模型的处理工作。这个压缩包包含了能够将osg、osgb、ive和obj等格式互相转换的软件工具,这极大地提升了在不同平台和...

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

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

    OSG-Dragger-Dragger.zip_osg_osg dragger

    本知识点将深入探讨`osg::Dragger`类及其子类,特别是关于`PointInfo`的概念。 首先,`osg::Dragger`是osg库中的一个类,用于实现3D空间中的拖拽行为。它为用户提供了一种直观的方式来操纵场景中的对象,如旋转、平...

    osg3.4-2015-x64.7z

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

    osgearth-osgearth-3.0.rar

    《osgearth:构建3D地理可视化应用的开源框架》 osgEarth是一个基于OpenSceneGraph(osg)的开源库,用于创建交互式的3D地球应用程序。它提供了丰富的功能,包括地形渲染、遥感图像处理、GPS数据集成以及各种地理...

    osg-wpf-master.zip

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

    osg-water-reflect.rar_osg_osg ocean_osg reflect_water_water in o

    【标题】"osg-water-reflect.rar" 是一个基于OpenSceneGraph (osg) 开发的程序,专注于实现水面的反射效果。"osg ocean" 暗示这个程序可能包含对海洋或者大面积水域的模拟,而 "osg reflect" 则强调了其中的反射功能...

    osgearth-osgearth-2.3.zip

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

Global site tag (gtag.js) - Google Analytics