资讯动态

MSVC2017环境下OSG3.6.3与osgEarth2.10集成Qt5.14配置指南

发布时间:2026/9/29 15:54:55 来源:尧图企业网站定制
简介这套压缩包是基于MSVC2017编译的OSG 3.6.3与osgEarth 2.10开发环境整合包同时附带了Qt 5.14/Qt Creator下的简易示例工程。包体约530MB包含约2000个文件类型涵盖大量hpp/h头文件、dll动态库、exe可执行文件、lib/ilk编译产物、earth/osg场景数据以及着色器脚本可直接作为项目依赖或环境验证模板。资源内还提供Qt工程源码与已编译好的库文件包含基于QWidget的渲染窗口和图像适配等示例代码方便开发者在Windows平台快速搭建基于osgEarth的三维渲染应用免去从源码构建OSG、osgEarth时复杂的依赖匹配和编译工作。借助预编译库即可链接调用示例工程也展示了Qt窗口与OSG交互的集成方式便于在此基础上扩展自定义功能。已有532人学习下载适合需要快速适配MSVC2017Qt5.14环境的中高级三维GIS开发人员。1. 拿到 msvc2017osg3.63osgearth2.10qt5.14 压缩包先搞清楚它解决什么做三维 GIS 或者数字孪生底板的同行大概率都经历过同一个翻车现场在 QtCreator 里配好的 osgEarth 工程MinGW 编译器编不过换用 msvc 编译器又找不到 osg 的头文件和 lib最后卡在「工具链选错、库全废」这一步上。这个压缩包就是为了绕开这条弯路——它把 MSVC2017 工具链、OSG 3.6.3、osgEarth 2.10、Qt 5.14 这四样东西按同一套 ABI 打包好解压后直接在 QtCreator 里建 Kit 就能编译运行。适合三类人刚接触 OSG 想少踩编译坑的新手做 Qt 三维视景需要快速搭出可运行 DEMO 的工程师以及被 osgEarth 版本对接折磨过想换一套干净环境的老人。它能解决的核心问题只有一个让 MSVC 编译器下的 OSG 程序在 Qt 窗口里正常跑起来而不是把时间耗在配环境上。2. 为什么是 MSVC 而不是 MinGW编译链选择与解压后的三处硬配置2.1 MinGW 与 MSVC 的差异光跑通和能出稳定三维程序的边界很多新手习惯在 Qt 官网下载页面直接选带 MinGW 的安装包因为 QtCreator 默认就能识别不用额外装 Visual Studio。但 OSG 和 osgEarth 这种底层三维库官方预编译包基本只发 MSVC 版本MinGW 版本要么自己用源码编要么依赖第三方维护的旧包。原因很直接MinGW 用的 GNU 工具链和 MSVC 的 C ABI 不兼容两个编译器编出来的静态库、动态库的符号修饰规则、异常处理方式都不一样混用会出现「头文件能 include链接时报一堆无法解析的外部符号」这种玄学问题。所以我 General 的建议是做 Windows 桌面三维应用只要不是强制要求开源工具链一律用 MSVC。osg 3.6.3 的预编译包标注 msvc2017_64osgEarth 2.10 也要求对应的 MSVC 版本Qt 5.14.2 官方同时提供 msvc2017_64 和 mingw73_64 两套选 msvc2017_64 这套才能跟 OSG 的库对上号。这里还有一个细节Qt 5.14 之后官方对 MinGW 的支持还在但 osgEarth 2.10 在 2019 年发布时就是针对 VS2017 做的发布验证你用 MinGW 去编它的源码会遇到大量第三方依赖库libzip、curl、sqlite3的交叉编译问题得不偿失。2.2 解压与路径规范D:/OSG 下的目录结构与 Qt 匹配压缩包解压后我一般会放到固定盘符根目录不建议放带中文或空格的路径也不建议放桌面。假设解压到D:/OSG目录结构长这样路径内容D:/OSG/OpenSceneGraph-3.6.3/includeOSG 全部头文件以osg/、osgViewer/、osgQt/开头D:/OSG/OpenSceneGraph-3.6.3/libosg 系列静态库与导入库文件形如osgViewerd.lib、osgEarth.libD:/OSG/OpenSceneGraph-3.6.3/bin运行所需的 DLL包括osg80-osgViewerd.dll、osgEarthd.dll等D:/OSG/osgEarth-2.10/includeosgEarth 头文件含osgEarth/MapNode、osgEarthUtil/ViewpointD:/OSG/osgEarth-2.10/libosgEarth 相关库osgEarthd.lib、osgEarthUtild.libD:/Qt/5.14.2/msvc2017_64Qt 5.14.2 的 MSVC 版本Bin 下带qmake.exe这里要特别注意 osgEarth 2.10 的库是跟 osg 3.6.3 混放在一个 lib 目录下的所以工程里写 LIBS 时OSG 和 osgEarth 的库路径可以指向同一个目录省事。但头文件目录建议分开写因为 osgEarth 的头文件里会通过相对路径引用 OSG 的头文件如果两个 include 路径都加进去编译器能找到全部依赖。2.3 环境变量与 PATH 硬配置别让 dll 在发布时失踪解压完不是直接就能用环境变量这一步漏了后面 QtCreator 里跑起来会报「找不到 osgEarthd.dll」。我习惯设三个系统环境变量变量值作用OSG_ROOTD:/OSG/OpenSceneGraph-3.6.3让 osgEarth 的 CMake 模块能找到 OSG 根目录OSG_FILE_PATHD:/OSG/OpenSceneGraph-3.6.3/dataOSG 自带模型数据的搜索路径跑 cow.osg 示例时用到PATH末尾追加D:/OSG/OpenSceneGraph-3.6.3/bin;D:/Qt/5.14.2/msvc2017_64/bin让程序和 QtCreator 运行时能找到 DLL设置完后在 cmd 里敲osgversion能输出版本信息就说明 OSG 的 bin 生效了。注意 PATH 里的顺序Qt 的 bin 排在后面避免 Qt 自带的某些 DLL 版本覆盖系统目录里的同名文件这种冲突在 Qt 5.14 上很常见尤其是libEGL.dll和libGLESv2.dll。提示环境变量改完后QtCreator 要完全退出重开才会读到新的 PATH。只关工程不退出程序照样找不到 DLL。3. 在 QtCreator 里把 OSG 接进工程qmake 与 CMake 两种写法3.1 QtCreator 新建 MSVC Kit 并绑定编译器环境变量配好之后QtCreator 的第一步是确认工具链识别正常。打开 Tools → Options → Kits 页面看 Compilers 标签下有没有Microsoft Visual C Compiler 17.0 (amd64)这一项。没有的话点 Add 手动指定cl.exe的路径通常是C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx64/x64/cl.exe。同时检查 Qt Versions 标签里有没有Qt 5.14.2 (msvc2017_64)没有就手动指向D:/Qt/5.14.2/msvc2017_64/bin/qmake.exe。Kits 页面新建一个 Kit编译器选刚加进去的 MSVC amd64Qt Version 选 5.14.2 msvc2017_64CMake 工具如果要用 CMake 写法需要确保 CMake 版本不低于 3.16否则 find_package 解析 osgEarth 的配置文件时会失败。注意Kit 里的 C 标准建议选 C17。OSG 3.6.3 和 osgEarth 2.10 用 C11 也能编但 Qt 5.14 的某些头文件在 C17 模式下表现更稳定后续如果接入 Qt Charts 或者 QML 也不会有标准冲突。3.2 pro 文件写法qmake 下把 OSG 库按 debug/release 分开qmake 写法适合不想引入 CMake 的工程直接把依赖写死在.pro文件里。我 General 的最小 pro 文件是这样的QT core gui widgets opengl TARGET OsgQtDemo TEMPLATE app CONFIG c17 console INCLUDEPATH D:/OSG/OpenSceneGraph-3.6.3/include INCLUDEPATH D:/OSG/osgEarth-2.10/include win32:CONFIG(release, debug|release): { LIBS -LD:/OSG/OpenSceneGraph-3.6.3/lib LIBS -losg -losgViewer -losgQt -losgDB -losgGA -losgUtil LIBS -losgEarth -losgEarthUtil } else:win32:CONFIG(debug, debug|release): { LIBS -LD:/OSG/OpenSceneGraph-3.6.3/lib LIBS -losgd -losgViewerd -losgQtd -losgDBd -losgGAd -losgUtild LIBS -losgEarthd -losgEarthUtild }逻辑说明这个 pro 文件的核心是 debug 和 release 两套库名。MSVC 环境下OSG 的 debug 库统一带d后缀比如osgViewer.lib对应 releaseosgViewerd.lib对应 debug。如果不区分直接写-losgViewerdebug 编译时链接器会找不到osgViewerd.lib报错LNK1104: cannot open file osgViewerd.lib。参数说明-L指定库搜索目录-l指定库名-l后面的名字要去掉.lib后缀。这里有一个容易翻车的点——osgQt这个库在 OSG 3.6.3 里是独立编译的如果你用的 OSG 包没有编 osgQt链接时会直接报找不到osgQt.lib。解压包里带了这个库就不用担心但如果是自己从源码编的 OSG记得在 CMake 配置时勾选BUILD_OSG_PLUGINS和BUILD_OSGQT相关选项。3.3 CMake 写法用 find_package 减少路径硬编码如果你的项目已经在用 CMake那更推荐这种方式因为 osgEarth 2.10 自带 CMake 配置文件能自动解析依赖关系。cmake_minimum_required(VERSION 3.16) project(OsgQtDemo) set(CMAKE_PREFIX_PATH D:/Qt/5.14.2/msvc2017_64 D:/OSG/OpenSceneGraph-3.6.3) set(CMAKE_AUTOMOC ON) find_package(Qt5 REQUIRED COMPONENTS Widgets OpenGL) find_package(OpenSceneGraph REQUIRED COMPONENTS osgDB osgViewer osgGA osgQt osgUtil) find_package(osgEarth REQUIRED) add_executable(OsgQtDemo main.cpp) target_link_libraries(OsgQtDemo Qt5::Widgets Qt5::OpenGL ${OPENSCENEGRAPH_LIBRARIES} ${OSGEARTH_LIBRARIES} )逻辑说明find_package(OpenSceneGraph)会读取 OSG 安装目录下的OpenSceneGraphConfig.cmake把头文件路径、库路径、库名一次性填充到OPENSCENEGRAPH_LIBRARIES变量里。find_package(osgEarth)同理它会检查 osgEarth 的版本是否与 OSG 匹配2.10 版本要求 OSG 不低于 3.6恰好满足。参数说明CMAKE_PREFIX_PATH必须同时包含 Qt 和 OSG 的根目录这样find_package才能按顺序找到两套配置。这里有三个坑第一osgEarth的 CMake 配置文件会调用find_package(OpenSceneGraph)如果CMAKE_PREFIX_PATH里 OSG 路径排在 Qt 后面cmake 会先找到 Qt 目录下的配置导致 OSG 版本检测失败第二osgQt组件在部分 OSG 预编译包里没有单独的 cmake 模块找不到就手动把D:/OSG/OpenSceneGraph-3.6.3/lib/osgQt.lib加到 target_link_libraries 里第三MSVC 环境下必须显式指定生成器比如cmake -G Visual Studio 15 2017 Win64否则 CMake 默认生成器可能是 MinGW 的库又对不上。4. 跑通第一帧Qt 窗口内嵌 osgQt 与 osgEarth 场景验证4.1 用 osgQt 把渲染窗口挂进 QWidget环境配置完成后的第一个验证目标是在 Qt 窗口里看到 OSG 的三维场景。OSG 3.6.3 里负责对接 Qt 的模块叫osgQt它提供GraphicsWindowQt类本质上是一个托管在 QWidget 里的 OpenGL 渲染窗口。注意这里不是老的osgViewer::Viewer直接建窗口而是让 Viewer 使用已经嵌入 QWidget 的 GraphicsWindow 来渲染。#include QApplication #include QWidget #include QVBoxLayout #include osgViewer/Viewer #include osgDB/ReadFile #include osgQt/GraphicsWindowQt osg::ref_ptrosgQt::GraphicsWindowQt createGraphicsWindow(int x, int y, int w, int h) { osg::DisplaySettings* ds osg::DisplaySettings::instance(); osg::ref_ptrosg::GraphicsContext::Traits traits new osg::GraphicsContext::Traits(ds); traits-windowName OsgQt Demo; traits-x x; traits-y y; traits-width w; traits-height h; traits-windowDecoration false; traits-doubleBuffer true; traits-alpha ds-getMinimumNumAlphaBits(); traits-stencil ds-getMinimumNumStencilBits(); traits-sampleBuffers ds-getMultiSamples(); traits-samples ds-getNumMultiSamples(); return new osgQt::GraphicsWindowQt(traits.get()); } int main(int argc, char** argv) { QApplication app(argc, argv); QWidget* mainWidget new QWidget; QVBoxLayout* layout new QVBoxLayout(mainWidget); osg::ref_ptrosgQt::GraphicsWindowQt gw createGraphicsWindow(0, 0, 800, 600); QWidget* widget gw-getGLWidget(); layout-addWidget(widget); osg::ref_ptrosgViewer::Viewer viewer new osgViewer::Viewer; viewer-setGraphicsContext(gw.get()); viewer-setThreadingModel(osgViewer::Viewer::SingleThreaded); viewer-setCameraManipulator(new osgGA::TrackballManipulator); osg::ref_ptrosg::Node scene osgDB::readNodeFile(cow.osg); viewer-setSceneData(scene.get()); mainWidget-show(); viewer-realize(); // 用 QTimer 持续刷新帧 QTimer* timer new QTimer; QObject::connect(timer, QTimer::timeout, []() { viewer-frame(); }); timer-start(16); // 约 60 FPS return app.exec(); }逻辑说明这个代码的核心步骤是「创建 GraphicsWindowQt → 把它的 QWidget 塞进布局 → 让 Viewer 使用这个窗口 → 用 QTimer 驱动 frame()」。frame()是 OSG 渲染一帧的入口放在 QTimer 里而不是自己开渲染线程是为了避免与 Qt 的事件循环冲突。需要考虑单线程模式SingleThreaded这是 osgQt 嵌入模式下最稳的配置开了多线程 DrawThreadPerContext 容易出现 OpenGL 上下文在不同线程切换导致的崩溃。参数说明traits里的sampleBuffers和samples是抗锯齿参数从DisplaySettings::instance()读取默认值如果目标机器显卡不支持会出现黑屏此时把两行改成traits-sampleBuffers 0; traits-samples 0;再试。cow.osg是 OSG 自带的模型文件路径靠OSG_FILE_PATH环境变量定位如果没有设置就改成绝对路径D:/OSG/OpenSceneGraph-3.6.3/data/cow.osg。4.2 加载 osgEarth 的 earth 文件验证地形窗口跑通普通模型后下一步换成 osgEarth 的地形这才是这套环境真正要发挥作用的地方。osgEarth 2.10 加载场景的方式是读取一个.earth文件里面描述影像、高程、图层的来源。最简单的方式是本地文件驱动的 earth 配置map namedemo typegeocentric version2 options cache typesqlite pathdemo_cache.db/ /options image layerimagery drivergdal urlD:/Data/satellite.tif/url /image elevation layerterrain drivergdal urlD:/Data/dem.tif/url /elevation /map逻辑说明typegeocentric表示全球地心坐标系适合加载全球范围数据如果只是做局部小场景改成typegeodetic会更快因为它不用处理极点扭曲。drivergdal是 GDAL 驱动osgEarth 2.10 的预编译包默认集成 GDAL能读 tif、img、dem 等栅格格式。cache节点是指 sqlite 缓存第一次加载会建索引后续再跑就快很多。参数说明url路径一定要用正斜杠或者双反斜杠否则 GDAL 在 Windows 下解析路径会出错。cache的path建议放在数据目录旁边别放 C 盘因为这块缓存占空间不小一张 1GB 的影像会生成几百 MB 的缓存文件。加载类示例osg::ref_ptrosgEarth::MapNode mapNode; osg::ref_ptrosgEarth::Map map new osgEarth::Map; mapNode new osgEarth::MapNode(map.get()); osg::ref_ptrosg::Node earthRoot osgDB::readNodeFile(D:/Data/map.earth); mapNode osgEarth::MapNode::get(earthRoot.get()); viewer-setSceneData(mapNode.get());逻辑说明osgDB::readNodeFile读取.earth文件时会通过 osgEarth 的插件机制解析 XML生成一个包含 MapNode 的节点。拿到这个节点后用MapNode::get从场景图中提取 MapNode 指针然后直接 setSceneData 即可。如果 earth 文件解析失败osgEarth 会在终端输出具体的驱动错误。4.3 验证成功的三个信号窗口、帧率、日志很多人跑通窗口就以为环境没问题其实只验证了一半。我 General 的习惯是看三个信号第一窗口是否出现且地形是否正常渲染没有黑屏、花屏、闪烁第二用滚轮缩放、拖动旋转是否流畅平均帧率维持在 30 FPS 以上才算合格第三控制台是否输出 osgEarth 的加载日志包含类似[osgEarth] Map loaded OK字样有这句说明 GDAL 驱动和数据源都正常。有一个容易被忽略的细节Qt 的 MSVC 版本默认输出到调试器如果在 QtCreator 里看不到 osgEarth 日志去 Tools → Options → Build Run → Debuggers 里确认 GDB 或 CDB 是启用的。跑 Release 模式时建议在 main 开头加一句osg::setNotifyLevel(osg::WARN);这段的作用是调低 OSG 的日志级别因为 osgEarth 加载成功后会在 INFO 级别输出大量细节Release 模式下刷屏会影响排查真正的问题。等确认能正常加载后再改回osg::NOTICE以保留 info 日志。5. 避坑清单MSVC 版 OSG 最常翻车的五个现场5.1 现象双击 exe 提示缺少 VCRUNTIME140.dll / msvcp140.dll原因目标机器上没有安装 Visual C 2017 运行库。OSG 3.6.3 的预编译包是用 VS2017 编的链接的是VCRUNTIME140.dll这是 VS2015–2019 共用的运行时但 Windows 10 老版本不会预装。解决在目标机器上安装vc_redist.x64.exe这一步所有部署 MSVC 程序都需要。也可以在 QtCreator 里用 Qt 自带的windeployqt.exe把运行库拷到 exe 目录命令是D:/Qt/5.14.2/msvc2017_64/bin/windeployqt.exe --release your_app.exe它会自动识别依赖并拷贝 DLL。5.2 现象编译时报cannot find -losgViewerd或LNK1104: cannot open file osgViewerd.lib原因pro 文件里 debug 和 release 的库名没有区分开或者工程处于 debug 模式但 LIBS 写的是 release 库名。MSVC 的 debug 库必须带d后缀osgViewerd.lib和osgViewer.lib完全不是同一个文件。解决严格按照 3.2 节的方式在 pro 文件里用win32:CONFIG(release, debug|release)和win32:CONFIG(debug, debug|release)两段分别写库名。也可以用 CMake让find_package(OpenSceneGraph)自动根据构建类型选择 debug/release 库。5.3 现象程序启动时提示qt.qpa.plugin: could not find the Qt platform plugin windows原因运行时缺少 Qt 的 platform 插件qwindows.dll这个文件在D:/Qt/5.14.2/msvc2017_64/plugins/platforms/目录下。OSG 程序的 exe 不会自动去 plugins 目录找插件需要显式指定或者拷贝。解决两种方案。一种是用windeployqt自动部署所有插件另一种是手动把plugins/platforms/qwindows.dll拷贝到 exe 的同级platforms目录并且在 main 里设置QApplication::addLibraryPath(QCoreApplication::applicationDirPath() /plugins)。我一般用 windeployqt省事且不会漏。5.4 现象程序启动几秒后崩溃退出码 0xC0000005访问冲突原因这个崩溃码在 OSG Qt 场景里最常见的根因是 osgEarth 的信号处理器与 Qt 的事件循环冲突。osgEarth 默认安装了自己的 SIGSEGV/SIGABRT 处理器当某些第三方库比如 libzip在 Qt 线程里触发异常时处理逻辑会走到 OSG 这边直接崩溃。解决在 main 最开始设置环境变量OSGEARTH_NO_SIGNAL_HANDLER1或者在代码里#ifdef _WIN32 _putenv_s(OSGEARTH_NO_SIGNAL_HANDLER, 1); #endif这段代码必须在osgEarth::initialize()之前调用。另外检查是否开了多线程渲染把 viewer 的 threadingModel 固定为SingleThreaded详见 4.1 节。5.5 现象Release 模式下编译通过运行报缺少 DLL但 debug 模式正常原因QtCreator 的构建目录会把 debug 和 release 的产物分开Release 构建目录里没有拷贝 OSG 的 DLL。debug 模式能跑是因为 QtCreator 默认把调试版 DLL 路径加入了 PATHrelease 模式下没有这个特殊照顾。解决在 QtCreator 的 Run 设置里Working Directory 改成D:/OSG/OpenSceneGraph-3.6.3/bin或者在构建后步骤里加一条命令把需要的 DLL 全拷到 exe 目录。建议用windeployqt处理 Qt 部分再用一行批处理把 osg 的 DLL 拷过去copy D:\OSG\OpenSceneGraph-3.6.3\bin\*.dll %USERPROFILE%\Desktop\release_output\6. 落地技巧用 osgEarth 的图层开关做最小可运行数字孪生底板6.1 图层控制与视点定位的两种写法当 osgEarth 场景跑起来后下一步通常是做图层控制。osgEarth 2.10 的 Map 节点支持在运行期动态开图层比如在 Qt 界面上加几个 QCheckBox 控制影像和高程的显隐。代码写法有两种第一种是通过 Map 层的索引控制osgEarth::Map* map mapNode-getMap(); osgEarth::Layer* imageLayer map-getLayerByName(imagery); imageLayer-setVisible(checkbox-isChecked());第二种是通过 MapNode 的图层节点去操作。注意getLayerByName拿到的是Layer指针而可视化节点是ImageLayer或ElevationLayer的子类需要做类型转换。关闭图层后osgEarth 会重新构建地形不需要手动刷新帧。视点定位可以用 osgEarthUtil 的 ViewpointosgEarth::Util::Viewpoint vp; vp.heading() 45.0; vp.pitch() -30.0; vp.focalPoint() osgEarth::GeoPoint(mapNode-getMapSRS(), 116.397, 39.908, 0.0); osgEarth::Util::EarthManipulator* manip new osgEarth::Util::EarthManipulator; manip-setViewpoint(vp); viewer-setCameraManipulator(manip);这个技巧的价值在于把影像、高程、矢量图层分离管理是数字孪生项目构建阶段成本最低的验证方式。先用这套环境把数据调度逻辑跑通后续再接入业务模型风险会小很多。6.2 发布前检查依赖的三板斧每次交付程序前我固定走一遍三个检查步骤。第一用 windeployqt 部署 Qt 依赖确认 platform 插件和 qml 插件齐全第二用 Process Explorer 打开 exe检查是否还有来自D:/OSG、D:/Qt的 DLL 被动态加载防止把开发机的绝对路径依赖带进了发布包第三在一台干净虚拟机里跑一遍能过才算完。验证技巧有个简单办法把D:/OSG/OpenSceneGraph-3.6.3/bin从 PATH 里临时移除然后运行 exe如果直接报缺 DLL说明发布目录没拷全如果正常运行说明不需要污染系统 PATH发布包是自包含的。从那以后我每次解压完这套环境第一件事就是先在命令行调osgversion加编译一个空 osgViewer 窗口确认库路径没串再开始堆业务代码。这套流程虽然看起来多花五分钟但能省掉后面一整天排查环境问题的时间希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