简介:该资源面向Windows 10平台下从事三维图形与三维GIS开发的C++程序员,提供基于Visual Studio 2019完整编译的OpenSceneGraph 3.6.5与OSGEarth 3.1双版本开发库,解决自行编译耗时长、依赖配置繁琐的问题,可直接接入新项目或替换旧版依赖。压缩包共42个文件,约3.49MB,以lib导入库为主,另含osg_demo示例、main.cpp入口代码及工程配置文件,覆盖几何渲染、地形加载、动画控制、标注系统、光照处理与坐标变换等模块。目录按Release与Debug双模式组织,bin、include、lib三个标准子目录齐备,从AnimationPath、AnnotationNode、AltitudeSymbol、AnisotropicLighting等类名可见关键扩展特性已启用,兼容x64架构,经多次编译验证。目前已有38人学习下载,适合三维GIS、仿真可视化与虚拟训练等桌面应用开发者快速搭建环境、对照示例验证链接配置,降低环境搭建与排错成本。
1. 为什么 Win10 下编译 OSG + OSGEarth 这件事值得你花一个下午
如果你在 Windows 上做三维地理可视化,大概率绕不开 OSG 和 OSGEarth 这套组合。OSG 负责底层渲染,OSGEarth 在它之上封装了地形、影像、矢量图层和坐标投影,两者版本必须严格对齐,差一个小版本就可能链接报错。而官方并不提供 Windows 下 VS2019 的预编译包,网上流传的要么是 VS2015 时代的旧库,要么是只编了 Release 没有 Debug 的半成品。结果就是:你拿到一个示例工程,Release 能跑,Debug 一启动就崩,或者反过来,调试时断点根本进不去。这篇笔记要讲的,就是怎么在 Win10 + VS2019 环境下,把 OSG 3.6.5 和 OSGEarth 3.1 完整编译出来,并且同时产出 Release 和 Debug 两套目录结构,让两种配置都能正常链接、正常调试。适合已经会写 C++、用过 CMake、但被第三方库编译折磨过的同学。下面按依赖准备、编译配置、目录组织、避坑、进阶验证的顺序展开,每一步都给出可复现的命令和参数。
2. 编译前的依赖准备:从零把第三方库凑齐
2.1 为什么 OSG 3.6.5 的依赖不能随便下
OSG 本身依赖一堆第三方库:zlib、libpng、libjpeg、libtiff、freetype、curl、GDAL、Proj 等。很多人图省事,直接从网上找现成的二进制包,结果编译时 CMake 找得到头文件却链接不上,或者运行时报缺少 DLL。根本原因是这些预编译包的编译器版本、运行库选项(/MT 还是 /MD)、字符集(Unicode 还是多字节)跟你当前工程不一致。我一般会统一用 vcpkg 来管理这些依赖,因为 vcpkg 能保证所有库用同一套工具链编译,并且自动处理依赖传递。如果你不想用 vcpkg,那就得手动下载源码,用同一个 VS2019 逐个编译,工作量翻倍且容易出错。
2.2 用 vcpkg 安装依赖的完整命令
先准备一个干净的目录,比如D:\dev,然后克隆 vcpkg 并引导:
git clone https://github.com/microsoft/vcpkg.git D:\dev\vcpkg cd D:\dev\vcpkg .\bootstrap-vcpkg.bat接着安装 OSG 和 OSGEarth 需要的依赖。注意这里要指定 triplet 为x64-windows,因为现在基本没人用 32 位了。如果你需要静态库,把 triplet 换成x64-windows-static,但 OSGEarth 官方更推荐动态库,所以下面以动态库为例:
.\vcpkg install zlib:x64-windows libpng:x64-windows libjpeg-turbo:x64-windows libtiff:x64-windows freetype:x64-windows curl:x64-windows gdal:x64-windows proj:x64-windows sqlite3:x64-windows这里有几个参数要解释:zlib是压缩库,OSG 读写 osgb 文件时用到;libpng、libjpeg-turbo、libtiff分别处理不同格式的纹理;freetype用于文字渲染;curl用于网络加载;gdal和proj是 OSGEarth 处理地理数据必须的,sqlite3则是 GDAL 的依赖。安装完成后,vcpkg 会把头文件和库放在D:\dev\vcpkg\installed\x64-windows下,后面 CMake 配置时要指向这个路径。
提示:vcpkg 安装 GDAL 比较慢,因为会连带编译很多依赖,建议先泡杯茶。如果中途失败,删掉
buildtrees目录重来,不要反复重试。
2.3 检查依赖是否齐全
装完后,用下面的命令确认关键库都存在:
dir D:\dev\vcpkg\installed\x64-windows\lib\*.lib你应该能看到zlib.lib、libpng16.lib、freetype.lib、gdal.lib、proj.lib等。如果缺了某个,说明安装时出错了,需要单独重装。另外,OSGEarth 3.1 对 GDAL 版本有要求,太新的 GDAL 可能 API 不兼容,vcpkg 默认拉的是较新的版本,如果编译 OSGEarth 时报 GDAL 相关错误,可以尝试指定旧版 GDAL,比如gdal[core]:x64-windows并加上版本约束,但 vcpkg 的版本控制比较麻烦,更稳妥的做法是手动编译一个 GDAL 2.x。不过根据我的经验,OSGEarth 3.1 配合 GDAL 3.x 也能编过,只是个别函数需要打补丁,后面避坑章节会讲。
3. 编译 OSG 3.6.5:CMake 参数与 Release/Debug 双目录
3.1 获取源码与目录规划
从 OSG 的官方仓库下载 3.6.5 版本的源码包,解压到D:\dev\osg-3.6.5。不要用 git clone 最新代码,因为最新代码可能已经到 3.7 了,版本对不上。目录结构建议这样规划:
D:\dev\ ├── osg-3.6.5\ # 源码 ├── osg-build\ # 编译中间目录 │ ├── release\ # Release 配置 │ └── debug\ # Debug 配置 ├── osg-install\ # 安装目录 │ ├── release\ # Release 库和头文件 │ └── debug\ # Debug 库和头文件 └── vcpkg\ # 依赖这样分开的好处是,Release 和 Debug 的库不会混在一起,工程里切换配置时只需要改库目录,不会出现链接到错误版本的问题。
3.2 Release 版本的 CMake 配置命令
打开 CMake GUI 或者直接用命令行。我习惯用命令行,因为参数可以保存成脚本。先创建 release 构建目录:
mkdir D:\dev\osg-build\release cd D:\dev\osg-build\release cmake D:\dev\osg-3.6.5 ^ -G "Visual Studio 16 2019" ^ -A x64 ^ -DCMAKE_INSTALL_PREFIX=D:\dev\osg-install\release ^ -DCMAKE_TOOLCHAIN_FILE=D:\dev\vcpkg\scripts\buildsystems\vcpkg.cmake ^ -DVCPKG_TARGET_TRIPLET=x64-windows ^ -DCMAKE_BUILD_TYPE=Release ^ -DBUILD_OSG_APPLICATIONS=ON ^ -DBUILD_OSG_EXAMPLES=ON ^ -DOSG_USE_UTF8=ON参数逐个说明:-G指定 VS2019 生成器;-A x64指定 64 位;CMAKE_INSTALL_PREFIX是安装路径;CMAKE_TOOLCHAIN_FILE让 CMake 自动找到 vcpkg 的库;VCPKG_TARGET_TRIPLET必须和安装依赖时一致;CMAKE_BUILD_TYPE在 VS 生成器下其实不生效,但写上没坏处;BUILD_OSG_APPLICATIONS和BUILD_OSG_EXAMPLES建议打开,方便后面验证;OSG_USE_UTF8开启 UTF-8 支持,避免中文路径乱码。
配置完成后,执行编译和安装:
cmake --build . --config Release --target INSTALL这一步会编译所有 OSG 核心库和插件,时间大概 20 到 40 分钟,取决于机器性能。编译完成后,D:\dev\osg-install\release下会出现include、lib、bin三个目录。
3.3 Debug 版本的 CMake 配置与编译
Debug 版本不能和 Release 共用构建目录,必须另建一个。步骤类似,只是路径和配置不同:
mkdir D:\dev\osg-build\debug cd D:\dev\osg-build\debug cmake D:\dev\osg-3.6.5 ^ -G "Visual Studio 16 2019" ^ -A x64 ^ -DCMAKE_INSTALL_PREFIX=D:\dev\osg-install\debug ^ -DCMAKE_TOOLCHAIN_FILE=D:\dev\vcpkg\scripts\buildsystems\vcpkg.cmake ^ -DVCPKG_TARGET_TRIPLET=x64-windows ^ -DCMAKE_BUILD_TYPE=Debug ^ -DBUILD_OSG_APPLICATIONS=ON ^ -DBUILD_OSG_EXAMPLES=ON ^ -DOSG_USE_UTF8=ON然后编译安装:
cmake --build . --config Debug --target INSTALLDebug 版本的库文件名通常带d后缀,比如osgdbd.lib,这样链接时不会和 Release 混淆。安装完成后,D:\dev\osg-install\debug下同样有完整的目录结构。
注意:vcpkg 安装的依赖库默认只有 Release 版本,Debug 版本需要额外安装
x64-windows的 debug 变体。实际上 vcpkg 在安装时会同时生成 release 和 debug 两套,但需要确认installed\x64-windows\debug\lib下是否有对应的*d.lib。如果没有,需要重新运行vcpkg install并加上--triplet x64-windows的 debug 选项,或者直接用vcpkg install zlib:x64-windows --debug这种形式。更简单的办法是安装时加上--recurse并确保没有跳过 debug。
4. 编译 OSGEarth 3.1:链接 OSG 与处理 GDAL 兼容性
4.1 OSGEarth 3.1 的源码获取与 CMake 关键变量
OSGEarth 3.1 的源码需要和 OSG 3.6.5 配套。下载后解压到D:\dev\osgearth-3.1。编译前要确保 CMake 能找到刚才安装的 OSG。关键变量是OSG_DIR,指向 OSG 的安装目录下的lib\cmake\osg或者直接指向安装根目录。我一般这样配置 Release 版本:
mkdir D:\dev\osgearth-build\release cd D:\dev\osgearth-build\release cmake D:\dev\osgearth-3.1 ^ -G "Visual Studio 16 2019" ^ -A x64 ^ -DCMAKE_INSTALL_PREFIX=D:\dev\osgearth-install\release ^ -DCMAKE_TOOLCHAIN_FILE=D:\dev\vcpkg\scripts\buildsystems\vcpkg.cmake ^ -DVCPKG_TARGET_TRIPLET=x64-windows ^ -DCMAKE_BUILD_TYPE=Release ^ -DOSG_DIR=D:\dev\osg-install\release ^ -DGEOJSON_LIBRARY=ON ^ -DBUILD_OSGEARTH_EXAMPLES=ON这里OSG_DIR必须指向 Release 版本的 OSG 安装目录,否则会链接到 Debug 库导致冲突。GEOJSON_LIBRARY开启 GeoJSON 支持,BUILD_OSGEARTH_EXAMPLES打开示例,方便验证。
4.2 处理 GDAL 版本不兼容的补丁
OSGEarth 3.1 的代码里有些地方调用了 GDAL 的旧 API,而 vcpkg 安装的 GDAL 可能是 3.4 以上,会报GDALAllRegister未定义或者OGRRegisterAll参数不匹配。常见的错误是error C2039: "OGRRegisterAll": 不是 "OGR" 的成员。解决办法是手动修改源码。找到src/osgEarth/GDALSource.cpp,把OGRRegisterAll()改成GDALAllRegister(),因为新版 GDAL 把 OGR 的注册合并到了 GDAL 里。另外,如果报CPLSetConfigOption相关错误,检查是否包含了cpl_conv.h。这些补丁不多,但必须打,否则编译不过。
4.3 编译安装与 Debug 版本
Release 编译命令:
cmake --build . --config Release --target INSTALLDebug 版本类似,但OSG_DIR要指向D:\dev\osg-install\debug,安装路径也换成D:\dev\osgearth-install\debug。注意 Debug 版本的 OSGEarth 库文件名也会带d后缀,比如osgEarthd.lib。编译完成后,检查bin目录下是否有osgEarth.dll和osgEarthd.dll,以及对应的插件 DLL。
提示:OSGEarth 编译时如果报找不到
osgEarth::Symbology之类的错误,多半是 OSG 的 Debug 库没有正确安装,回头检查D:\dev\osg-install\debug\lib下是否有osgd.lib等文件。
5. 避坑与常见问题:血泪经验五条
5.1 链接时报 LNK2038 或 RuntimeLibrary 不匹配
现象:编译自己的工程时,链接器报LNK2038: 检测到"RuntimeLibrary"的不匹配: 值"MDd_DynamicDebug"与"MTd_StaticDebug"不匹配。原因:OSG 或 OSGEarth 编译时用的运行库选项和你工程的不一致。vcpkg 默认用动态运行库(/MD),如果你的工程设成了 /MT,就会冲突。解决:在 VS 里把工程的 C/C++ -> 代码生成 -> 运行库改成“多线程调试 DLL (/MDd)”对应 Debug,“多线程 DLL (/MD)”对应 Release。如果必须用 /MT,那就得重新编译所有依赖,用x64-windows-statictriplet。
5.2 Debug 版本启动崩溃,Release 正常
现象:用 Debug 配置运行程序,一启动就崩,报缺少osgDBd.dll或者osgEarthd.dll。原因:系统 PATH 里只有 Release 的 DLL,或者拷贝 DLL 时只拷了 Release 版。解决:把D:\dev\osg-install\debug\bin和D:\dev\osgearth-install\debug\bin加到 PATH 最前面,或者把 Debug 的 DLL 拷贝到 exe 同目录。注意 Debug 和 Release 的 DLL 不能混用,文件名带 d 的必须对应 Debug 配置。
5.3 CMake 找不到 OSG,报 Could NOT find OSG
现象:配置 OSGEarth 时,CMake 输出Could NOT find OSG。原因:OSG_DIR没设对,或者 OSG 安装目录下缺少osg-config.cmake。解决:确认D:\dev\osg-install\release\lib\cmake\osg下是否有osg-config.cmake。如果没有,说明 OSG 安装时没有生成 CMake 配置文件,需要重新编译 OSG 并确保CMAKE_INSTALL_PREFIX正确。另外,OSG_DIR应该指向包含lib和include的根目录,而不是lib子目录。
5.4 运行时提示“无法定位程序输入点”于某个 DLL
现象:运行示例程序时,弹窗提示无法定位程序输入点 xxx 于动态链接库 osgDB.dll 上。原因:DLL 版本不匹配,比如用 Release 的 exe 加载了 Debug 的 DLL,或者 OSG 和 OSGEarth 的版本不对应。解决:用 Dependency Walker 或dumpbin /dependents检查 exe 依赖的 DLL,确保所有 DLL 都来自同一套安装目录。特别要注意,OSGEarth 的 DLL 必须和 OSG 的 DLL 版本严格一致,不能混用不同时间编译的产物。
5.5 中文路径导致读取文件失败
现象:加载包含中文路径的模型或影像时,OSG 报Could not find plugin to read或者直接崩溃。原因:OSG 默认使用本地编码,而 Windows 中文系统是 GBK,如果路径是 UTF-8 就会乱码。解决:编译时加上-DOSG_USE_UTF8=ON,并且在代码里用osgDB::convertStringFromCurrentCodePageToUTF8转换路径。另外,尽量把资源放在纯英文路径下,这是最省事的做法。
6. 验证双版本库是否可用:一个最小加载示例与进阶技巧
编译完成后,怎么确认两套库都能正常工作?我一般写一个最小的 OSGEarth 示例,加载一个简单的 earth 文件,然后分别用 Release 和 Debug 编译运行。示例代码:
#include <osgViewer/Viewer> #include <osgEarth/MapNode> #include <osgEarth/EarthManipulator> #include <osgDB/ReadFile> int main(int argc, char** argv) { osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer; // 加载 earth 文件,这里假设当前目录下有 simple.earth osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("simple.earth"); if (!node) return -1; viewer->setSceneData(node); viewer->setCameraManipulator(new osgEarth::Util::EarthManipulator); return viewer->run(); }对应的simple.earth文件内容:
<map name="test"> <options> <profile>global-geodetic</profile> </options> <image name="world" driver="gdal"> <url>world.tif</url> </image> </map>把world.tif换成任意一张全球影像。编译时,Release 配置链接osgEarth.lib、osg.lib等,Debug 配置链接osgEarthd.lib、osgd.lib。运行前确保 PATH 包含对应版本的 bin 目录。如果窗口能正常显示地球,说明双版本库都可用。
进阶技巧:如果你需要把这两套库集成到自己的工程里,建议在 VS 里建两个属性表(Property Sheet),一个叫OSG_Release.props,一个叫OSG_Debug.props,分别设置包含目录、库目录和依赖项。然后在工程里根据配置自动导入对应的属性表。这样切换配置时不用手动改路径,减少出错。另外,OSGEarth 的插件 DLL 很多,部署时可以用windeployqt类似的工具,但 OSG 没有官方工具,我一般写个批处理脚本,把bin目录下所有 DLL 拷贝到输出目录,再根据配置筛选带 d 和不带 d 的。这个脚本我用了三年,比手动拷贝靠谱得多。
最后说一个我踩过的坑:有一次我为了省空间,把 Release 和 Debug 的安装目录合并成一个,结果 CMake 生成的配置里同时包含了两种库的路径,链接时随机选一个,导致程序时而正常时而崩溃,查了两天才发现是目录混用。从那以后,我坚持 Release 和 Debug 完全隔离,连头文件都分开存放。希望帮到你。
本文还有配套的精品资源,点击获取