☰
VS2019下OSG 3.6.5与osgEarth三方库配置与编译
2026/10/28 19:15:26 网站建设 项目流程

简介:面向使用 Visual Studio 2019 开发 OSG3.6.5 与 OSGEarth2.10 三维地球应用的 C++ 开发者,这套预编译 64 位第三方库用于减少逐项编译依赖、处理链接错误和配置环境的时间,适合需要快速建立可编译工程的中级学习者。压缩包约 2000 个文件、整体 137.76MB,以 1351 个头文件、56 个静态库和 4 个动态库为主,并配有 cmake 配置、inc 模块文件及少量 C/C++ 源码与辅助页面,覆盖声明、链接库和构建配置等环节。目前已有 626 人学习下载。包内依赖按模块整理,读者可在 VS2019 工程中直接引用头文件与库目录,用于复现编译环境、定位第三方库缺失、核对库文件结构,也能作为整理本地依赖与排查版本不匹配问题的参考。

1. 别急着运行 CMake:先搞清 3rdParty.zip 里装的是什么

在 VS2019 上编译 OSG 3.6.5,真正卡住的往往不是引擎本身,而是那二十几个第三方库:zlib、libpng、libjpeg、libtiff、freetype、curl、GDAL、PROJ、sqlite3、expat、libxml2 等等。每个库都自己编译一遍,配置一次或两次就能花掉一整天,版本之间还互相冲突。这份预编译好的 3rdParty.zip 解决的正是这件事:它按 VS2019 的 v142 工具集和 x64 位,把 OSG 3.6.5 与 OSGEarth 需要的三方库编译好了,include、lib、bin 成套提供,你只需要在 CMake 里把路径指过去。它适合两类人:一是想跳过依赖编译问题、直接生成引擎的;二是已经编译失败过一次、需要一份版本能对得上的参照物,来反查自己哪里配置错了。

2. 拆包先看三层目录:工具集标签、位数与 CMake 变量的对应关系

2.1 解压后先确认三件事

拿到手的包,目录组织常见两种形态。一种是平铺的,顶层直接就是include、lib、bin三个目录;另一种按工具集和平台分了层,形如x64/v142/include、x64/v142/lib。这两种布局决定了你后面CMAKE_PREFIX_PATH到底该指到哪一层,指错一级,CMake 就会安静地少找到一半库,最后表现为插件被跳过,而不是报错。

先花两分钟确认目录,不要省略:

# 1) 看顶层结构:include / lib / bin 是否成套,还是按工具集分了层 Get-ChildItem D:\OSG\3rdParty | Select-Object Name, Mode # 2) 往下探两层,确认 v142 这一级在哪(v142 对应 VS2019,v143 对应 VS2022) Get-ChildItem D:\OSG\3rdParty -Directory -Recurse -Depth 2 | Select-Object FullName # 3) 抽查关键头文件是否齐全,缺哪个后面就会缺哪个插件 "zlib.h","png.h","jpeglib.h","tiffio.h","ft2build.h","gdal.h","proj.h","sqlite3.h","curl/curl.h" | ForEach-Object { [pscustomobject]@{ Header = $_; Exists = Test-Path "D:\OSG\3rdParty\x64\v142\include\$_" } }

第三段里的Test-Path路径按你实际层级改。这一步的价值在于:OSG 的 CMake 在找不到某个依赖时,默认行为是把这个依赖对应的功能关掉,然后继续编译。也就是说,你可能得到一份“编译成功但缺 gdal 驱动、缺 curl 插件”的产物,等到运行时加载 .earth 文件才报错。提前查一遍头文件,比事后排查省事得多。

接着看lib目录里的文件名。这里要注意 Debug 和 Release 是分开放的还是同名的。常见的三种情况:只有 Release 库(文件名不带后缀);Release 和 Debug 分两个子目录(lib和lib/debug);或者 Debug 库带d后缀(zlibd.lib、libpng16d.lib)。这一点直接决定你后面能不能同时生成 Debug 和 Release 两套,也是第五章第一个问题会涉及的根源。

2.2 OSG 的 CMake 在 Windows 上是怎么找这些库的

OSG 源码根目录下有个CMakeModules目录,里面是一批FindXXX.cmake,比如 FindZLIB、FindPNG、FindJPEG、FindTIFF、FindFreetype、FindCURL、FindGDAL、FindSqlite3、FindEXPAT、FindLibXml2。这些脚本在 Windows 上遵循 CMake 的标准查找顺序:先看缓存变量有没有被手动指定,再看CMAKE_PREFIX_PATH,最后才在系统默认路径里查找。

