
簡介OpenSceneGraph 3rdParty_VS2017_v141_x64_V11_full.7z 是一套專為 Visual Studio 2017v141 工具集準備的 OSG 第三方依賴庫完整打包面向需要在 Windows x64 環(huán)境下編譯或運行 OpenSceneGraph 的 C 開發(fā)者。由于 OSG 官網(wǎng)訪問不穩(wěn)定、下載速度極慢作者耗時一周才完整獲取這些依賴組件現(xiàn)以 7z 壓縮包形式共享可省去逐個尋找與等待的時間。該壓縮包約 98.6MB解壓后即可獲得用于 VS2017 x64 環(huán)境下的依賴組件集合涵蓋編譯 OSG 所需的第三方庫、頭文件及運行支持文件適用于配置渲染、場景管理等基礎開發(fā)環(huán)境也適合剛接觸 OSG 的讀者直接解壓使用。目前已有 822 人瀏覽學習說明對解決環(huán)境搭建痛點有實際參考價值。下載后按 VS2017 x64 工程配置好包含目錄與庫目錄即可讓 OSG 及相關插件正常編譯鏈接減少因缺少依賴而反復報錯的困擾。1. 用 OpenSceneGraph 做渲染卻被依賴卡住這個 v141_x64 依賴包到底解決什么三周前某開發(fā)者抱著“VS2017 編譯成功但一運行就閃退”的工程來找我查了一下午問題不在他的代碼而在 OSG 插件運行時找不到第三方 DLL。OpenSceneGraphOSG編譯本身不難難的是 zlib、libpng、freetype、glew、tbb 這一圈第三方依賴各自版本、工具集、Debug/Release 一變鏈接期能過運行期不一定能過。OpenSceneGraph 3rdParty_VS2017_v141_x64_V11_full.7z就是給 Visual Studio 2017v141 工具集x64 架構準備的整套依賴混合包解壓后直接喂給 CMake把“逐個下載依賴再編譯”這個最耗時且最容易翻車的環(huán)節(jié)砍掉。適合要做 OSG 三維仿真、地形渲染、跨平臺視景程序又不想在依賴上繼續(xù)消耗時間的 C 開發(fā)者。2. 拆包看本質這個依賴包里到底裝著什么2.1 目錄結構背后的三分法邏輯把壓縮包解開后典型的 3rdParty 目錄結構是三個平級目錄include、lib、bin。這個結構不是隨便擺的它對應 OSG 在 CMake 配置階段的三種搜索需求——頭文件路徑include、鏈接庫路徑lib、運行時 DLL 路徑bin。3rdParty/ ├── include/ │ ├── zlib.h │ ├── png.h │ ├── ft2build.h │ └── ...各依賴庫頭文件 ├── lib/ │ ├── zlib.lib # Release 版 │ ├── zlibd.lib # Debug 版 │ └── ...同規(guī)則命名的靜態(tài)庫 └── bin/ ├── zlib1.dll ├── zlibd1.dll # Debug 版帶d后綴 └── ...同名但分 Debug / Release 的 DLLOSG 用 CMake 做配置檢測時靠名字后綴區(qū)分庫的調(diào)試態(tài)與發(fā)布態(tài)zlibd.lib里的 d 代表 debugableRelease 構建不要鏈接它。這個“同名帶 d / 不帶 d”的規(guī)則貫穿整個包后面寫 LIBPNG、FREETYPE 時同理。把 Debug 庫和 Release 庫混著鏈最常見的結局是編譯期報LNK2038或者運行時彈“無法定位程序輸入點”這屬于可以提前避開的基礎常識。另一個細節(jié)是OSG 之所以不直接用系統(tǒng)自帶的同名依賴庫是因為它的插件體系要求每個第三方庫以獨立模塊存在版本一旦錯位插件加載時就是靜默失敗不報任何明確信息。2.2 各依賴庫的角色定位這份依賴包里的每個庫在 OSG 渲染管線里承擔的任務不一樣。我拆過幾個 OSG 工程把直接參與常用渲染路徑的庫挑出來依賴庫在 OSG 里的用途必用程度zlib底層解壓縮PNG 壓縮數(shù)據(jù)解析依賴它極高libpng / libjpeg / libtiff紋理圖片解碼加載 jpg/png/tiff 貼圖時被插件調(diào)用高giflibgif 紋理加載視需求而定freetype文字紋理渲染HUD 和標注信息顯示靠它高做 GIS/仿真必備curl網(wǎng)絡文件讀取遠程模型庫加載視需求而定glewOpenGL 擴展入口加載OSG 渲染線程初始化時使用極高glfw / sdl窗口與事件管理viewer 創(chuàng)建窗口視選擇而定tbb并行計算多線程渲染與裁剪算法加速極高lua腳本綁定可選的腳本化控制層低你解壓后看到的“full”全量包就是把 debug 和 release 兩套庫都塞進去了配齊的好處是不需要因為缺少某一個靜態(tài)庫去臨時補編。壞處是體積變大后面發(fā)布截取時可以再瘦身這個放到第 5 章講。2.3 給熟手劃清邊界這個包適配什么、不背什么鍋名字上寫得很直白VS2017、v141、x64、V11。v141 是 Visual Studio 2017 默認的平臺工具集版本號這和工程屬性里看到的“Visual Studio 2017 (v141)”是一回事。如果你手里是 VS2019v142 工具集用這份包大概率碰不到顯式報錯但庫的 ABI 兼容與工具集元數(shù)據(jù)不匹配會以各種奇怪鏈接錯誤的形式出現(xiàn)不排除能過的情況但別指望它能穩(wěn)定復現(xiàn)。V11 指的是 3rdParty 包的版本代次對應 OSG 3.6.x 開發(fā)周期中某一輪的配套依賴快照和 OSG 主版本號不是同一個數(shù)字體系實際編譯前要確認你的 OSG 源碼版本和這個包在 CMake 里的檢測結果能對上。還要劃清的邊界是這包只管“第三方依賴”不含 OSG 主庫源碼、不附帶 CMake 構建工具、不提供 VS 工程模板。它的正確用法是作為輸入源喂給 OSG 的 CMake 配置讓 OSG 的構建腳本在它上面自動生成依賴變量。把這個前提理解透后面每一步操作都不會跑偏。3. 把依賴接進 OSG 構建流程從解壓到生成 VS 工程全記錄3.1 環(huán)境核對與目錄規(guī)劃動手前先對一遍環(huán)境Visual Studio 2017 已裝好、勾選了“適用于 Visual Studio 2017 的 C 工具集”、CMake 版本不低于 3.10。架構上明確是 x64生成的 OSG 庫和插件全是 64 位后面所有配置選項都圍繞 x64 走不要在配置中途切到 Win32否則依賴檢測會全部落空。路徑規(guī)劃是很多人在這一步就開始踩坑的地方。把這整個 3rdParty 文件夾放到一個純英文、無空格的路徑下比如D:/dev/3rdParty_vs2017_x64不要放進C:\Program Files之類帶空格的目錄。因為 CMake 在處理第三方庫路徑時會把空格后的內(nèi)容拆成新的參數(shù)變量名帶引號可以緩解但依賴庫附帶的 pkgconfig 文件不認空格。OSG 源碼目錄也建議放在同類規(guī)則的路徑下。3.2 用 CMake 配置腳本把依賴指給 OSG常見做法是在 OSG 源碼目錄外創(chuàng)建一個 build 目錄把 CMake 生成結果統(tǒng)一收進去。把 3rdParty 告訴 CMake 的方式不同版本略有差異。通常優(yōu)先設置CMAKE_PREFIX_PATH因為 OSG 的 CMake 腳本會在該路徑下自動搜索include、lib、bin三個子目錄。具體命令行如下以命令行為例CMake GUI 里對應是兩個輸入框cmake ../OpenSceneGraph \ -G Visual Studio 15 2017 \ -A x64 \ -DCMAKE_PREFIX_PATHD:/dev/3rdParty_vs2017_x64 \ -DCMAKE_BUILD_TYPERelease \ -DBUILD_OSG_EXAMPLESON-G指定生成器Visual Studio 15 2017是 VS2017 在 CMake 里的固定字符串不要手寫版本號-A x64強制架構為 64 位CMAKE_PREFIX_PATH指向解壓后的 3rdParty 根目錄OSG 的檢測腳本會按“根/include、根/lib、根/bin”的約定自動找到各依賴庫的具體路徑CMAKE_BUILD_TYPE在 VS 多配置生成器下只作為默認配置項實際 Debug 和 Release 都可以在 VS 里切換但它會影響 CMake 選擇依賴庫時偏向哪一組BUILD_OSG_EXAMPLESON把自帶示例編進去強烈建議開著后面驗證渲染和插件是否正常全靠它。3.3 逐項核對 CMake 變量是否指向正確路徑命令行配置完成后打開 CMake GUI 加載 build 目錄的 CMakeCache.txt逐項檢查幾個關鍵依賴變量的取值。重點看它們是否落在D:/dev/3rdParty_vs2017_x64的范圍內(nèi)CMake 變量期望取值示例錯誤取值預示的問題ZLIB_INCLUDE_DIRD:/dev/3rdParty_vs2017_x64/include找不到 zlib.hPNG 插件編譯失敗ZLIB_LIBRARYD:/dev/3rdParty_vs2017_x64/lib/zlib.lib鏈接期找不到 zlib報 LNK1181LIBPNG_LIBRARYD:/dev/3rdParty_vs2017_x64/lib/libpng16.lib紋理解碼功能缺失FREETYPE_INCLUDE_DIR_freetype2D:/dev/3rdParty_vs2017_x64/include/freetype2HUD 文字渲染不可用TBB_INCLUDE_DIRD:/dev/3rdParty_vs2017_x64/include多線程渲染退化為單線程遇到某一個變量顯示NOTFOUND不要急著對整個包做修改。先確認對應目錄里是否有該文件、文件名是否帶 d 后綴、x64 子目錄是否存在。CMake 在同一個根路徑下檢測時只要目錄命名標準絕大多數(shù)變量能自動對齊。若個別項找不到手工點 ... 按鈕把路徑指過去然后重新 Configure直到整張變量表沒有紅色錯誤項。3.4 生成與編譯一次生成別單獨編某個項目配置完成后點擊 Generate 生成 VS 解決方案然后打開生成的OpenSceneGraph.sln對整個解決方案執(zhí)行“生成解決方案”。這里有個容易出現(xiàn)的方向性錯誤不要因為只想驗證某個功能就單獨編譯osgViewer項目OSG 的插件和庫存在復雜的依賴順序單獨編某個小項目會漏掉插件 DDL運行時會報一堆 “Failed to load plugin”。命令行下全量構建可參考如下步驟VS 界面里執(zhí)行同樣的全量生成即可cmake --build . --config Release --target install--config Release指定構建配置和前面 CMAKE_BUILD_TYPE 保持一致--target install會把產(chǎn)物收集到 CMAKE_INSTALL_PREFIX 指定的目錄默認是 OSG 源碼下的 install 子目錄。執(zhí)行時觀察輸出zlib、libpng、freetype 的編譯日志如果出現(xiàn)在“Building”階段說明前面的依賴路徑已被正確接上。整個過程在主流配置下約 20 到 50 分鐘中間如果報錯百分之八十的根因都集中在依賴路徑指向錯誤上。4. 避坑實錄把這份包接進 VS2017 后我翻過的四次車4.1 Debug 和 Release 混用導致的 LNK2038現(xiàn)象編譯 OSG 主庫時報LNK2038 mismatch detected for RuntimeLibrary詳細提示是“值 MT_StaticRelease 與 MD_DynamicRelease 不匹配”看起來像是 CRT 靜態(tài)鏈接和動態(tài)鏈接混在一起。原因CMake 在 Debug 配置下自動選擇了帶 d 的 debug 庫在 Release 配置下選擇不帶 d 的 release 庫但工程里如果有自定義第三方項目同時引用兩條路徑鏈接器就會看到同一符號對應兩種不同的運行時庫規(guī)則。另一種更常見的觸發(fā)方式是在 Release 項目里手工追加了 debug 版的.lib文件路徑。解決打開 VS 工程屬性在“鏈接器 → 輸入 → 附加依賴項”里逐行核對文件名Debug 配置只保留zlibd.lib、libpng16d.lib這類帶 d 的庫Release 配置只保留不帶 d 的庫。對照表如下配置zlib 用這個libpng 用這個Debugzlibd.liblibpng16d.libReleasezlib.liblibpng16.lib檢查完后重新生成解決方案不要再只編出錯的單項目強迫 CMake 重算一次依賴關系。4.2 運行時提示缺少 zlib1.dll / libpng16.dll現(xiàn)象編譯全部通過生成了osgviewer.exe雙擊運行直接彈窗“由于找不到 zlib1.dll無法繼續(xù)執(zhí)行代碼”或者沒有任何彈窗就閃退。原因OSG 插件在運行時通過動態(tài)加載方式查找依賴 DLL搜索順序是 exe 所在目錄、系統(tǒng) PATH、當前工作目錄。這個包里的bin目錄從未被加入 PATH插件加載失敗后 viewer 選擇了靜默退出。我遇到過因為工作目錄不同而時好時壞的情況代碼沒變行為變了查了一小時才發(fā)現(xiàn)是 PATH 問題。解決將D:/dev/3rdParty_vs2017_x64/bin追加到系統(tǒng)環(huán)境變量 PATH?;蛘吒∈碌淖龇ò裝in里的 DLL 一次性復制到 exe 同級目錄。復制的代價是發(fā)布時容易帶全所有 debug DLL所以只建議本地調(diào)試用。提示修改 PATH 后要新開一個終端或重啟 VS否則環(huán)境變量不會刷新。4.3 插件加載失敗但不報任何原因現(xiàn)象運行時輸出窗口出現(xiàn)Warning: Failed to load plugin osgdb_png.dll但文件明明存在于bin/osgPlugins-3.6.x/目錄下手動用加載庫方式打開該 DLL 也成功。原因osgdb_png.dll本身存在但它依賴的libpng16.dll或者zlib1.dll不在系統(tǒng)搜索路徑中。這屬于間接依賴缺失Windows 只報告第一層加載失敗不會告訴你“因為缺 libpng16.dll 所以 osgdb_png.dll 加載不了”。解決用 Dependencies 工具老牌的 Depends.exe 已停止維護社區(qū)維護的 Dependencies 可用打開osgdb_png.dll在“導入函數(shù)”列表里找標紅的 DLL逐個比對3rdParty/bin目錄中是否存在同名且同架構版本。定位后把缺少的那個 DLL 的目錄加入 PATH問題立刻消失。4.4 含空格的路徑讓 CMake 變量全線 NOTFOUND現(xiàn)象把 3rdParty 放到C:\Program Files\3rdParty_vs2017_x64后執(zhí)行 CMakeZLIB_INCLUDE_DIR、LIBPNG_LIBRARY等全部為 NOTFOUND反復點擊 Configure 無效手填變量后被下一次 Configure 覆蓋回空值。原因CMake 的內(nèi)置find_path、find_library模塊對帶空格的路徑處理不徹底生成器表達式和緩存變量在空格路徑下會解析出兩個參數(shù)導致匹配失敗。解決把整個包移動到D:/dev/3rdParty_vs2017_x64這種無空格無中文的路徑重新解壓后再次執(zhí)行緩存清理。我習慣刪掉 build 目錄后重新走一遍配置不給 CMake 緩存留任何歷史包袱。5. 編譯成功只是開始驗證與配送那幾件容易忽略的事5.1 osgversion 與依賴檢查雙線驗證編譯安裝完成后先到安裝目錄的 bin 下找到osgversion.exe命令行執(zhí)行它osgversion正常輸出類似3.6.5某些版本還會帶OpenSceneGraph Library 3.6.5的字樣。這個輸出說明主庫構建時對第三方依賴的檢測、鏈接都成功了。再把osgviewer.exe拖進 Dependencies 工具看導入列表里是否出現(xiàn)OPENGL32.dll、GLU32.dll之外的依賴項重點觀察它們是否全部來自3rdParty/bin。如果列表里出現(xiàn)某個庫的絕對路徑指向了別處說明 CMake 緩存里混入了其他版本依賴后面發(fā)布時會踩“開發(fā)機正常、別的機器崩”的雷。5.2 首屏渲染驗證插件鏈是否真的通了用一個 3D 模型或圖片驗證整套插件鏈。OSG 自帶的示例模型在data目錄下用 osgviewer 加載osgviewer cow.osg窗口能彈出來且顯示一只牛說明窗口系統(tǒng)相關的 GLFW/GLUT 插件已生效模型表面紋理顯示正常說明 PNG/JPEG 插件能完成紋理解碼旋轉操作流暢說明 TBB 并行模塊被正確鏈接進渲染循環(huán)。如果界面流暢但紋理是灰色色塊優(yōu)先檢查 zlib 和 libpng 的 debug/release 配置是否錯位。這一步同時把 OSG 的核心鏈路和第三方依賴鏈路做了一次全局冒煙測試。5.3 發(fā)布階段的 DLL 裁剪清單生產(chǎn)環(huán)境發(fā)布時不能把 3rdParty 的 bin 整個搬過去。按功能鏈路裁剪能省大量體積我通常按這個最小清單配貨DLL 文件用途鏈路是否必須zlib1.dllPNG 壓縮解壓、網(wǎng)絡流解壓必須libpng16.dll紋理 PNG 解碼按內(nèi)容格式jpeg62.dlljpg 貼圖解碼按內(nèi)容格式freetype.dll文字標注渲染GIS/仿真類必須glew32.dllOpenGL 擴展入口必須tbb.dll并行線程調(diào)度必須libcurl.dll網(wǎng)絡加載模型按需經(jīng)驗是三類 DLL 必帶渲染鏈路glew、tbb、文件 I/O 鏈路zlib、libpng、字體鏈路freetype。其他如 giflib、lua 按實際調(diào)用的 OSG 插件裁剪。不帶 d 后綴的是 Release 版發(fā)布時只帶這組。6. 把這份依賴包用成基礎設施的三個高階習慣把 3rdParty 當一次性解壓工具用太浪費我更傾向讓它成為一個被多個工程共享的基礎目錄。第一種做法是符號鏈接代替復制避免把 DLL 庫文件散落得到處都是mklink /D D:\dev\shared_3rdParty D:\dev\3rdParty_vs2017_x64Windows 下mklink /D創(chuàng)建目錄符號鏈接可以給同一份依賴做多個邏輯入口比如第一個工程用 VS2017 編譯時指向上層路徑第二個工程在另一臺機器上用同樣鏈接映射到同一個物理目錄。注意符號鏈接本身對 CMake 透明路徑被解析成真實路徑后不再體現(xiàn)鏈接關系。第二種習慣是把CMAKE_PREFIX_PATH寫進用戶級環(huán)境變量這樣后續(xù)新拉的 OSG 源碼、甚至其他依賴同一套庫的工程CMake 都能默認找到依賴根目錄。新建工程的 CMakeLists 里不需要再寫死路徑直接沿用環(huán)境配置。第三種習慣是對不需要的依賴做頏減在 CMake 配置階段關掉BUILD_OSG_LUA和所有非核心插件的編譯選項讓整個構建時間縮短三分之一以上。全量包負責兜底頏減后的構建負責交付。從那以后我每次換 OSG 主版本都強制走一遍同樣的動作先解壓 3rdParty、校準工具集、再清掉 build 緩存重配 CMake最后用 osgviewer 加載一個帶紋理的模型確認插件鏈路完整隨后才敢繼續(xù)寫業(yè)務代碼。這套流程看著樸素但把“依賴不匹配”這類的黑匣子消掉后編譯期報錯反而變得直白可查。希望幫到你。本文還有配套的精品資源點擊獲取