简介:本资源为基于Visual Studio 2019预编译的OSG3.6.5与OSGEarth 2.10配套第三方库,面向从事三维地理可视化、虚拟仿真与数字地球开发的中高级C++工程师,解决自行编译第三方依赖耗时长、易报错的问题。压缩包共约2000个文件,整体137.76MB,以1351个h头文件、56个lib静态库、32个cmake配置、28个inc及22个c源文件为主,另含少量dll、hpp、proto等,覆盖头文件声明、库文件链接与构建脚本,可直接接入VS2019的64位工程。目录中附带大量时区与地名数据文件,便于地理坐标与时间处理。目前已有626人学习下载,适合需要快速搭建OSG与OSGEarth开发环境、专注业务逻辑而非依赖编译的开发者参考使用。
1. 为什么我建议你直接用这份 OSG 3.6.5 + OSGEarth 预编译 3rdParty
如果你在 Windows 上从源码编译过 OSG,大概率经历过这样的夜晚:CMake 配置到一半,突然告诉你找不到 zlib;好不容易把 zlib 编过,libpng 又报链接错误;等 PNG 搞定,GDAL 和 PROJ 的依赖链又把你拖进下一个坑。更别提 OSGEarth 还要额外依赖 curl、sqlite3、protobuf 这一串东西。这套 3rdParty.zip 就是来解决这个问题的——它把 OSG 3.6.5 和 OSGEarth 在 VS2019 工具链下需要的第三方库全部预编译好了,解压就能用,省掉你至少一整天的编译折腾。
这份资源适合两类人:一是刚接触 OSG/OSGEarth、想快速跑通第一个三维地球 Demo 的新手;二是已经熟悉 OSG、但不想在依赖库上反复消耗时间的老手。它不包含 OSG 和 OSGEarth 本身的源码,只提供第三方依赖库,你需要自己下载 OSG 3.6.5 和 OSGEarth 的源码来配合使用。下面我会把整个流程拆开讲清楚,包括目录结构、CMake 参数怎么配、编译时容易翻车的地方,以及怎么验证你编出来的东西真的能用。
2. 拆开这个压缩包:目录结构与版本匹配逻辑
2.1 3rdParty 里到底装了什么
解压之后你会看到一个典型的 3rdParty 目录树,结构大致是这样的:
3rdParty/ ├── bin/ # 运行时 DLL │ ├── zlib.dll │ ├── libpng16.dll │ ├── jpeg62.dll │ ├── tiff.dll │ ├── gdal.dll │ ├── proj.dll │ ├── curl.dll │ ├── sqlite3.dll │ ├── protobuf.dll │ └── ... ├── include/ # 头文件 │ ├── zlib.h │ ├── png.h │ ├── gdal/ │ ├── proj/ │ └── ... ├── lib/ # 导入库 .lib │ ├── zlib.lib │ ├── libpng16.lib │ ├── gdal_i.lib │ └── ... └── share/ # 数据文件 ├── proj/ └── gdal/这个结构是 OSG 社区约定俗成的布局,CMake 在找依赖时会按include、lib、bin三个子目录去搜索。你不需要手动改任何路径,只要在 CMake 里把CMAKE_PREFIX_PATH指向这个 3rdParty 的根目录就行。
关键要确认的是版本匹配。OSG 3.6.5 对第三方库的版本有明确要求,比如 libpng 需要 1.6.x、zlib 需要 1.2.x、GDAL 通常是 2.x 或 3.x 的某个稳定版。这份预编译包已经按 OSG 3.6.5 的FindXXX.cmake模块要求做好了版本对齐,你直接拿来用不会出现「头文件版本和库版本不一致」的玄学问题。
2.2 为什么版本匹配比你想的重要
很多人觉得第三方库嘛,随便下个最新版就行。但在 OSG 这个生态里,版本不匹配会导致非常隐蔽的运行时崩溃。举个例子:GDAL 2.x 和 3.x 的 ABI 不兼容,如果你用 GDAL 3.x 的头文件编译 OSGEarth,但链接的是 GDAL 2.x 的库,编译能过,运行时一加载地理数据就崩,而且崩的位置往往在 GDAL 内部,堆栈信息完全看不出是版本问题。
再比如 PROJ 库,从 5.x 到 6.x 经历了一次大的 API 重构,坐标转换的接口完全变了。OSG 3.6.5 的某些版本对 PROJ 的调用方式是按 5.x 写的,如果你混用了 6.x 的库,编译阶段就会报一堆未定义符号。这份 3rdParty 包的价值就在于,它已经帮你把所有这些版本约束都验证过了,你不需要再去逐个排查。
提示:如果你手头已经有其他项目在用的 3rdParty 目录,不要直接混用。不同项目对同一库的版本要求可能不同,混用会导致链接冲突。
2.3 和源码编译方式对比:省了多少事
从源码编译一套完整的 OSG 3.6.5 + OSGEarth 依赖链,大致需要以下步骤:
| 依赖库 | 源码编译耗时(约) | 常见问题 |
|---|---|---|
| zlib | 5 分钟 | 基本无坑 |
| libpng | 10 分钟 | 需要先编 zlib |
| libjpeg | 10 分钟 | 版本选择困惑 |
| libtiff | 15 分钟 | 依赖 zlib + jpeg |
| GDAL | 40 分钟 | 依赖链极长,PROJ、sqlite3、curl 都要先编 |
| PROJ | 20 分钟 | 数据文件路径配置易错 |
| curl | 15 分钟 | SSL 后端选择 |
| sqlite3 | 5 分钟 | 基本无坑 |
| protobuf | 30 分钟 | 需要匹配编译器版本 |
合计至少 2.5 小时,这还不算中间出错重来的时间。用预编译包,解压 2 分钟,配置 CMake 5 分钟,直接进入 OSG 本身的编译。对于只是想快速验证功能或者做原型开发的人来说,这个时间差是决定性的。
3. 从零跑通:CMake 配置与 VS2019 编译全流程
3.1 准备工作:源码下载与目录规划
你需要准备三样东西:
- 这份 3rdParty.zip,解压到某个路径,比如
D:\dev\3rdParty - OSG 3.6.5 源码,从官方渠道获取,解压到
D:\dev\OpenSceneGraph-3.6.5 - OSGEarth 源码,版本要与 OSG 3.6.5 兼容,解压到
D:\dev\osgearth
目录规划建议保持平级,不要嵌套太深,否则 Windows 的路径长度限制(260 字符)可能在编译后期找麻烦。我一般会在 D 盘根目录下建一个dev文件夹,把所有相关的东西都放进去。
# 推荐的目录结构 D:\dev\ ├── 3rdParty\ # 解压后的第三方库 ├── OpenSceneGraph-3.6.5\ # OSG 源码 ├── osgearth\ # OSGEarth 源码 ├── build-osg\ # OSG 编译输出目录 └── build-osgearth\ # OSGEarth 编译输出目录把编译输出目录和源码目录分开,这是 CMake 的 out-of-source 构建习惯。好处是源码目录保持干净,编译失败想重来时直接删掉 build 目录就行,不用重新解压源码。
3.2 CMake 配置 OSG:关键参数逐个说
打开 CMake GUI,设置源码路径为D:/dev/OpenSceneGraph-3.6.5,构建路径为D:/dev/build-osg。点击 Configure,选择 Visual Studio 2019 作为生成器,平台选 x64。
第一次 Configure 会报一堆红字,提示找不到各种依赖。这时候需要设置以下关键变量:
# 在 CMake GUI 中添加这些条目,或者直接在 CMakeLists.txt 中设置 CMAKE_PREFIX_PATH = D:/dev/3rdParty CMAKE_INSTALL_PREFIX = D:/dev/osg-install BUILD_OSG_EXAMPLES = ON BUILD_OSG_APPLICATIONS = ONCMAKE_PREFIX_PATH是最关键的,它告诉 CMake 去 3rdParty 目录下找所有依赖。设置好之后再次 Configure,之前找不到的 zlib、libpng、GDAL 等应该都能自动定位到。
如果某些库仍然显示 NOTFOUND,检查一下 3rdParty 的目录结构是否完整。常见情况是lib目录下缺少对应的.lib文件,或者include目录下头文件路径多了一层嵌套。比如有些打包方式会把头文件放在include/gdal/gdal.h,而 CMake 期望的是include/gdal.h,这种就需要手动调整。
Configure 通过后,点击 Generate,然后在 build-osg 目录下打开生成的OpenSceneGraph.sln,选择 Release 配置,右键 ALL_BUILD 进行编译。编译完成后,再对 INSTALL 项目执行一次编译,把产物安装到CMAKE_INSTALL_PREFIX指定的目录。
3.3 CMake 配置 OSGEarth:额外依赖的处理
OSGEarth 的配置流程类似,但有几个额外的注意点:
CMAKE_PREFIX_PATH = D:/dev/3rdParty;D:/dev/osg-install OSG_DIR = D:/dev/osg-install/lib/cmake/OpenSceneGraph BUILD_OSGEARTH_EXAMPLES = ON注意CMAKE_PREFIX_PATH这里用了分号分隔两个路径:一个是 3rdParty,一个是 OSG 的安装目录。因为 OSGEarth 既要找第三方库,也要找 OSG 本身的库和头文件。
OSG_DIR指向 OSG 安装目录下的 CMake 配置文件夹,这样 OSGEarth 就能通过find_package(OpenSceneGraph)正确找到 OSG 的版本信息。
OSGEarth 编译过程中最容易出问题的是 GDAL 和 PROJ 的链接。如果编译时报unresolved external symbol相关的错误,大概率是 3rdParty 里的 GDAL 库和 OSGEarth 期望的版本有差异。这时候可以检查CMakeCache.txt里GDAL_LIBRARY和GDAL_INCLUDE_DIR的值,确认指向的是 3rdParty 里的路径。
编译完成后同样执行 INSTALL,把 OSGEarth 的库和头文件安装到指定位置。
3.4 环境变量与运行时 DLL 配置
编译成功只是第一步,运行时还需要确保 DLL 能被找到。把以下路径添加到系统 PATH 环境变量中:
D:\dev\3rdParty\bin D:\dev\osg-install\bin D:\dev\osgearth-install\bin或者,如果你不想改系统环境变量,可以把这些 DLL 复制到你的可执行文件同级目录下。我一般倾向于后者,因为不同项目可能依赖不同版本的库,放在一起容易冲突。
验证 OSG 是否正常,可以运行osgversion.exe,应该输出类似OpenSceneGraph Library 3.6.5的信息。验证 OSGEarth,可以运行osgearth_version.exe,确认版本号和编译日期。
4. 避坑指南:编译和运行中最容易翻车的五个地方
4.1 现象:CMake 找到了库但链接时报 LNK2019
原因:头文件版本和库文件版本不一致。最常见的情况是 3rdParty 里的某个库被系统 PATH 中另一个版本的库抢先加载了。
解决:在 CMake 中显式指定每个库的路径,不要依赖自动搜索。比如设置ZLIB_LIBRARY、PNG_LIBRARY等变量,直接指向 3rdParty 下的具体文件。同时检查系统 PATH,把可能冲突的路径移除。
4.2 现象:编译通过,运行时提示缺少 xxx.dll
原因:3rdParty 的 bin 目录没有加入 PATH,或者编译出的 exe 没有和 DLL 放在同一目录。
解决:用 Dependency Walker 或dumpbin /dependents检查 exe 依赖哪些 DLL,然后确保这些 DLL 在搜索路径中。最稳妥的方式是把所有需要的 DLL 复制到 exe 同级目录。
4.3 现象:OSGEarth 加载 .earth 文件时崩溃,堆栈指向 GDAL
原因:GDAL 的数据文件路径没有正确配置。GDAL 需要gdal-data目录下的坐标系统定义文件才能正常工作。
解决:设置GDAL_DATA环境变量指向 3rdParty 下的share/gdal目录。同样,PROJ 需要PROJ_LIB指向share/proj。
set GDAL_DATA=D:\dev\3rdParty\share\gdal set PROJ_LIB=D:\dev\3rdParty\share\proj4.4 现象:Debug 配置编译失败,Release 正常
原因:3rdParty 里通常只包含 Release 版本的库。OSG 的 CMake 在 Debug 模式下会尝试链接xxxd.lib,但 3rdParty 里没有这些文件。
解决:统一使用 Release 配置编译和运行。如果确实需要 Debug 版本,需要自己从源码编译 Debug 版的第三方库,或者修改 CMake 配置让 Debug 模式也链接 Release 库(不推荐,可能导致运行时 CRT 冲突)。
4.5 现象:编译到 90% 时报内存不足或编译器崩溃
原因:OSG 和 OSGEarth 的某些源文件非常大,VS2019 在编译这些文件时会消耗大量内存。如果同时开了多个编译任务,容易触发资源瓶颈。
解决:在 VS 中减少并行编译的项目数。工具 → 选项 → 项目和解决方案 → 生成并运行 → 最大并行项目生成数,改为 1 或 2。另外确保系统有足够的虚拟内存。
5. 验证与进阶:确认你的 OSG 真的能跑起来
5.1 用最小示例验证编译结果
编译完成后,不要急着跑复杂的 OSGEarth 示例。先写一个最小的 OSG 程序,确认基本的渲染管线是通的:
#include <osgViewer/Viewer> #include <osg/Geode> #include <osg/ShapeDrawable> int main() { // 创建一个简单的球体 osg::ref_ptr<osg::ShapeDrawable> sphere = new osg::ShapeDrawable( new osg::Sphere(osg::Vec3(0.0f, 0.0f, 0.0f), 1.0f)); osg::ref_ptr<osg::Geode> geode = new osg::Geode(); geode->addDrawable(sphere); osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer(); viewer->setSceneData(geode); return viewer->run(); }这段代码创建了一个球体并显示在窗口中。如果能正常看到球体,说明 OSG 的核心库、渲染后端、窗口系统集成都没问题。如果报错,根据错误信息定位是哪个库缺失。
5.2 用 OSGEarth 加载在线地图验证完整链路
OSG 跑通后,再验证 OSGEarth。创建一个简单的.earth文件:
<map name="test"> <image name="world" driver="gdal"> <url>D:/data/world.tif</url> </image> <elevation name="srtm" driver="gdal"> <url>D:/data/srtm.tif</url> </elevation> </map>用osgearth_viewer.exe test.earth加载。如果能正常显示地形和影像,说明 GDAL、PROJ、curl 等依赖全部工作正常。如果加载在线地图(比如 TMS 服务),还能验证 curl 和网络模块是否正常。
5.3 性能调优的几个参数
当你的场景变得复杂时,可能需要调整一些参数来平衡性能和效果:
| 参数 | 作用 | 建议值 |
|---|---|---|
OSG_NOTIFY_LEVEL | 控制日志输出级别 | WARN |
OSG_MAX_TEXTURE_SIZE | 限制纹理最大尺寸 | 根据显卡调整 |
OSGEARTH_CACHE_POLICY | 缓存策略 | 根据磁盘空间选择 |
OSG_USE_VBO | 是否使用 VBO | ON |
这些可以通过环境变量设置,也可以在代码中通过osg::DisplaySettings配置。
5.4 我踩过的一个坑
有一次帮同事排查一个 OSGEarth 崩溃问题,现象是加载特定区域的影像时必崩,换其他区域就正常。查了两天,最后发现是 3rdParty 里的 libtiff 版本和 GDAL 编译时用的版本不一致,导致读取某些压缩格式的 TIFF 文件时内存越界。换成配套的 libtiff 后问题消失。从那以后我每次拿到新的 3rdParty 包,都会先用dumpbin /dependents检查一遍所有 DLL 的依赖关系,确认没有混入系统路径下的其他版本。这个习惯帮我省了很多事后排查的时间。
希望这份笔记能帮你顺利跑通 OSG 3.6.5 和 OSGEarth 的环境。如果你在配置过程中遇到其他问题,欢迎一起交流。
本文还有配套的精品资源,点击获取