关键在于查找规则:find_path会在候选前缀下拼/include,find_library会拼/lib。所以只要把CMAKE_PREFIX_PATH指向同时含include和lib的那一层父目录,大部分依赖就能被自动找到。

提示:CMAKE_PREFIX_PATH要指到这两个目录的父目录,不要指到include或者lib本身。指错了不会报“路径不存在”,只会找不到,排查起来很费时间。

另外,部分版本的 OSG 在 CMakeLists 里还会认一个ACTUAL_3RDPARTY_DIR缓存项,作用是一次性把所有依赖的搜索根目录换掉。你可以在 OSG 源码根目录搜一下这个名字:

Select-String -Path D:\OSG\src\OpenSceneGraph-3.6.5\CMakeLists.txt -Pattern "3RDPARTY_DIR"

搜得到就顺手传,搜不到就老老实实用CMAKE_PREFIX_PATH加逐个变量指定,这两条路都能走通。

2.3 一张变量对照表,把路径固定下来

如果三方库目录层级规整,CMAKE_PREFIX_PATH一条就够了。但如果包里混了多个版本的同名库,或者某个库的头文件被放在奇怪的位置(GDAL 和 freetype 经常这样),就得逐个固定路径。下表是我常用的对应关系,变量名是 OSG 的 Find 模块实际读取的那几个:

依赖头文件变量库变量目录里常见的文件名
zlibZLIB_INCLUDE_DIRZLIB_LIBRARYzlib.lib或zlibstatic.lib
libpngPNG_PNG_INCLUDE_DIRPNG_LIBRARYlibpng16.lib
libjpegJPEG_INCLUDE_DIRJPEG_LIBRARYjpeg.lib、libjpeg.lib
libtiffTIFF_INCLUDE_DIRTIFF_LIBRARYlibtiff.lib、tiff.lib
freetypeFREETYPE_INCLUDE_DIRSFREETYPE_LIBRARYfreetype.lib
curlCURL_INCLUDE_DIRCURL_LIBRARYlibcurl.lib、libcurl_imp.lib
GDALGDAL_INCLUDE_DIRGDAL_LIBRARYgdal.lib
PROJPROJ_INCLUDE_DIRPROJ_LIBRARYproj.lib
sqlite3SQLITE3_INCLUDE_DIRSQLITE3_LIBRARYsqlite3.lib
expatEXPAT_INCLUDE_DIREXPAT_LIBRARYexpat.lib、libexpat.lib

对应的固定写法,可以把这一段放到一个单独的.cmake文件里,用-C预置进缓存,也可以直接拼进命令行。我用后者多一点,因为出问题时命令行就在历史记录里,不用再回头翻文件:

# 假设 TP 指向 x64/v142 这一层 set(TP "D:/OSG/3rdParty/x64/v142") set(ZLIB_INCLUDE_DIR "${TP}/include" CACHE PATH "zlib headers") set(ZLIB_LIBRARY "${TP}/lib/zlib.lib" CACHE FILEPATH "zlib import lib") set(PNG_PNG_INCLUDE_DIR "${TP}/include" CACHE PATH "libpng headers") set(PNG_LIBRARY "${TP}/lib/libpng16.lib" CACHE FILEPATH "libpng import lib") # 其余照抄,把 lib 文件名换成你目录里真实存在的那个,不要凭记忆写

文件名一定要按目录里实际存在的内容填写。三方库打包方式差异很大,同一个库在这份包里叫libcurl.lib,在另一份里可能叫libcurl_imp.lib,写错一个字符,CMake 就当成没找到。

3. 编译 OSG 3.6.5:从 CMake 配置到 install 产物的完整链路

3.1 源码、三方库、构建目录的摆放约定

目录结构如果不整理好,后面会出现两类很难查的问题:一是install目录被上一次失败构建的残渣污染,新产物和老产物混在一起;二是构建目录放在源码目录里,清理时删不干净。我的习惯是四个目录完全分开:

D:\OSG\ ├─ 3rdParty\ 预编译三方库,解压后不再改动 ├─ src\ │ ├─ OpenSceneGraph-3.6.5\ │ └─ osgEarth\ ├─ build\ │ ├─ osg365\ CMake 的二进制目录 │ └─ osgearth\ └─ install\ OSG 和 osgEarth 共用一个安装前缀

