osg开发配置与第一个osg程序
目錄
1.前言
2.osg簡介
3.OSG開發環境配置
3.1下載安裝VS2022
3.2獲取osg庫
4.編寫、編譯并運行第一個osg程序
4.1編寫第一個C++ CMake程序
4.2編寫第一個osg程序
4.3一個xue微有點追求的osg程序
1.前言
本文介紹開源圖形庫osg的開發環境配置和編寫第一個osg程序的完整過程。這是一個教程,也是一個與各位圖形從業者的交流平臺。
開發環境:Windows10 專業版、Visual Studio 2022、osg3.6.5;
項目構建:CMake。
Visual Studio從版本2017開始支持CMake項目,本文編寫時VS的最新版本是VS2022,我們就使用最新版本。CMake?是一個跨平臺、開源的元構建系統,廣泛應用于C/C++項目的源碼構建,它可以為make、ninja等構建系統生成構建腳本。CMake根據用戶在CMakeLists.txt編寫的各種命令構建工程,本文對涉及到的CMake命令會進行介紹。
2.osg簡介
OpenSceneGraph簡稱osg,是基于標準C++語言和OpenGL編寫的圖形引擎,詳細介紹見osg主頁。
3.OSG開發環境配置
3.1下載安裝VS2022
VS官網下載VS2022。VS2022分為社區版,個人版和企業版,其中社區版可免費使用,個人版和企業版可免費使用30天。如使用個人版和企業版,請用你懂得的方式進行,如想減輕使用盜版軟件帶來的負罪感,社區版也是夠用的。
VS安裝時需注意,勾選項"用于Windows的C++ CMake 工具"和"MSVC V142 - VS 2019 C++ x64/x86 生成工具"。如下圖所示
在此解釋一下勾選這兩項的原因:
3.2獲取osg庫
獲取osg庫至少有三種方式:
本文例子使用Visual C++ 2019編譯的64位osg3.6.5?
下載Release和Debug版,并解壓到本地硬盤。假設Release版和Debug版的保存路徑分別為:"E:/osg/OpenSceneGraph-3.6.5-VC2019-64-Release/ "和 "E:/osg/OpenSceneGraph-3.6.5-VC2019-64-Debug/"。庫的目錄組織如下圖:
?bin目錄存放可執行的二進制文件,即exe文件和dll文件,包括實用工具"模型/場景查看器" osg_viewer.exe、"格式轉換工具"osg_conv.exe等;include目錄存放頭文件;lib目錄存放.lib庫文件。
為了簡化本篇教程,本例子只用Debug庫,涉及Debug和Release的切換問題,將在后續教程介紹。
至此,所需的軟件都已準備就緒。下面我們將創建第一個osg程序。
4.編寫、編譯并運行第一個osg程序
本著由簡入繁、一步一個腳印的原則,我們將首先使用VS2022創建一個CMake工程,并使用標準C++編寫一個最簡單的程序(Hello World: "沒錯,就是我!"),程序正常編譯和運行后再引入osg庫并創建第一個osg窗口,而后創建一個簡單的場景,這一切都正常編譯運行后,我們的第一個osg程序任務就可以完美結束了。
4.1編寫第一個C++ CMake程序
首先我們先用VS2022創建一個CMake工程。
這時候有的同學要問了,為什么要用CMake呢,VS的工程(.sln)不可以嗎?
答案是:可以。VS工程經過界面化的配置就可以開發運行osg程序,但是我依然推薦大家使用CMake工程,因為在程序員生涯中,您一定會接觸開源、跨平臺的C++項目,您甚至會自己開發一套開源軟件,而在這個過程中一定繞不開CMake,所以CMake命令雖然入門有難度,但是學習它是很有必要的。因此在此文中,我將創建CMake工程,并與大家一起探索和使用這個優秀的工具。
言歸正傳,我們開始創建第一個CMake工程。
1.新建文件夾"learn_osg_01",在文件夾內創建文件"CMakeLists.txt"和文件"main.cpp",此時兩個文件都是空的。
2.打開VS2022,選擇"打開本地文件夾",并選擇"learn_osg_01"目錄。
?3.此時VS經過一番自動操作,完成了CMake工程的生成工作。可以發現此時在"learn_osg_01"目錄下多了兩個文件夾".vs"和"out",其中".vs"目錄下會生成VS的項目配置、緩存等文件,由VS自動維護,我們可以不用關心,甚至可以在關閉工程時刪除(再次打開VS還會重新生成);"out"目錄下將存放將來編譯、鏈接生成的各種文件。
4.在"main.cpp"中編寫"Hello World"程序。
#include <iostream>int main(int argc, char** argv) {std::cout << "Hello, osg!" << std::endl;return 0; }5.這是一個可正常編譯運行的C++源程序,正確使用CMake可生成可執行程序。CMake如何知道怎么構建呢?答案是通過"CMakeLists.txt"文件的指令。我們在"CMakeLists.txt"中輸入以下代碼并保存:
project("learn_osg_01") add_executable(${PROJECT_NAME} main.cpp)6.點擊VS菜單的"生成-全部生成",VS會自動調用相關工具生成"learn_osg_01.exe",F5可運行調試,此時在控制臺上已經可以輸出"Hello, osg!"。
至此,第一個CMake C++程序已經完成了。在進行下一步之前請容我簡要介紹一下用到的兩條CMake指令。
project("learn_osg_01")project()指令的作用是設置項目名稱,并存放在變量PROJECT_NAME中,如果在頂層的CMakeLists.txt中調用此指令,會同時把項目名稱存放在變量CMAKE_PROJECT_NAME中,同時還會自動設置以下變量:
PROJECT_SOURCE_DIR:? 項目源碼的絕對路徑,在此例中是"E:/一坨路徑.../learn_osg_01"
PROJECT_BINARY_DIR:?項目二進制目錄的絕對路徑,在此例中是"E:/一坨路徑.../learn_osg_01/out/build/x64-Debug"
另外project()指令還可指定版本,語言等。
add_executable(${PROJECT_NAME} main.cpp)add_executable()指令的作用是使用指定的源文件生成目標可執行文件,指令的第一個參數是要生成可執行文件(Windows系統中是exe文件)的名稱,本例中會生成"learn_osg_01.exe",名字后邊的參數是源文件列表,此例中目前只有一個源文件,即"main.cpp",如有多個源文件,要依次列在后邊,用空格或換行隔開。
我們已經搞明白了這幾行代碼,接下來我們要開始編寫基于osg的程序了。
4.2編寫第一個osg程序
寫過Visual C++項目的同學一定了解,在VC++項目中,通過圖形界面就可配置庫,非常方便。對于CMake工程,我們要用自己勤勞的雙手輸入指令代碼去完成配置。
我們要引入osg庫,首先要告訴編譯器庫頭文件的位置。在CMake中使用include_directories()指令實現。
include_directories("E:/osg/OpenSceneGraph-3.6.5-VC2019-64-Debug/include")include_directories()指令告訴編譯器搜索頭文件的路徑,把目錄加入到屬性INCLUDE_DIRECTORIES中。
我們還要告訴編譯器庫文件的位置。在CMake中使用link_directories()指令實現。
link_directories("E:/osg/OpenSceneGraph-3.6.5-VC2019-64-Debug/lib")link_directories()指令告訴鏈接器器搜索庫文件的路徑,把目錄加入到屬性LINK_DIRECTORIES中。
接下來我們還要告訴編譯器,具體鏈接哪個庫文件。在CMake中使用target_link_libraries()指令實現。
target_link_libraries(${PROJECT_NAME} osgdosgViewerd )target_link_libraries()指令指定哪些庫需要鏈接到目標上。本例的目標是最終要生成的exe文件,由上文中add_executable()指令指定,需要鏈接的庫是osgd.lib和osgViewerd.lib。
至此本例的CMake庫配置已經基本完成,目前為止CMakeLists.txt文件的全部內容如下:
project("learn_osg_01")set(OSG_DIR "E:/osg/OpenSceneGraph-3.6.5-VC2019-64-Debug") include_directories(${OSG_DIR}/include) link_directories(${OSG_DIR}/lib)add_executable(${PROJECT_NAME} main.cpp)target_link_libraries(${PROJECT_NAME} osgdosgViewerd )注意到include_directories()指令和link_directories()指令都用到了osg庫的根目錄,本著方便快捷、便于維護的目的,我們使用set()指令把osg庫根目錄賦值給變量OSG_DIR,本文件后續再使用可以直接引用此變量。
接下來我們就可以在代碼中調用osg庫了。
我們創建一個osgViewer::Viewer對象,并運行該Viewer的主循環。main.cpp文件中的代碼改造如下
#include <osgViewer/Viewer> #include <iostream>int main(int argc, char** argv) {std::cout << "Hello, osg!" << std::endl;osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;return viewer->run(); }F7啟動目標生成,可以看到目標已經成功生成。
?此時,您一定迫不及待的要按下F5,想讓程序跑起來了。遺憾的是,目標還不能正常運行,因為找不到動態鏈接庫。
?解決這個問題至少有兩個辦法:
第一個辦法最簡單也最節省硬盤空間,但是如果您在同時開發多個項目,而每個項目使用的osg版本是不同的,那這個辦法會引起意想不到的錯誤;
接下來我們介紹一下第二種辦法。
有同學可能會想到手動去拷貝dll文件,這是一個解決方案但顯然有點low,那有什么看起來比較有調性的方法呢?用CMake!
file(GLOB OSG_DLLS ${OSG_DIR}/bin/*.dll) file(COPY ${OSG_DLLS} DESTINATION ${CMAKE_BINARY_DIR})使用file()指令可自動拷貝源路徑下的所有.dll文件到目標路徑。file()指令可對文件系統進行操作,它的功能遠不止本例中用到的這些,感興趣的同學可以繼續研究一下。
在CMakeLists.txt文件中增加上兩行指令并保存,CMake會自動完成文件拷貝,這時F5啟動程序,您將看到一個全屏顯示的osg窗口,第一個osg程序終于運行起來了!
有的同學要問了:“我不想全屏啟動應用程序怎么辦?”
在main.cpp中添加一行代碼,指定窗口的位置和大小
viewer->setUpViewInWindow(50, 50, 800, 600);運行結果如下圖所示
?至此,一個空場景的osg窗口已經運行起來了。
?CMakeLists.txt的完整代碼是:
project("learn_osg_01")set(OSG_DIR "E:/osg/OpenSceneGraph-3.6.5-VC2019-64-Debug") include_directories(${OSG_DIR}/include) link_directories(${OSG_DIR}/lib)add_executable(${PROJECT_NAME} main.cpp)target_link_libraries(${PROJECT_NAME} osgdosgViewerd )file(GLOB OSG_DLLS ${OSG_DIR}/bin/*.dll) file(COPY ${OSG_DLLS} DESTINATION ${CMAKE_BINARY_DIR})main.cpp的完整代碼是:
#include <osgViewer/Viewer> #include <iostream>int main(int argc, char** argv) {std::cout << "Hello, osg!" << std::endl;osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;viewer->setUpViewInWindow(50, 50, 800, 600);return viewer->run(); }此教程到此可以告一段落了,但是作為一個有追求的程序員,空場景顯然不符合我們的調性,因此我們繼續折騰一下,讓場景里顯示一個三維物體。
4.3一個xue微有點追求的osg程序
我們在場景中創建一個地球模型。
首先在坐標(0,0,0)處創建一個半徑為1.0的球,main.cpp函數中添加代碼:
#include <osg/Geode> #include <osg/ShapeDrawable>...int main(int argc, char** argv) {...osg::ref_ptr<osg::Geode> geode = new osg::Geode;geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(), 1.0f)));viewer->setSceneData(geode);... }編譯運行結果如下:
?這是一個沒有靈魂的球,我們將為這個球注入地球的靈魂,通過——貼紋理。
本例子使用的紋理下載鏈接
?下載后放于"E:/test/"目錄下。
在main.cpp中添加代碼
#include <osg/Texture2D> #include <osgDB/ReadFile>...int main(int argc, char** argv) {...osg::ref_ptr<osg::Texture> texture = new osg::Texture2D(osgDB::readRefImageFile("E:/test/world.png"));auto stateSet = geode->getOrCreateStateSet();stateSet->setTextureAttributeAndModes(0, texture);...}在CMakeLists.txt中添加代碼:
target_link_libraries(${PROJECT_NAME} osgDBd )file(GLOB OSG_PLUGIN_DLLS ${OSG_DIR}/bin/osgPlugins-*/osgdb_png*.dll) file(COPY ${OSG_PLUGIN_DLLS} DESTINATION ${CMAKE_BINARY_DIR})引入osgDB庫,同時將插件庫中的png文件讀寫插件dll拷貝到可執行文件同目錄下。
編譯運行,出現三維地球的場景終于出現了,如下圖
osg默認為我們增加了相機操控器,可以通過鼠標操作瀏覽場景。
按下鼠標坐標左鍵并拖動:旋轉場景;
按下鼠標中鍵并拖動:平移場景;
按下鼠標右鍵并拖動:縮放場景;
鼠標滾輪:縮放場景;
鍵盤空格鍵:恢復初始相機視角;
鍵盤ESC鍵:退出。
本教程的代碼已經全部編寫完成。代碼不多,但篇幅略長,每句代碼都有說明,有些更是踩過坑后總結的經驗,旨在為新手同學提供詳細、友好的入門教程,同時希望對老手也有所啟發。感謝各位能閱讀到此,希望與大家在學習探索osg的旅程上結伴同行。
最后附上完整代碼。
CMakeLists.txt
project("learn_osg_01")set(OSG_DIR "E:/osg/OpenSceneGraph-3.6.5-VC2019-64-Debug") include_directories(${OSG_DIR}/include) link_directories(${OSG_DIR}/lib)add_executable(${PROJECT_NAME} main.cpp)target_link_libraries(${PROJECT_NAME} osgdosgViewerdosgDBd )file(GLOB OSG_DLLS ${OSG_DIR}/bin/*.dll) file(COPY ${OSG_DLLS} DESTINATION ${CMAKE_BINARY_DIR}) file(GLOB OSG_PLUGIN_DLLS ${OSG_DIR}/bin/osgPlugins-*/osgdb_png*.dll) file(COPY ${OSG_PLUGIN_DLLS} DESTINATION ${CMAKE_BINARY_DIR})main.cpp
#include <osg/ShapeDrawable> #include <osg/Texture2D> #include <osgViewer/Viewer> #include <osgDB/ReadFile>#include <iostream>int main(int argc, char** argv) {std::cout << "Hello, osg!" << std::endl;osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;viewer->setUpViewInWindow(50, 50, 800, 600);osg::ref_ptr<osg::Geode> geode = new osg::Geode;geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(), 1.0f)));osg::ref_ptr<osg::Texture> texture = new osg::Texture2D(osgDB::readRefImageFile("E:/test/world.png"));auto stateSet = geode->getOrCreateStateSet();stateSet->setTextureAttributeAndModes(0, texture);viewer->setSceneData(geode);return viewer->run(); }總結
以上是生活随笔為你收集整理的osg开发配置与第一个osg程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: EndNote(参考文献管理软件)官方正
- 下一篇: 教你快速制作出简洁美观的PPT目录页-来