
簡(jiǎn)介這份壓縮包是面向 Visual Studio 2017v141 工具集的 OpenSceneGraph 第三方依賴庫(kù)合輯專為 Windows x64 環(huán)境下的 OSG 開發(fā)環(huán)境搭建而整理。作者因 osg 官網(wǎng)頻繁崩潰、下載極慢前后耗時(shí)近一周才集齊所需的 3rdParty 組件直接打包分享可免去重復(fù)尋找與等待對(duì)初次配置 OSG 的初學(xué)者尤其友好。壓縮包整體采用 7z 格式大小約 98.6MB便于傳輸與一次性解壓由于平臺(tái)未列出文件總數(shù)與類型明細(xì)無(wú)法提供精確清單但這套第三方庫(kù)資源通常已覆蓋 OSG 官方推薦的 Windows 依賴包括頭文件、導(dǎo)入庫(kù)和運(yùn)行所需的 DLL能滿足多數(shù)編譯場(chǎng)景。目前已有 821 人學(xué)習(xí)/下載說(shuō)明它在 OSG 學(xué)習(xí)者中有一定認(rèn)可度。如果你正需要在 VS2017 x64 環(huán)境中引入 OSG 第三方庫(kù)這份資料可以省去數(shù)天的網(wǎng)絡(luò)折騰讓你把精力更多放在 OSG 的學(xué)習(xí)與項(xiàng)目開發(fā)上。OpenSceneGraph 3rdParty_VS2017_v141_x64_V11_full.7z搞 OpenSceneGraph 開發(fā)的人尤其是剛在 Windows 上從零開始折騰編譯環(huán)境的朋友十有八九都見過(guò)這個(gè)壓縮包OpenSceneGraph 3rdParty_VS2017_v141_x64_V11_full.7z。我第一次看到它時(shí)也一頭霧水文件名又長(zhǎng)又拗口到底有什么用、怎么裝、裝完怎么配網(wǎng)上資料零散得很。后來(lái)自己動(dòng)手在 VS2017 x64 環(huán)境下編譯 OSG折騰了一整個(gè)周末才把這套依賴關(guān)系理清楚。簡(jiǎn)單說(shuō)這個(gè) 7z 包是 OpenSceneGraph 在 Windows 平臺(tái)編譯時(shí)所需的“第三方依賴庫(kù)全家桶”。OSG 本身只負(fù)責(zé)三維渲染內(nèi)核但圖片加載、字體渲染、網(wǎng)絡(luò)傳輸、地理數(shù)據(jù)讀取這些功能都要靠外部的開源庫(kù)來(lái)完成。你當(dāng)然可以選擇自己一個(gè)個(gè)去編譯這些庫(kù)但更高效、更穩(wěn)定的做法是直接用社區(qū)維護(hù)好的預(yù)編譯版本——也就是這個(gè) 3rdParty 包。這篇文章我就結(jié)合自己的實(shí)操經(jīng)歷把這個(gè)包從下載解壓到配置編譯、再到排錯(cuò)避坑的完整流程講透適合正準(zhǔn)備用 VS2017 編譯 OSG、或者已經(jīng)在編譯路上被各種“找不到 lib / 找不到 dll”折磨的朋友參考。1. 這包到底是什么從文件名拆解 OpenSceneGraph 的依賴體系1.1 文件名里藏著的關(guān)鍵信息先把這個(gè)看起來(lái)很唬人的文件名拆開看你會(huì)發(fā)現(xiàn)它其實(shí)把最重要的信息都寫明白了OpenSceneGraph核心對(duì)象即 OSG 三維渲染引擎本身這套依賴庫(kù)就是服務(wù)于它的。3rdParty第三方庫(kù)集合里面是 OSG 官方幫大家準(zhǔn)備好的外部依賴項(xiàng)。VS2017 與 v141針對(duì) Visual Studio 2017 編譯環(huán)境。v141 是 VS2017 的 C 工具集版本號(hào)在 CMake 配置和工程屬性里經(jīng)常能看到這個(gè)標(biāo)識(shí)。x6464 位目標(biāo)架構(gòu)?,F(xiàn)在絕大多數(shù)開發(fā)機(jī)都是 64 位系統(tǒng)渲染類應(yīng)用對(duì)內(nèi)存尋址空間又很敏感所以 x64 版本是絕對(duì)的主流。V11第三方依賴庫(kù)集合的版本號(hào)。它不代表 OSG 的版本而是這一套第三方庫(kù)的資源版本標(biāo)識(shí)選新不選舊一般沒錯(cuò)。full完整版意味著里面包含了幾乎你能用到的所有依賴項(xiàng)不用再額外找別的包。.7z7-Zip 壓縮格式壓縮率高但 Windows 自帶的資源管理器不能直接解壓得安裝 7-Zip 或 Bandizip 之類的工具。把這些信息連起來(lái)理解這個(gè)包的核心定位就非常清楚了它為“使用 VS2017 編譯 64 位 OSG”這件事提供了一站式的依賴環(huán)境讓你省去逐個(gè)編譯 zlib、libpng、freetype 等基礎(chǔ)庫(kù)的巨大工作量。1.2 為什么 OSG 離不開這一堆第三方庫(kù)很多新手會(huì)問(wèn)既然叫 OpenSceneGraph為什么不能把所有功能內(nèi)置到源碼里非要依賴外部庫(kù)這其實(shí)是開源圖形項(xiàng)目非常典型的架構(gòu)決策。三維引擎關(guān)注的核心是場(chǎng)景管理、渲染管線、節(jié)點(diǎn)遍歷這些“圖形學(xué)重活”而圖片解碼、字體柵格化這些屬于“通用系統(tǒng)能力”自己重寫一遍既費(fèi)時(shí)又容易出漏洞直接復(fù)用被廣泛驗(yàn)證過(guò)的成熟庫(kù)是更明智的選擇。舉幾個(gè)具體依賴場(chǎng)景你加載一張.png貼圖OSG 會(huì)把解碼任務(wù)交給 libpng 和 zlib加載.jpg則走 libjpeg。在三維場(chǎng)景里顯示文字依賴 freetype 做字形渲染。從網(wǎng)絡(luò)地址加載模型或紋理需要 curl 庫(kù)支持。加載 GeoTIFF 等 GIS 數(shù)據(jù)格式需要 GDAL地理空間數(shù)據(jù)抽象庫(kù)來(lái)解析。OSG 在設(shè)計(jì)上把這些功能做成了“插件機(jī)制”核心是一個(gè)執(zhí)行引擎具體格式的解析由獨(dú)立的osgdb_xxx插件動(dòng)態(tài)加載完成。而 3rdParty 包提供的正是這些插件編譯時(shí)依賴的底層庫(kù)。沒有它們OSG 的內(nèi)核能編出來(lái)但各種常見功能都會(huì)癱瘓——比如連個(gè)最簡(jiǎn)單的 PNG 圖片都加載不了。用過(guò) Linux 的朋友可以把這理解成“Windows 下的 apt 依賴緩存”只是它需要你手動(dòng)解壓、手動(dòng)告訴 CMake 去哪里找。2. 從解壓到 CMake 配置的完整上手流程2.1 解壓部署與目錄規(guī)劃這一步看似簡(jiǎn)單但部署位置的規(guī)劃很影響后續(xù)使用體驗(yàn)。我建議把 3rdParty 解壓到一個(gè)純粹的、沒有中文沒有空格的路徑下比如D:\OSG\3rdParty。不要圖省事直接扔到下載目錄或者桌面因?yàn)楹罄m(xù) CMake 會(huì)反復(fù)引用這個(gè)路徑路徑里有空格或非 ASCII 字符可能在配置階段引發(fā)莫名其妙的報(bào)錯(cuò)。解壓工具我推薦使用 7-Zip 官方版本。右鍵選擇“7-Zip → Extract to”把壓縮包完整解壓。解壓后你會(huì)看到類似這樣的目錄結(jié)構(gòu)3rdParty_VS2017_v141_x64_V11_full/ ├── include/ # 所有第三方庫(kù)的頭文件 ├── lib/ # 靜態(tài)庫(kù)與導(dǎo)入庫(kù)(.lib) ├── bin/ # 運(yùn)行時(shí)DLL文件 └── share/ # 部分庫(kù)的附加數(shù)據(jù)或CMake配置這里要特別提醒bin目錄下的 DLL 不只是編譯時(shí)需要OSG 程序運(yùn)行同樣離不開。很多人編譯成功了一運(yùn)行程序就報(bào)“找不到 zlib1.dll”或“freetype.dll 缺失”就是因?yàn)閎in目錄沒加到系統(tǒng) PATH 里。建議在系統(tǒng)環(huán)境變量里新增一個(gè)用戶級(jí) PATH 項(xiàng)把D:\OSG\3rdParty\bin加進(jìn)去隨后重啟終端或 IDE 讓環(huán)境變量生效。2.2 CMake 里如何正確關(guān)聯(lián)這套依賴庫(kù)拿到依賴庫(kù)之后接下來(lái)的關(guān)鍵步驟是在 CMake 配置 OSG 時(shí)讓它找到這些庫(kù)。一般有兩種做法我分別說(shuō)下。第一種是設(shè)置CMAKE_PREFIX_PATH。在 CMake GUIcmake-gui打開 OSG 源碼目錄后在變量框里找到CMAKE_PREFIX_PATH把 3rdParty 的路徑填進(jìn)去。這樣 CMake 會(huì)自動(dòng)在3rdParty/lib、3rdParty/include等下掛載搜索子目錄進(jìn)而找到 zlib、libpng、freetype 等庫(kù)的頭文件和 lib 文件。第二種是逐個(gè)指定依賴庫(kù)路徑在 CMake 變量里找到ZLIB_LIBRARY、PNG_LIBRARY、FREETYPE_LIBRARY之類的手動(dòng)指到具體文件。這方法更精細(xì)但效率低、容易遺漏。我實(shí)測(cè)下來(lái)第一種方法在大多數(shù)情況下已經(jīng)足夠遇到個(gè)別庫(kù)沒找對(duì)再手動(dòng)微調(diào)即可。配置過(guò)程中有幾個(gè)關(guān)鍵變量需要確認(rèn)一下BUILD_OSG_EXAMPLES是否構(gòu)建示例工程建議開啟方便驗(yàn)證環(huán)境是否搭建成功。DYNAMIC_OPENSCENEGRAPH和DYNAMIC_OPENTHREADS建議保持默認(rèn)的 ON生成動(dòng)態(tài)鏈接庫(kù)版本。OSG_WINDOWING_SYSTEMWindows 平臺(tái)默認(rèn)是 Win32無(wú)需改動(dòng)。配置完成后點(diǎn)擊 Generate為 VS2017 生成解決方案。接下來(lái)用 VS2017 打開OpenSceneGraph.sln直接選擇 Release x64 配置右鍵 ALL_BUILD 生成。注意第一次全量編譯需要等待較長(zhǎng)時(shí)間二十分鐘到半小時(shí)都屬于正常范圍。3. 我實(shí)際踩過(guò)的編譯與運(yùn)行坑3.1 鏈接階段報(bào)錯(cuò)“找不到 xxx.lib”類問(wèn)題配置明明沒報(bào)錯(cuò)但一編譯鏈接就報(bào)LINK : fatal error LNK1104: cannot open file png.lib。這一類問(wèn)題大概率出在 CMake 緩存上。OpenSceneGraph 和第三方庫(kù)的 CMake 配置不是一次檢索就能全部完成的有時(shí)候你改了CMAKE_PREFIX_PATH但某個(gè)依賴項(xiàng)在緩存里還是舊的空值。解決辦法是點(diǎn)擊 CMake GUI 的“File → Delete Cache”徹底清掉緩存后重新 Configure確保所有依賴項(xiàng)都重新檢索一遍。這個(gè)坑我印象特別深。那次我明明把路徑填對(duì)了zlib 也都找到了唯獨(dú) png 一直報(bào)缺失后來(lái)發(fā)現(xiàn)是先前一次失敗配置把PNG_LIBRARY緩存成了PNG_LIBRARY_NOTFOUND不清緩存根本不會(huì)重新搜索。所以提醒各位凡是改了路徑相關(guān)的變量最好果斷刪緩存別怕重新等那幾分鐘比反復(fù)試錯(cuò)強(qiáng)多了。3.2 運(yùn)行時(shí)報(bào)錯(cuò)“could not find plugin to read objects from file”這個(gè)應(yīng)該是最經(jīng)典的 OSG 新手錯(cuò)誤了。場(chǎng)景是你寫了一個(gè)讀取.ive或.osgt的小程序編譯都通過(guò)了運(yùn)行卻提示W(wǎng)arning: could not find plugin to read objects from file xxx.ive出現(xiàn)這個(gè)提示絕大多數(shù)情況不是插件代碼有問(wèn)題而是 OSG 運(yùn)行時(shí)根本沒找到插件目錄osgPlugins-3.6.x。這個(gè)目錄位于源碼編譯產(chǎn)物中里面是幾十個(gè)osgdb_xxx.dll插件。如果你沒有把 OSG 的bin目錄包含osg80-osg.dll、osgDB.dll等和插件目錄加到 PATHOSG 就會(huì)懵在原地。解決辦法把D:\OSG\bin或者你的 OSG 編譯輸出目錄也加進(jìn) PATH。也可以在程序里顯式設(shè)置插件搜索路徑osgDB::Registry::instance()-setLibraryFilePathList(D:/OSG/bin/osgPlugins-3.6.x);我實(shí)際項(xiàng)目里會(huì)在程序啟動(dòng)時(shí)打印一次插件搜索路徑列表早點(diǎn)暴露問(wèn)題避免在集成第三方引擎時(shí)排查半天。4. 常見問(wèn)題速查表與避坑經(jīng)驗(yàn)4.1 一張表搞定高頻問(wèn)題這里把我在實(shí)際使用中遇到的、以及群里朋友常問(wèn)的問(wèn)題整理成一張速查表方便以后遇到直接對(duì)號(hào)入座問(wèn)題現(xiàn)象可能原因解決思路CMake 找不到 PNG/JPEG/FREETYPE依賴路徑未關(guān)聯(lián)或緩存殘留刪除 CMakeCache 后重新 Configure編譯報(bào) LNK2038 RuntimeLibrary 不匹配Debug/Release 或庫(kù)編譯器版本混用確保 ALL_BUILD 與 3rdParty 工具集一致運(yùn)行提示缺少 zlib1.dll / freetype.dll3rdParty 的 bin 目錄不在 PATH添加 PATH 并重啟終端/IDE運(yùn)行提示 could not find pluginOSG 插件目錄未找到添加 OSG bin 目錄到 PATH或代碼指定插件路徑Release 版正常Debug 版鏈接失敗3rdParty 只包含對(duì)應(yīng)版本庫(kù)檢查 lib 目錄下是否有 debug 版本 lib 文件GDAL 相關(guān)插件加載失敗GDAL 運(yùn)行時(shí)環(huán)境缺失確認(rèn) 3rdParty bin 中 gdal DLL 完整性必要時(shí)單獨(dú)部署 GDAL 環(huán)境4.2 關(guān)于版本匹配的“血淚經(jīng)驗(yàn)”版本匹配是我最想強(qiáng)調(diào)的一點(diǎn)。這個(gè) 3rdParty 包明確標(biāo)注了VS2017和v141那就意味著它默認(rèn)匹配 VS2017 的工具集。如果你手頭只有 VS2019 或者 VS2022也能用 v141 工具集編譯消耗這些庫(kù)但前提是你得在 VS 安裝器里補(bǔ)裝“VS2017 工具集”組件。否則用 v142/v143 工具集去鏈接一個(gè) v141 編譯的庫(kù)系統(tǒng)會(huì)報(bào)工具集版本不一致的警告嚴(yán)重時(shí)甚至鏈接失敗或是運(yùn)行時(shí)行為異常。另外Debug 和 Release 的區(qū)分也容易踩坑。OSG 的第三方庫(kù)通常同時(shí)提供 debug 版和 release 版的.lib文件CMake 會(huì)根據(jù)你生成的配置自動(dòng)挑選。但假如你只有 Release 版 3rdParty卻用 Debug 模式去編譯 OSG就會(huì)出現(xiàn)運(yùn)行時(shí)庫(kù)不匹配、內(nèi)存錯(cuò)誤等一系列詭異問(wèn)題。我的建議是一開始就用 Release x64 編譯 OSG 和測(cè)試程序確認(rèn)整個(gè)流程走通后再考慮 Debug 版。畢竟 Debug 版的 OSG 依賴更多調(diào)試符號(hào)對(duì)新手來(lái)說(shuō)排查起來(lái)更吃力。還有一個(gè)朋友踩過(guò)的坑從網(wǎng)上下載了名稱類似但版本是 V10 或 V12 的 3rdParty 包結(jié)果在 CMake 階段各種奇怪報(bào)錯(cuò)。不同版本的 3rdParty 里庫(kù)的布局、命名可能略有差異最好不要混用。老老實(shí)實(shí)根據(jù) OSG 版本和官方文檔選擇合適的依賴包。5. 擴(kuò)展思考何時(shí)需要自己手動(dòng)編譯第三方庫(kù)5.1 預(yù)編譯包的局限性雖然這個(gè) 3rdParty 包很省心但它不是銀彈。如果項(xiàng)目有特殊需求預(yù)編譯包就不一定夠用了。最常見的場(chǎng)景是使用靜態(tài)鏈接。預(yù)編譯包默認(rèn)是動(dòng)態(tài)鏈接的即運(yùn)行環(huán)境里得有一堆 DLL 文件。如果你希望最終產(chǎn)品是“一個(gè) exe 走天下”把依賴庫(kù)靜態(tài)鏈接進(jìn)主程序那你就得用/MT模式重新編譯所有第三方庫(kù)。這可不是改幾個(gè) CMake 開關(guān)就行的小工程因?yàn)閦lib、libpng等庫(kù)各自有自己的構(gòu)建系統(tǒng)全部靜態(tài)化是個(gè)多步驟、高維護(hù)成本的操作。另一種場(chǎng)景是自定義編譯選項(xiàng)。比如你需要在curl里啟用某些特定協(xié)議或者想讓freetype支持某種特殊字體格式預(yù)編譯包顯然沒法幫你做到。這時(shí)候就需要手動(dòng)介入。5.2 vcpkg 作為備選方案的經(jīng)驗(yàn)要是決定自己編譯我建議優(yōu)先考慮微軟的 vcpkg 包管理器而不是挨個(gè)庫(kù)去下載源碼手動(dòng)構(gòu)建。vcpkg 可以一鍵安裝依賴還自動(dòng)管理版本關(guān)系。我試過(guò)用它編譯整套 OSG 依賴命令大致是這樣的vcpkg install zlib libpng libjpeg-turbo freetype curl gdal openexr --triplet x64-windows安裝完成后CMake 配置 OSG 時(shí)加上-DCMAKE_TOOLCHAIN_FILE[vcpkg路徑]/scripts/buildsystems/vcpkg.cmakevcpkg 會(huì)自動(dòng)把依賴項(xiàng)注入到 CMake 搜索路徑中。這個(gè)流程對(duì)習(xí)慣命令行的開發(fā)者來(lái)說(shuō)很順手對(duì)零基礎(chǔ)新手來(lái)說(shuō)還是略復(fù)雜畢竟 vcpkg 本身也要編譯、校準(zhǔn)工具鏈中途難免冒出各種環(huán)境問(wèn)題。所以我還是那句話能用預(yù)編譯包就別折騰先跑通主干流程再考慮可控性和優(yōu)化問(wèn)題。6. 一些值得沉淀的實(shí)踐心得6.1 我推薦的環(huán)境變量和目錄組織方案經(jīng)驗(yàn)多了之后我通常會(huì)把所有圖形開發(fā)相關(guān)的東西集中到一個(gè)固定的目錄比如D:\dev下面分別放 OSG 源碼、3rdParty 依賴庫(kù)、CMake 構(gòu)建產(chǎn)物等。目錄結(jié)構(gòu)會(huì)做成類似這樣D:\dev\ ├── OSG\ # OSG 源碼 ├── 3rdParty\ # 第三方依賴 ├── build\ # CMake 構(gòu)建輸出 └── tools\ # 7-Zip、CMake 等工具然后配置幾個(gè)明確的環(huán)境變量OSG_3DPARTY_DIR指向D:\dev\3rdPartyOSG_ROOT指向D:\dev\build\installOSG 安裝目錄再把兩者的bin都加進(jìn) PATH。以后不管寫 CMakeLists 還是配置 Qt Creator都可以直接引用這些變量不至于在多個(gè)項(xiàng)目里重復(fù)填一堆絕對(duì)路徑。6.2 給準(zhǔn)備入門的朋友一句實(shí)在話如果你只是想先跑通一個(gè) OSG 的 Demo完全沒有必要去深究每一個(gè)第三方庫(kù)的編譯細(xì)節(jié)。先把 3rdParty 包配好把 OSG 源碼編過(guò)把一個(gè)簡(jiǎn)單的osgViewer程序跑起來(lái)這是最重要的一步。等整體流程有感覺了再回過(guò)來(lái)研究某些庫(kù)的內(nèi)部機(jī)制也不遲。我在第一次搞 OSG 環(huán)境時(shí)就是因?yàn)樘敫闱宄恳粋€(gè)庫(kù)的來(lái)龍去脈結(jié)果陷入不斷編譯、不斷調(diào)試泥潭里白白浪費(fèi)了兩三天。后來(lái)的經(jīng)驗(yàn)是工程上的事情先能用再優(yōu)化最后才是搞懂。這套思路放到 OpenSceneGraph 的構(gòu)建上同樣適用。最后再分享一個(gè)小技巧3rdParty 包里帶的bin目錄 DLL 雖然多但程序發(fā)布時(shí)其實(shí)只需要拷貝你用到的那些。你可以用 Process Explorer 或 Dependencies 工具查看最終 exe 的模塊加載列表再?zèng)Q定哪些 DLL 需要一起分發(fā)。這樣能有效控制產(chǎn)品體積也避免把大量無(wú)關(guān)心帶出去造成誤導(dǎo)。本文還有配套的精品資源點(diǎn)擊獲取