简介:面向基于Qt的OsgEarth三维数字地球开发者,这份代码把OSG 3.4与OsgEarth 2.8成功集成到Qt Creator 5.12与MSVC2017环境中,构成一套可直接运行的完整工程。工程内部已经封装好主窗口与渲染交互逻辑,无需额外组装即可编译启动,适合作为三维地球应用的基础框架。资源共113个文件,压缩包约65MB,其中44个DLL解决运行库依赖,42个qm为Qt界面翻译文件,4个cpp与4个h文件保留核心源码,3个exe是可执行程序;同时配套obj、pdb、pro、ui、Makefile与debug/release等工程文件,便于二次开发、排错和配置调整,MOC生成文件也一并保留,方便理解Qt信号槽机制与OsgEarth渲染线程的配合。作者在2060显卡上实测帧率超过150,能够支撑流畅的交互浏览,大幅降低OsgEarth与Qt混编时的环境搭建门槛。已有1168人学习下载,适合需要快速构建高帧率数字地球原型的中高级Qt与OSG开发者。 刚把一套 osgEarth 工程从别的机器迁移到 Qt Creator 里,环境是 Qt 5.12、编译器选的 MSVC2017、OSG 3.4 + osgEarth 2.8,折腾了大概一个周末,把该踩的坑基本都踩了一遍。今天把这套环境的搭建过程、工程配置思路、还有那些“文档里不写但你必须知道”的细节整理出来,给正好想用 Qt + OSG + osgEarth 做三维GIS或仿真开发的朋友做个参考。
先说你拿到这套组合最关心的几个问题:这套东西能不能跑?配置起来有多麻烦?为什么网上有人用 MinGW 也能编译,有人却坚持用 MSVC?以及那个最常见的 "no qt platform plugin could be initialized" 报错到底怎么根治。这篇博文就是从零开始、用 MSVC2017 编译器把 osgEarth 工程跑起来的完整记录,步骤和坑都写清楚了。
1. 版本选型与整体设计思路
1.1 为什么是 Qt 5.12 + MSVC2017 + OSG 3.4 + osgEarth 2.8
这套组合看起来像是“老古董”,但在工业项目和科研场景里非常常见。我先说结论:Qt 5.12 是 Qt 5 系列里稳定性口碑最好的一代,MSVC2017 对应的是 Visual Studio 2017 的运行时,OSG 3.4 是 OpenSceneGraph 的经典稳定分支,而 osgEarth 2.8 是跟 OSG 3.4 搭配最顺的版本。这四者的组合不是随便拼的,而是经过社区大量项目验证过的“黄金搭配”。
很多人上来就问“能不能用 Qt 6 + OSG 3.6 + osgEarth 3.x”,技术上当然可以,但你要面对的是编译链脱节、第三方依赖库找不到匹配版本、插件加载方式变了等一系列问题。在项目交付场景下,稳定压倒一切,所以这套老组合至今仍有大量存量项目和商业产品在用。如果你手头有现成的数据、插件、模型资源,也是基于这套组合生成的,那就不用犹豫,直接用这个版本搭配。
还有一点值得注意:编译器必须统一。Qt 库、OSG 库、osgEarth 库、以及你的应用程序,四者的 ABI(二进制接口)必须一致。Qt 5.12 官方提供的有 MSVC2015、MSVC2017 等预编译包,OSG 和 osgEarth 你如果是自己用 CMake 编译的,也要选对应的 Visual Studio 生成器。混用不同编译器的库,最常见的后果就是链接时一堆无法解析的外部符号,或者运行时崩溃在某个莫名的内存地址上。
1.2 MSVC 和 MinGW 的本质区别
既然标题里明确写了“编译器 msvc2017”,我得把这事儿说透。Qt 官方安装包会同时提供 MinGW 和 MSVC 两套工具链,很多人图省事装了 MinGW 版本,结果后面调用某些 Windows API、接入第三方 SDK 时各种受挫。
MSVC 就是 Microsoft Visual C++ 编译器,它的运行库是 Windows 系统自带的 Universal CRT 和 VC Runtime;MinGW 是 GNU 编译器在 Windows 下的移植版,用的是开源运行库。两者生成的二进制文件不能混用,你写代码时包含的头文件、链接的 .lib 文件,都必须跟最终执行时加载的 .dll 来自同一套编译链。
对 OSG / osgEarth 这套库来说,还有更现实的原因:osgEarth 依赖的 GDAL、CURL、SQLite 等第三方库,在 Windows 上大多只有 MSVC 版本的预编译包。你要用 MinGW 就得全部自己折腾源码编译,工作量瞬间翻好几倍。而且 OSG 官方提供的 Windows 预编译包也是 MSVC 版本的。所以做这套开发,老老实实走 MSVC 是性价比最高的路。
2. 开发环境准备与库编译要点
2.1 Qt 5.12 安装时的组件选择
装 Qt 的时候千万别无脑全选,也不要只选一个“Qt 5.12.12”就完事。打开 Qt 安装器的组件树,在 Qt 5.12.12 这一层下面,你会看到 MSVC 2017 32-bit、MSVC 2017 64-bit 这两个关键选项。如果你的内存大于 4GB、模型数据比较大,务必选 64-bit 版本,我这边就是用 64 位的。
另外强烈建议勾选 "Qt Debug Symbols" 和 "Qt Sources",前者让你在调试时能进入 Qt 源码,后者在排查问题时可以直接看 Qt 的实现。别嫌占磁盘空间,Debug 阶段你会感谢这两个选项的。
还有 Qt Creator 本身不用额外装,Qt 安装包自带。不过装完以后建议到“工具 → 选项 → Kits → 编译器”里确认一下 MSVC2017 的检测状态。有时候你已经装了 VS2017,但 Qt Creator 没自动识别,需要手动添加cl.exe的路径。添加方法很简单:编译器选项卡里点“添加 → MSVC”,编译器路径填C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\bin\Hostx64\x64\cl.exe,具体的版本号路径以你机器为准。这里容易犯的错是填了 Hostx86 的路径,导致 64 位目标编译不了。
2.2 OSG 3.4 与 osgEarth 2.8 的编译准备
OSG 和 osgEarth 涉及到的第三方依赖比较多,如果你是第一次编译,建议先理顺依赖顺序:第三方库 → OSG → osgEarth。第三方库里最核心的是 GDAL、CURL、SQLite、ZLIB、PNG、JPEG、TIFF 等跟地形和影像读写相关的库。
我不建议你用 vcpkg 一次性全装,因为 vcpkg 默认的 OSG 版本可能跟 osgEarth 2.8 的接口不匹配。更可控的做法是手动下载源码,逐个用 CMake 配置编译:
- OSG 3.4 源码:直接从 GitHub 的 OpenSceneGraph 仓库拉取
OpenSceneGraph-3.4.1标签 - osgEarth 2.8 源码:拉取
osgEarth-2.8分支
注意 osgEarth 2.8 对 CMake 的最低版本有要求,建议 CMake 用 3.15 以上。编译时几个关键配置项:
CMAKE_PREFIX_PATH = D:/dev/Qt/5.12.12/msvc2017_64 # 让 osgEarth 能发现 Qt CMAKE_BUILD_TYPE = Release OSG_USE_QT = ON如果你在 osgEarth 的 CMake 配置界面里找不到 Qt 相关选项,大概率是CMAKE_PREFIX_PATH没指对。Qt 的 MSVC2017_64 目录下应该有lib/cmake/Qt5这样的子目录,CMake 才能通过find_package(Qt5)找到 Qt。
2.3 编译时的核心参数选择
编译 OSG 时有几个参数会直接影响后续使用体验,我按优先级排一下:
第一,CMAKE_CONFIGURATION_TYPES 设成 Release;Debug。不要只编 Release,调试时你会需要 Debug 版本来定位崩溃问题。第二,OSG_USE_QT 一定要开 ON,否则 osgEarth 的 UI 集成组件(比如 osgEarthQt)编不出来。第三,BUILD_OSG_PLUGINS 保持默认全开,OSG 的插件机制是靠动态库实现的,少了某个插件就意味着某类模型或图片加载不了。
编译时间上,OSG 全量编译在 8 核机器上大约要 20-30 分钟,osgEarth 依赖少一些,大约 5-10 分钟。编译完以后记得把生成目录里的bin路径加到系统 PATH,或者至少在你的工程运行配置里把 PATH 指过去。我的做法是直接在系统环境变量里加:
D:/dev/OSG/OpenSceneGraph/bin D:/dev/osgEarth/install/bin这样不管是命令行还是 Qt Creator 里跑,都能找到对应的 DLL。
3. Qt Creator 下的 osgEarth 工程搭建实操
3.1 创建工程与 .pro 文件编写
打开 Qt Creator,新建项目时选“其他项目 → 空的 qmake 工程”就行。我一般不勾选“生成主窗口”之类的模板,因为 OSG 渲染窗口的嵌入方式跟普通 QWidget 稍有不同,手写反而更清晰。
工程的 .pro 文件是整个配置的核心,我的基础配置长这样:
QT += core gui widgets opengl CONFIG += c++11 TARGET = OsgEarthDemo TEMPLATE = app DEFINES += QT_DEPRECATED_WARNINGS DEFINES += WIN32 INCLUDEPATH += D:/dev/OSG/OpenSceneGraph/include \ D:/dev/osgEarth/install/include \ D:/dev/Qt/5.12.12/msvc2017_64/include LIBS += -LD:/dev/OSG/OpenSceneGraph/lib \ -LD:/dev/osgEarth/install/lib \ -lOpenThreads \ -losg \ -losgDB \ -losgGA \ -losgViewer \ -losgEarth \ -losgEarthUtil \ -losgEarthQt这里有几个细节要提醒你:lib 名称不要带 .dll 或 .lib 后缀,也不要带osg130之类的版本号。qmake 会根据-l参数自动去LIBS指定的目录里找对应名称的 .lib 文件。如果你编译 OSG 时改了库命名规则(比如加了_d后缀区分调试版),那这里还需要针对 debug 和 release 分别处理,通常用CONFIG(debug, debug|release)和CONFIG(release, debug|release)区分。
另一个容易忽视的是opengl模块。Qt 5.12 里 OpenGL 模块被拆分得更细,你不仅要QT += opengl,建议也加上QT += openglextensions,否则有些头文件会报找不到。
3.2 主窗口代码框架:让 osgEarth 渲染到 QWidget 里
OSG 嵌入 Qt 的经典做法是把osgViewer::Viewer的摄像机图像附着到 QWidget 的窗口句柄上。网上很多教程用的是osgViewer::GraphicsWindowEmbedded,配合QWidget::winId()来创建渲染窗口,这个思路没错,但有几个关键点漏了会直接黑屏或者崩溃。
首先,QWidget 必须显式设置Qt::WA_NativeWindow属性,让它拥有独立的原生窗口句柄。不设置的话,winId() 返回的可能是 QWidget 内部合成的窗口,OSG 往上面画东西就会出问题。其次,你还得处理 Qt 的高DPI缩放,否则在 2K 或 4K 屏幕上画面会模糊。最简单的方案是在 main 函数开头调用:
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);然后是事件循环问题。OSG 的frame()函数会一直刷新渲染,你不能把它放到 GUI 线程里死循环,否则窗口拖拽、按钮点击全部卡死。我的做法是用一个QTimer定时调用 viewer 的 frame:
QTimer timer; QObject::connect(&timer, &QTimer::timeout, [&]() { viewer->frame(); }); timer.start(16); // 约 60 FPS如果你需要更高的交互流畅度,也可以把渲染放到独立线程,但那就涉及线程间同步和 GL 上下文共享的问题,复杂度高一截。对大多数 GIS 场景,16ms 定时刷新的方案完全够用。
3.3 创建 osgEarth 地图节点
osgEarth 的加载方式有两种:earth 文件(XML)和代码硬编码。推荐用 earth 文件,因为修改地图源、图层配置时不用重新编译。我举个最简单的地形加载例子:
<map name="MyMap" type="geocentric"> <options> <cache type="filesystem"> <path>D:/cache</path> </cache> </options> <image layer driver="gdal"> <url>D:/data/world.tif</url> </image> <elevation layer driver="gdal"> <url>D:/data/srtm.tif</url> </elevation> </map>代码里加载就一行:
osg::ref_ptr<osgEarth::MapNode> mapNode = osgEarth::MapNode::load("D:/data/map.earth");这里的核心技巧是type="geocentric"还是type="geodetic"。地心坐标系适合全球视角,投影坐标系适合局部区域。如果你的数据是 WGS84 经纬度的影像,且要拉得很远看,用geocentric可以避免极点附近的畸变;如果只是看某一城市的局部,用geodetic性能会更好,因为少了椭球体变换的数学开销。
3.4 配置运行环境 PATH 和 DLL 搜索路径
终于到了那个著名的 "no qt platform plugin could be initialized" 报错环节。这个报错几乎每个 Qt 新手都会遇到,场景就是你点了运行,程序一闪而过,控制台输出这么一行红字。原因其实特别朴素:Qt 的程序启动时需要加载 platform 插件(qwindows.dll),而这个插件位于 Qt 安装目录的plugins/platforms下,你的程序找不到它。
解决办法有两个层面,第一层是开发期临时解决,在 Qt Creator 的“项目 → 运行 → 环境”里增加 PATH,把D:/dev/Qt/5.12.12/msvc2017_64/plugins加进去。第二层是发布期,用windeployqt工具自动把 Qt 相关的 DLL 和插件拷贝到 exe 同级目录,命令是:
windeployqt D:/build/OsgEarthDemo/release/OsgEarthDemo.exe但 windeployqt 只会处理 Qt 自身的依赖,OSG 和 osgEarth 的 DLL 它不管。所以你还得手动把 OSG 的bin目录下的所有 DLL 拷到 exe 目录,或者再把D:/dev/OSG/OpenSceneGraph/bin和 osgEarth 的 bin 目录也加进 PATH。我这里给个建议:开发期全用 PATH 环境变量,发布期才拷贝 DLL,这样改代码重编时不会因为 DLL 版本覆盖而引入莫名其妙的 bug。
3.5 Debug/Release 混合使用的隐藏坑
这应该是整套环境里最隐蔽的问题——Qt 的 Debug 和 Release 模式用的库文件名不一样。Qt 在 Debug 模式下链接的是Qt5Cored.dll、Qt5Guid.dll,Release 模式则不带d;OSG 库也类似,编译时如果你选择了生成调试符号,可能得到的是osgd.lib、osgDBd.lib。
很多人 .pro 文件里只写了-losg -losgDB,结果 Debug 编译时链接器找不到osgd.lib,报错LNK1104: cannot open file 'osgd.lib'。解决办法有两个:一是写程序时就用CONFIG(debug, debug|release)分别指定不同库名;二是干脆只使用 Release 版本的 OSG 库,Debug 程序也链接 Release 库。第二种方法不推荐,因为 Debug 程序带调试信息,而 Release 库做了优化,两者混用可能导致调试时看到的值和实际不符、单步跟踪时跳到错误的行号。
我推荐的做法是在 .pro 文件里写一段干净的版本判断:
CONFIG(debug, debug|release) { LIBS += -losgd -losgDBd -losgViewerd -losgEarthd -losgEarthUtild } else { LIBS += -losg -losgDB -losgViewer -losgEarth -losgEarthUtil }注意 osgEarth 的调试库不一定带了d后缀,这个要看你编译时是否开启了CMAKE_DEBUG_POSTFIX。默认情况下 CMake 会加,但如果你编译时清掉了这个选项,那就只能靠肉眼检查 lib 目录下的文件名来确认了。这东西很烦,但一旦配好,Debug/Release 切换就是零成本。
4. 常见问题与排查技巧实录
4.1 启动崩溃与黑屏问题速查
这套环境常见的运行问题有好几个,我把它们列成一张速查表,你按图索骥会快很多:
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 启动提示 no qt platform plugin could be initialized | PATH 缺少 Qt plugins 路径 | 在运行环境里把D:/dev/Qt/5.12.12/msvc2017_64/plugins加进 PATH |
| 窗口弹出来但全黑 | 没有调用viewer->frame()或未设置线程模型 | 检查 QTimer 定时器是否启动;在 viewer 初始化时设置osgViewer::ViewerBase::SingleThreaded |
| 加载 .earth 文件没反应,控制台无输出 | 缺少 osgdb_earth 插件或 earth 文件路径错误 | 检查 OSG 的 plugin 目录下是否有osgdb_osgearth.dll;用绝对路径 |
| 编译报错无法打开 osgd.lib | Debug 模式下用了 Release 库名 | 按上文所述在 .pro 里区分 debug/release 库名 |
| 运行时内存访问冲突,崩溃位置在 osgEarth::MapNode | OSG 与 osgEarth 版本不匹配 | 确认 OSG 3.4 对应 osgEarth 2.8,不要混用其他大版本 |
这里面最阴间的其实是黑屏问题。很多人以为窗口出来了、程序没崩溃就算成功了,结果黑屏上什么都没有,这时候第一反应是去看 .earth 文件路径、去看影像数据读取,但经常忽略了渲染线程没有跑起来这件事。OSG 的 Viewer 默认是多线程模式,在某些 Windows 显卡驱动下,多线程渲染嵌入到 QWidget 里会出现无法附着上下文的问题,表现就是黑屏。
解决方法是显式设置线程模型:
viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);在开发初期用单线程模式足够,而且调试起来特别方便。等到功能稳定了再切换回DrawThreadPerContext或多线程模式提升性能。
4.2 osgEarth 插件加载失败的排查思路
osgEarth 加载地图时依赖 OSG 的插件机制,它的osgdb_osgearth.dll要能被 OSG 找到。这个插件默认在 osgEarth 的bin目录下,但 OSG 找插件时不是去 PATH 里找,而是去找 OSG 的OSG_LIBRARY_PATH环境变量,或者它自己编译时默认设置的插件路径。
有几次我明明把 bin 目录加进了 PATH,但 osgEarth 文件就是加载不了,后来发现是因为osgdb_osgearth.dll依赖的osgEarth.dll在加载时失败了(DLL 依赖链断裂)。Windows 的 DLL 搜索顺序是先看应用程序目录、再看系统目录、再看 PATH,所以我建议最稳的方法是把所有 OSG 和 osgEarth 的 DLL拷贝到 exe 所在目录,一劳永逸,不依赖 PATH 顺序。
判断插件加载是否成功,可以在加载 .earth 文件之前设置 OSG 的通知级别:
osg::setNotifyLevel(osg::INFO);控制台会输出类似这样的信息:
Info: Registry::loadLibrary(osgdb_osgearth.dll)如果你没看到loadLibrary的成功信息,那就说明插件没被找到或加载失败,按上面说的方法处理。
4.3 性能调优的独门经验
当你的程序能跑起来之后,就会开始关心性能问题。osgEarth 默认加载高分辨率影像和地形时,第一次会很卡,这是因为它在做数据调度和缓存。有几个参数值得你调一下:
第一,缓存一定要开。在地球文件里配置 filesystem 缓存后,第一次浏览缓存到本地,第二次启动速度能提升 5-10 倍。缓存目录放在 SSD 上效果更明显。第二,调整 LOD 策略。如果你主要看小范围高精度数据,可以把max_range调高,让高细节层在更远距离就开始加载;反之,如果你看全球范围,就把min_range调大,避免加载过多无谓细节。
第三,影像和地形并发策略。osgEarth 2.8 的默认调度器是MapNodeProfile,在 CPU 核心多的情况下,可以把调度器线程数调大:
<options> <scheduler driver="default"> <num_threads>8</num_threads> </scheduler> </options>不过这里要注意,线程数不是越大越好。osgEarth 的数据调理会占用 IO 带宽,如果数据在机械硬盘上,线程开太多反而会因为磁盘寻道竞争而变慢。我自己实测下来,8 核机器配num_threads=4是磁盘 IO 和数据解码的甜点值。
4.4 粒子效果和扩展方向
搜热词里有人提到“osg粒子效果”,这是个很好的扩展方向。OSG 自带的粒子系统(osgParticle)跟 osgEarth 可以无缝集成,因为 osgEarth 的 MapNode 本质上是一个 OSG 节点,你可以随便往场景里加粒子特效。比如模拟爆炸、喷泉、天气效果,都能直接挂在场景图里。
我基于这套 Qt + osgEarth 工程做过一个简单的粒子需求,核心代码就十几行:
osg::ref_ptr<osgParticle::PrecipitationEffect> rain = new osgParticle::PrecipitationEffect; rain->rain(0.5); mapNode->addChild(rain);PrecipitationEffect是 OSG 自带的最简单的粒子实现,雨、雪效果都能出。复杂一点的粒子系统要用osgParticle::ParticleSystem配合ModularProgram和Emitter自己搭,但原理是一样的:只要能拿到场景根节点的引用,粒子就能加到任何位置。对于 GIS 场景来说,一个常见的应用是把粒子系统绑定到某个地理坐标上空,可以通过osgEarth::GeoTransform节点把局部坐标转换到地理坐标:
osg::ref_ptr<osgEarth::GeoTransform> xform = new osgEarth::GeoTransform; xform->setPosition(osgEarth::GeoPoint(mapNode->getMapSRS(), 116.39, 39.90, 500)); xform->addChild(rain.get()); mapNode->addChild(xform.get());这样粒子就会出现在北京上空 500 米的位置,而且会随着视角远近调整。
5. 工程迁移与发布实战要点
5.1 换机器后的重新部署难题
工程在一台机器上配好了,换到另一台机器上可能还会遇到新的问题。最常见的就是路径硬编码。我在 .pro 文件里写的D:/dev/OSG这种路径,到另一台机器上可能就变成了E:/libs/OSG,你需要通篇替换。
一个更好的做法是用 qmake 的环境变量引用:
OSG_ROOT = $$(OSG_ROOT) isEmpty(OSG_ROOT) { OSG_ROOT = D:/dev/OSG } INCLUDEPATH += $$OSG_ROOT/include LIBS += -L$$OSG_ROOT/lib然后在系统环境变量里定义OSG_ROOT,这样换机器只需要改一个环境变量,不需要动代码。osgEarth 的位置也建议用类似方式处理,比如OSGEARTH_ROOT。
5.2 发布时的最小依赖集
用 windeployqt 打完包之后,exe 同级目录会生成一堆 Qt DLL 和 plugins 文件夹。但这只是“最小 Qt 依赖”,你还得手动把以下内容拷贝进去:
- OSG 的全部 DLL:
OpenThreads.dll、osg*.dll - osgEarth 的全部 DLL:
osgEarth.dll、osgEarthUtil.dll、osgEarthQt.dll - OSG 插件目录:
osgPlugins-3.4.0(版本号以实际为准) - osgEarth 插件:
osgdb_osgearth.dll - 如果是 Debug 版本,所有 Debug DLL 也要带
d后缀
一个容易忽略的点是C++ 运行库。如果你用的是 MSVC2017 工具链,目标机器上需要有 VC++ 2015-2022 Redistributable。如果是 Debug 版,还需要调试运行时(Debug 版 VC++ Redistributable),这个默认不装的话程序会直接报缺少vcruntime140d.dll。发布时建议直接编译 Release 版本,省掉这个麻烦。
5.3 常见发布后崩溃问题
发布版最常遇到的崩溃有两种。第一种是“无法定位程序输入点于动态链接库”,这个基本上是因为 exe 启动时加载的某个 DLL 版本不对,比如系统里已经装了一个旧版 OSG,PATH 优先级把旧版 DLL 给找上了。排查方法是用 [Dependency Walker] 或 [Process Explorer] 查看实际加载的 DLL 路径,然后把正确的 DLL 放到 exe 目录下,强制优先加载。
第二种是“0xc000007b”错误,这个错误码的意思是“应用程序无法正常启动”。大概率是 64 位和 32 位二进制混用。比如你编译的是 x64 程序,但拷贝进来的某个 DLL 是 32 位的,就会触发这个错。检查方法很简单,右键 DLL 看属性,或者在 VS 开发者命令行里执行dumpbin /headers xxx.dll查看机器类型。、
6. 我的最终配置清单与建议
为了让你少走弯路,我把最终的一套可用的关键配置汇总一下:
Qt 版本: Qt 5.12.12 MSVC2017 64-bit 编译器: Visual Studio 2017 (MSVC 14.16) OSG 版本: OpenSceneGraph 3.4.1 osgEarth 版本: osgEarth 2.8 CMake: 3.20 第三方依赖: GDAL 2.4, CURL 7.x, SQLite 3.x 编译模式: Release + Debug 都编译 OSG_USE_QT: ON 工程构建工具: qmake + Qt Creator 4.x这套搭配我前后跑了两个项目,一个是地形浏览,一个是基于遥感影像的标绘系统,运行都挺稳定。最后再分享一个小技巧:调试 osgEarth 的 earth 文件配置时,不要每次都启动 GUI 程序,可以先写一个控制台工具只做加载和打印:
osg::ref_ptr<osgEarth::MapNode> node = osgEarth::MapNode::load(argv[1]); if (!node.valid()) { std::cerr << "load failed" << std::endl; return 1; } std::cout << "map loaded, layers: " << node->getMap()->getNumLayers() << std::endl;这样排查数据问题比开 GUI 调试快得多。等控制台工具确认 earth 文件没问题,再回到 Qt 工程里看渲染交互,两边结合,效率能高不少。这套环境配置本身不复杂,难就难在版本匹配和路径一致性上,只要这两点掌握好,后面开发就顺了。
本文还有配套的精品资源,点击获取