源码、构建、安装三者分离的好处很直接:--target INSTALL是覆盖写,install目录可以随时整个删掉重来,而源码和三方库保持原样;构建目录出问题删掉重建,代价只有一次 CMake 配置的时间。另外提醒一句,整条路径尽量全 ASCII、不要空格、不要太深。这不是迷信,第五章最后一节会讲为什么。

3.2 一份可直接抄的配置命令,逐行解释开关

VS2019 对应的生成器名是Visual Studio 16 2019,平台用-A x64指定。下面这条命令是我在 x64 环境下反复用过的版本:

cmake -S D:\OSG\src\OpenSceneGraph-3.6.5 -B D:\OSG\build\osg365 ` -G "Visual Studio 16 2019" -A x64 ` -DCMAKE_INSTALL_PREFIX=D:/OSG/install ` -DCMAKE_PREFIX_PATH="D:/OSG/3rdParty/x64/v142" ` -DBUILD_OSG_APPLICATIONS=ON ` -DBUILD_OSG_EXAMPLES=OFF ` -DBUILD_DOCUMENTATION=OFF ` -DDYNAMIC_OPENSCENEGRAPH=ON ` -DDYNAMIC_OPENTHREADS=ON ` -DOPENGL_PROFILE=GL3 ` -DCMAKE_DEBUG_POSTFIX=d

逐项说明一下为什么这么设:

CMAKE_INSTALL_PREFIX统一指向D:/OSG/install,是为了让后面 osgEarth 用find_package直接找到 OSG,不用再配第二套路径。CMAKE_PREFIX_PATH指到x64/v142这一层,理由在 2.2 说过。

DYNAMIC_OPENSCENEGRAPH和DYNAMIC_OPENTHREADS设成 ON 是生成 DLL 而不是静态库。写业务代码时这一点很关键:DLL 模式下插件(osgdb_png.dll这类)才有意义;静态链接时插件机制基本失效,读到非原生格式就报“找不到合适的读取器”。

OPENGL_PROFILE设GL3是给 osgEarth 3.x 用的。默认值一般是更老的配置,画能画出来,但某些着色器路径会退化,帧率也上不去,排查这类问题很容易变成无休止的调试过程。如果你只是纯粹跑 OSG 不做地球,保持默认也不是不行。

CMAKE_DEBUG_POSTFIX=d会让 Debug 版的库和 DLL 带d后缀,比如 Release 是osg.dll、Debug 是osgd.dll,插件同理。这个名字后面在第五章排查“插件加载不上”时还会遇到。

配置完成后,重点看 CMake 输出里那一段依赖汇总。正常情况你能看到逐行列出 zlib、png、jpeg、tiff、freetype、curl、gdal、sqlite 的“找到/未找到”。出现Could NOT find的项,先在 2.3 的表里固定对应变量,再重新配置。不要带着缺项往下编译,编译是通过了,运行时就要遇到问题。

3.3 编译、安装、产物自检

# 只编 Release,目标直接打 INSTALL,省一步手动拷贝 cmake --build D:\OSG\build\osg365 --config Release --target INSTALL -- /m:8

/m:8是传给 MSBuild 的并行度,按你的物理核数调整,一般设成核数或核数的一半。内存小的机器把并行度调低些,否则链接阶段容易因为内存不足出现莫名其妙的失败。

编译完成后不要直接开始写代码,先做一次产物盘点:

$root = "D:\OSG\install" "主 DLL 数量 : " + (Get-ChildItem "$root\bin" -Filter *.dll -File).Count "插件数量 : " + (Get-ChildItem "$root\bin\osgPlugins-3.6.5" -Filter *.dll -File).Count "导入库样例 :" Get-ChildItem "$root\lib" -Filter *.lib | Select-Object -First 8 Name "版本头文件 : " + (Test-Path "$root\include\osg\Version")

三个判断标准:bin下的主 DLL 应该有十几个以上(osg、osgDB、osgUtil、osgViewer、osgGA、osgText、osgSim 等各自一个);插件目录里的 DLL 通常有几十个,如果只有个位数,基本可以确定是三方库没找全,对应的读写插件被跳过编译了;include\osg\Version必须存在,缺了说明安装步骤根本没跑完,你拿到的是一个半成品。

4. 编译 OSGEarth:版本匹配、依赖裁剪与插件目录

4.1 osgEarth 与 OSG、GDAL、PROJ 之间的版本匹配

osgEarth 3.x 对 OSG 的主次版本是有硬性检查的,写在根目录的 CMakeLists 里。别凭印象判断,直接搜:

Select-String -Path D:\OSG\src\osgEarth\CMakeLists.txt ` -Pattern "OSG_VERSION|MIN_OSG|OSGEARTH_VERSION|CXX_STANDARD"

这条命令会同时告诉你三件事:它要求的 OSG 最低版本、osgEarth 自己的版本号、以及 C++ 标准(3.x 一般是 C++11,部分分支要求 C++14)。版本对不上时 CMake 会在配置阶段直接拒绝,这个失败反而是好事,比运行时崩溃好排查一万倍。

真正容易出问题的是 GDAL 和 PROJ 这一对。GDAL 3.x 之后,坐标系相关功能全部交给 PROJ 6+ 处理,运行时需要proj.db这个数据文件;而 GDAL 2.x 时代的二进制包根本不带这个东西。osgEarth 的 gdal 驱动是通过 GDAL 间接调用 PROJ 的,所以一旦 PROJ 的运行环境没配好,症状不是“编译失败”,而是“能启动、能画球、一加载带投影的影像就报错或者位置偏到别处”。

这也解释了为什么这份预编译三方库的价值主要在这里:GDAL 和 PROJ 的版本必须相互匹配,自己单独升级其中一个,大概率会掉进 API 变更的坑里。我的建议是保持包内原有组合不替换,真需要新版 GDAL 就整体重编一套,不要只替换其中一半。

GEOS 属于可选依赖,不装不影响主流程,但涉及缓冲区、相交判断这类几何运算时没有它就跑不了。是否启用看你的业务场景,纯做影像贴图和地形渲染的项目可以不装,省一点体积和出错面。

4.2 配置命令与必须显式指定的几个变量

# 先确认 OSG 的 config 文件到底安装在哪个子目录,不同分支位置不完全一样 Get-ChildItem D:\OSG\install -Recurse -Filter OpenSceneGraphConfig.cmake | Select-Object FullName

拿到真实路径后再配置:

cmake -S D:\OSG\src\osgEarth -B D:\OSG\build\osgearth ` -G "Visual Studio 16 2019" -A x64 ` -DCMAKE_INSTALL_PREFIX=D:/OSG/install ` -DCMAKE_PREFIX_PATH="D:/OSG/install;D:/OSG/3rdParty/x64/v142" ` -DOpenSceneGraph_DIR="D:/OSG/install/lib/cmake/OpenSceneGraph" ` -DBUILD_OSGEARTH_EXAMPLES=OFF ` -DOSGEARTH_BUILD_TESTS=OFF

CMAKE_PREFIX_PATH里同时放了两个前缀:install用来找 OSG 自己,3rdParty用来找 GDAL、PROJ、curl。osgEarth 找 OSG 走的是 config 模式(读OpenSceneGraphConfig.cmake),找其他依赖还是 module 模式,所以两个前缀都得给。

OpenSceneGraph_DIR必须明确指定到 config 文件所在目录,不要指望 CMake 自己猜。常见的失败信息是Could not find a package configuration file provided by "OpenSceneGraph",看到这句就回头执行上面那条Get-ChildItem,把真实路径填进去。

BUILD_OSGEARTH_EXAMPLES关掉是省时间,示例工程几十个,每个都要链接一遍,编一次多花十几分钟,而你验证功能只需要osgearth_viewer这一个工具。等主流程稳定了想跑示例再单独打开。

4.3 插件目录与运行时 DLL 的部署方式

osgEarth 装完之后,bin下会多出一个插件目录,不同分支的命名不完全一致,有叫osgEarthPlugins的,也有直接并入osgPlugins-3.6.5的。不要凭记忆找,直接列:

Get-ChildItem D:\OSG\install\bin -Directory | Select-Object Name Get-ChildItem D:\ <p> <a href="https://download.csdn.net/download/AAALB/89539472" style="color:#ec7500;font-size:14px;"> 本文还有配套的精品资源,点击获取 </a> <img alt="menu-r.4af5f7ec.gif" src="https://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif" style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;"> </p>

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询