關於 OGRE 與 OSG 的簡單比較
1 前言
我曾經細緻閱讀過 OGRE 和 OSG 官方提供的文檔,有《Pro OGRE 3D Programming》、OGRE內建手冊(manual)、王銳老師等翻譯的《OpenSceneGraph Quick Guide》,同時在網路上查閱了大量的 OGRE 架構源碼分析的文章。簡單使用過 OSG,對 OSG 的情境管理器設計和編程風格有所瞭解,而在近期的項目中大量使用 OGRE,相對於 OSG,對 OGRE 的認識比較深刻一些。目前 OGRE 的最新版本是 1.7,OSG 的最新版本是 2.9.7。
本文是對 OGRE 和 OSG 這兩大三維圖形繪製引擎的一個不全面的個人比較,主要簡單介紹它們在運行效率、平台支援、資源管理、情境樹管理、功能支援、可擴充性、易用性和相關支援方面的異同,而不是評論誰優誰劣(當然本人也沒這資曆),通過瞭解差異後,根
據不同項目要求做出不同選擇。
因為本人使用這兩個繪製引擎的時間不長、運用的功能特性也不全,所以有些比較結論可能不合理,歡迎指正,通過交流,共同進步。
2 繪製引擎簡介
2.1 OGRE
OGRE 是 Object-Oriented Graphics Rendering Engine(物件導向的圖形繪製引擎)的簡稱,是一個用 C++開發的物件導向且使用靈活的 3D 引擎,是一個被廣泛使用的開源三維圖形渲染庫。它成功地被應用於諸多三維模擬領域,其中包括網路遊戲和一些商業的三維模擬項目。
它的目的是讓開發人員能更方便和直接地開發基於 3D 硬體裝置的應用程式或遊戲。引擎中的類庫對更底層的系統庫(如:Direct3D 和 OpenGL)的全部使用細節進行了抽象,並提供了基於現實世界對象的介面和其它類。OGRE 的主要特性有:
效率特性
簡單、易用的物件導向介面設計使你能更容易地渲染 3D 情境,並使你的實現產品獨立於渲染 API(如 Direct3D、OpenGL、Glide 等等)。
可擴充的程式架構(framework)使你能更快的編寫出更好的程式。
為了節省你的寶貴時間,OGRE 會自動處理常見的需求,如渲染狀態管理,空間裁剪,半透物體排序等等。
清晰、整潔的設計加上全面的文檔支援。
在很多商業產品(特別是電子遊戲)上得到應用,並被證實是一個穩定的引擎。
平台和 3D API 支援
支援 Direct3D 和 OpenGL。
多平台支援,支援 Windows(所有版本)、Linux 和 Mac OSX。
在 Windows 平台上可以使用 Visual C++或 Code::Blocks 編譯。
在 Linux 平台和 Mac OSX 平台(使用 XCode)上可以使用 gcc 3+編譯。
材質、Shader 支援
強大的材質聲明語言使你可以在代碼之外維護材質資源。
支援頂點和像素著色器(Shader),同時支援低級的彙編著色器和進階的著色器,如Cg、D3D 中的 HLSL 和 GLSL,並為許多常用的常量提供自動的綁定的,如世界視點矩陣、光照狀態、視點全局座標等。
支援固定渲染管線的全部功能,如多紋理、多遍繪製融合、紋理座標產生和修改、為低端的不可程式化顯卡提供獨立的顏色融合操作。
支援多個材質技術,你可以設計不同顯卡配置的不同技術,OGRE 自動選擇最佳的技術。
支援材質的 LOD;你的材質可以在它們遠離視點時減少資源消耗。
支援從 PNG、JPEG、TGA、BMP 或 DDS 等檔案中載入紋理;支援不常見的 1D 紋理、立體紋理、立體盒紋理和壓縮紋理(DXT、S3TC)。
可以通過外掛程式即時提供及更新紋理,如從視頻上。
支援透射紋理映射(Projective Texturing)。
網格 Meshes
靈活的網格資料格式支援,獨立於頂點緩衝、序號緩衝、頂點聲明和緩衝映射。
支援漸進的網格 LOD,可以自動或手動產生。
支援用 Bézier 樣條實現的曲面。
靜態幾何分批繪製。
動畫
支援複雜的骨骼動畫
靈活的形狀動畫支援
支援情境節點動畫,並提供樣條插值
普通動畫路徑支援可插入的物體適配器(不是很清楚,詳見官網說明)
情境特性
擁有高效率和高度可配置性的情境管理器,並且支援多種情境類型。使用系統預設的場
景組織方法,或通過親自編寫外掛程式使用自己的情境組織方法。
提供的 BspSceneManager 外掛程式是快速的室內渲染器,它支援載入 Quake3 關卡和 shader指令碼分析。
多等級的情境組織體系;情境結點支援物體的附屬(attach),並帶動附屬物體一起運動,實現了類似於關節的運動繼承體系。
特效
粒子系統包括可以通過編寫外掛程式來擴充的粒子發射器(emitter)和粒子特效影響器(affector)。通過指令碼語言可以不用重新編譯就設定和更改粒子屬性。支援並自動管理粒子池,從而提升粒子系統 的效能。
支援天空盒、天空面和天空圓頂,使用非常簡單。
支援公告板,以實現特效。
自動管理透明物體(系統自動幫你設定渲染順序和深度緩衝)
其它特性
資源管理和文檔載入(ZIP、PK3)。
支援高效的外掛程式體繫結構,它允許你不重新編譯就擴充引擎的功能。
運用“Controllers”你可以方便地改變一個數值。例如通過生命值動態改變一個飛船的防護罩的顏色值。
支援記憶體泄露檢測的記憶體調試管理器
通過 ReferenceAppLayer 常式瞭解如何讓 OGRE 與其它庫協同工作,如做碰撞可信度的ODE 庫。
可以用 XMLConverter 讓二進位格式檔案與 XML 相互轉換,方便交流和編輯。
2.2 OSG
OSG 是 OpenSceneGraph 的簡稱,是一個開放源碼、跨平台的圖形開發包。它為諸如飛行器模擬,遊戲,虛擬現實,科學計算可視化這樣的高效能圖形應用程式開發而設計。它基於情境圖的概念,它提供一個在 OpenGL 之上的物件導向的架構,從而能把開發人員從實現和
最佳化底層圖形的調用中解脫出來,並且它為圖形應用程式的快速開發提供很多附加的工具 + 生產力。
它完全是由標準 C++程式和 OpenGL 寫的,充分利用 STL 和設計模式,發揮開源開發模型的優勢來提供一個免費的開發庫,並且重點集中在使用者的需求上。隨著使用一個全特性的情境圖 OpenSceneGraph 的關鍵優勢在於它的效能、可擴充性、可移植性和快速開發
(productivity),更具體的來說:
效能
支援視圖投影剔除(view frustum culling)、隱藏面剔除(occlusion culling)、小特性剔除(small feature culling)、細節層次節點(LOD)、OpenGL 狀態排序(state sorting)、頂點數組、頂點緩衝對象(vertex buffer objects)、OpenGL 著色語言和把顯示列表(display lists)作為情境圖核心的一部分。它們共同使 OpenSceneGraph 成為一個高效能的圖形庫。OpenSceneGraph
也支援繪製流程(drawing process)的定製,比如情境圖的連續細節層次(CLOD)的網格(參見虛擬地形項目和 Delta3D)。
快速開發
情境圖的核心封裝了包括最新擴充的大部分 OpenGL 功能,提供諸如剔除和排序的渲染最佳化功能,同樣提供能快速開發高效能圖形應用程式的一整套補充庫。應用程式開發人員可以更關心實質性內容和如何操控這些它們,而不再是底層的代碼通過學習已有的情境圖,比如:Performer 和 Open Inventor,把它們同像設計模式這樣現代軟體工程理念聯合起來,加上早期開發週期中的大量反饋資訊,設計一個清晰的可擴充的庫已經成為可能。使用者可以很簡單的適應 OpenSceneGraph 並且把它整合到自己的應用程式中
資料裝載
為了讀入和寫出資料庫,資料庫支援庫(osgDB)支援動態外掛程式機制,從而支援大量資料格式,目前的發布版本有 55 種單獨的外掛程式支援 3D 資料和映像格式的裝載。
支援的 3D 資料格式包括 COLLADA、LightWave (.lwo)、Alias Wavefront (.obj)、OpenFlight (.flt),多線程頁面調度支援的 TerraPage (.txp)、Carbon Graphics GEO (.geo)、3D Studio MAX (.3ds)、Peformer (.pfb)、AutoCAd (.dxf)、Quake Character Models (.md2)、Direct X (.x)和 Inventor Ascii 2.0 (.iv)/ VRML 1.0 (.wrl)、Designer Workshop (.dw)、AC3D (.ac) 和內建的.osg ASCII 文字格式設定。
支援的映像格式包括.rgb、.gif、.jpg、.png、.tiff、.pic、.bmp、.dds (包含壓縮的一系列Mip 貼圖影像)、.tga 和 quicktime (在 OSX 環境下),全範圍的高品質、消除鋸齒字型也能通過freetype 外掛程式支援,基於字型的映像也可以通過.txf 外掛程式支援。
使用者也可以通過與一個同盟項目(VirtualPlanetBuilder)產生大規模地形空間資料(multi GB),使 用 OpenSceneGraph 的內建資料分頁調度支援來查看這些資料。
節點工具箱
這個情境圖同樣有一套節點工具集,它們是可以在你的應用程式中編譯或者在運行時裝載的獨立庫:
osgParticle——粒子系統
osgText——高品質消除鋸齒文本
osgFX——特效架構結構
osgShadow——陰影架構結構
osgManipulator——互動控制
osgSim——虛擬模擬相關的效果
osgTerrain——地形繪製
osgAnimation——動畫
osgVolume——體繪製(通過 Dicom 外掛程式支援醫學資料)
可移植性
情境圖的核心已經被設計成盡量少的依賴具體的平台,很少的部分超出了標準 C++程式和 OpenGL。這就使得這個情境圖可以快速移植到大部分系統中——最開始在 IRIX 開發,然後移植到 Linux,接著 到 Windows,再後來就是 FreeBSD, Mac OSX,Solaris,HP-UX, AIX 甚至是 PlayStation2!
完全獨立與視窗作業系統的情境圖核心庫使得使用者在它上面可以增加他們自己的指定視窗庫和應用程式,在發布版本中 osgViewer 庫提供內建視窗支援,可支援 Windows (Win32),Unix (X11) 和 OSX (Carbon)。osgViewer 庫也可以輕鬆的和你的視窗開發包整合起來,作為OpenSceneGraph-2.0 發布版本的一部分,有例子示範了如何在 Qt, GLUT, FLTK, SDL, WxWidget, Cocoa and MFC 中的使用。
延展性
情境圖核心的可擴充性使得它不僅僅可運行在攜帶型裝置,甚至高端的多核、多 GPU的系統和叢集上。這可能是因為情境圖核心為 OpenGL 的顯示列表和紋理對象支援多重圖形渲染環境(multiple graphics contexts),剔除和繪製的遍曆過程被設計成隱藏渲染資料為局部變數,這樣可以以幾乎唯讀方式使用情境圖核心。這樣就允許多對剔除—繪製過程運行在多個 CPU 上,CPU 則是綁定在多個圖形子系統之上。對多圖形裝置渲染環境和多線程的支援可以在 osgViewer 中方便使用,發布版本中所有的例子都可以以多線程和多 GPU 的方式運行。
多語言支援
OpenSceneGraph 以社區項目的形式支援多種語言,比如 Java,Lua 和 Python。
3 OGRE 與 OSG 的異同
通過上一節的簡介可以大致瞭解到這兩大 3D 繪製引擎的功能特性,同時也容易察覺到兩者的異同。下面就兩者的具體說明:
設計和體系
如果你曾經使用傳統而基本的方法進行過 3D 應用程式開發(換句話說,就是有使用OpenGL 或者 Direct3D 這種底層 API 的經驗),你會瞭解到它們有一些相似而且繁瑣的過程:
通過調用 API 設定渲染狀態;通過調用 API 傳送幾何體資訊;通過調用 API 通知 GPU 渲染;清理;返回到第一步,直到渲染完一幀進入下一幀。這個過程會讓你陷入紛雜的 API 操作之中,相對於真正的應用,可能你會被浪費在基本的幾何體操作中去。如果使用物件導向的方法來渲染幾何體,就可以從幾何體層級的處理工作中抽離出來,轉而處理具體的情境和在情境中的物體。其中的物體包括:可活動的物體、靜態物體組成的情境本身、燈光、攝像機以及其他。你只需簡單的把物體放到情境之中,OGRE 或 OSG 繪製引擎可以協助你完成雜亂的幾何渲染處理。也是為什麼我們在開發 3D 應用程式時不直接使用 OpenGL 或 D3D 的原因。
OGRE 和 OSG 在架構設計上存在著許多共同之處,都是為了兼顧系統的高效性、可移植性和可擴充性,採用了以下設計理念和工具進行系統的設計和構建:
ANSI 標準 C++
C++標準模板庫(STL)
設計模式(Design patterns, Gamma95)
通過設計模式的一些模式如 Abstract Factory、Listener、Adopter、Singleton 等,提高程式庫的擴充性並易於與其它庫協同工作。如 OSG 和 OGRE 庫都有大量的功能強大外掛程式支援,並可以同第三方介面庫(如 Qt、MFC、WxWidget 等)分工合作。
但兩者也存在著一些明顯的不同之處。OGRE 從它的命名上可以直接看出,它是一個物件導向的三維繪製引擎。相比 OpenGL 和 D3D 的顯明帶有面向過程特徵的 API,經過抽象的物件導向 API 更簡明,使用更方便。而 OSG 是在 OpenGL 基礎上提供了很多使用方便的功能包,並沒有對底層圖形介面(OpenGL)進行抽象。下面《Pro OGRE 3D Programming》中關於物件導向的優勢所在的論述:
嗯,現在的圖形引擎就像任何龐大的軟體系統。在一開始很苗條,但很快變成驚人複雜的怪獸,讓人難以理解它。這樣大的系統難於管理,任何對系統的修改都可能影響其可靠性。而在這樣一個不斷出現新技術和手段的領域,修改又是必不可少。大量的使用 c 函數調用也無法對這一情況有任何改善 —— 即使所有的函數都是同一個人寫的。通常會發現,幾個月以後,一小段代碼也會變得複雜難懂;該如何組織這些函數也會變成一個難題。
面對對象是解決複雜性問題的一個常用手段。它逐步的把代碼分解到函數中,把函數和表示狀態的資料用類組織起來,以表示現實中的各種概念。它能讓你把複雜性隱藏在容易確定的程式碼封裝當中,只暴露出簡單易用的介面。這樣你就有了可以搭建在一起的“建築材料”。你也可以通過組織這些材料使它們有一致的外部介面,而在內部,實現這些介面的方法卻各不相同。這同樣減少了複雜性,因為開發人員只需要學習一種介面。
同時,OGRE 只專註於繪製,不負責其它模組,如使用者介面、聲音、網路、碰撞檢測等,其它模組都是以外掛程式的形式存在。而 OSG 提供了更多的功能,如前者所沒有的功能,如虛擬模擬、體繪製、分頁地形載入(最新 OGRE1.7 也引入了部分相關功能)等。所以如果是要利用現有成熟模組的項目可以使用 OSG,而需要開發更成熟更商業化的產品可以使用OGRE。
平台支援
從前面的特性分析可以看出,OGRE 與 OSG 對平台的支援的側重點有所不同,如 OGRE側重於成熟的商業化的平台,如 D3D 及主流圖形作業系統,從而可以。而 OSG 強調支援多個作業系統,如 FreeBSD、Solaris、HP-UX、AIX 等,只要是支援 OpenGL 的平台,OSG 就有可能支援。由於大部分遊戲及商業軟體是基於 D3D 的,而 OGRE 對 D3D 提供了很好的支援,所以如果是開始遊戲,OGRE 是一個很好的選擇。
資源管理
不管地形、紋理還是字型等一切對象,繪製它們都需要不同的資源。如何載入、重用、卸載這些資源是非常重要的,因此,有專門的一批類來完成這些事情。OGRE 提供了一個功能完美的資源管理系統,包括對材質、Shader、粒子系統等一系列資源的分離於代碼外的管理。OGRE 定義了功能強大的材質聲明檔案,可以在檔案中直接定義紋理、繪製狀態、Shader等資訊,從 OGRE1.6 起還支援簡單的變數和聲明繼承等,極大的方便了資源管理工作,更代碼思路更清晰。
在圖形引擎中,有大量的狀態管理和上下文相關操作的代碼。封裝能把這些代碼放在獨立的資源聲明檔案中,這樣以來代碼就更容易理解。而且由於封裝避免了複製代碼方式的重用,也使得程式變得更可靠。且這些資源聲明檔案也是獨立於平台的,這是 OGRE 作為一個成熟的 3D 繪製引擎的一個重大特性。
情境樹管理
OGRE 與 OSG 都有一個情境樹在管理整個情境的相關資訊,通過情境樹可以方便的管理情境物體,並且在向底層介面提交繪製操作前進行一些軟裁剪和繪製順序調整工作。同時OGRE 與 OSG 的情境樹上每個節點所代表的內容是不同的。
首先,Ogre 對情境圖的操作維持在介面層級;它並不關心去操作圖形的具體演算法實現。換言之,Ogre 只是通過 API 來操作環境圖,進而忽略了具體的演算法實現。其次,Ogre 的情境圖介面只負責維護情境結構。節點中沒有包含任何固有的內容和管理方法。具體的內容被
放置到一種可渲染(Renderable)對象之中,它提供了情境中全部幾何圖形(包括活動的的或者其他所有的)。它們的渲染的屬性(也可以說是材質)被包含在實體(Entity)對象中,在實體物件裡面同樣包含著一個或多個子實體(SubEntity)對象,這些子實體才是是真正可
以被渲染對象。
情境圖形樹結構的頂部是一個根節點。從根節點向下延伸,各個組節點中均包含了幾何資訊和用於控制其外觀的渲染狀態資訊。
ORGE《Pro OGRE 3D Programming》中提到:
雖然沒有得到權威的論證,但我還是堅信情境圖和情境內容的分離的設計一定是整個Ogre 項目中最亮眼的地方。雖然看起來它是一個如此的簡單易懂,不過對於那些仍然堅守“傳統的設計方法”來完成情境圖設計的人仍然會難以理解。
在傳統設計中(就是很多商業和開源 3D 引擎所採用的)將情境內容和情境結構放到一個繼承體系中,並將情境內容生硬的作為情境節點的子類。我斷言這是一個極其失敗的設計方案。如果不修改所有的子類,基本上是沒有辦法更改或者擴充圖形演算法的,因此讓修改基類的介面非常困難,進而導致以後的維護工作變得舉步維艱。此外這種“所有節點源自同一節點類型”的設計思想會讓整個程式變得凝固且難以複用(至少從維護的觀點看):
當增加新的基類功能方法或者屬性的時候,不管是否真的需要,這些都強迫的塞入所有子類。最後導致哪怕是對準系統做很小的修改,都會牽一髮會動全身, 導致開發維護最終變得難與控制。這種糟糕的設計理念讓陷入的人們痛苦不堪,從而希望擺脫這種邏輯採用全
新的設計方法。
可以看出 OGRE 是出於可維護性和可擴充性才選擇這種情境樹管理方式的。配合 OGRE強大的代碼資源分離功能,及可擴充的多情境管理器支援能力,這種簡明的情境樹管理設計取得了重大成功。
易用性
為了使代碼可以支援 D3D 和 OpenGL 引擎,OGRE 編程中不推薦直接使用 D3D 或 OpenGL的 API,且繪製流水線與底層的 API 有一定區別,這就提高了入門難度,加大了學習曲線的陡峭程度。而OSG 只是基於OpenGL 單個底層API 的,所以可以直接在OSG 工程中加入 OpenGL的 API 呼叫,且一般情況下只也是唯一方案,如要使用 OSG 所沒包括的新的 OpenGL 擴充。
從這點來看 OSG 比較適合要用到新的顯卡技術的項目,而 OGRE 比較適合技術通用、成熟且要求使用更適合遊戲的 D3D 引擎的項目。如前面提到的 OGRE 有一個強大的、功能齊全的資源管理員,可以大大減輕資源管理複雜度,提高資源載入、分配和利用效率。這有助於把美工、效果與代碼分離,使編程時邏輯更清晰。這是程式設計的一個主流方向,如 Nokia的 Qt 使用者介面庫就是一直朝這個方向發展的。
相關支援
OGRE 與 OSG 在對一些資源和功能的支援上也存在這差異,如 OGRE 沒有提供像 OSG 那樣廣泛的 Mesh 檔案格式支援。其實 OGRE 只支援自身特有的.mesh 檔案支援,而其它模型只能通過轉換到這種格式才可以載入。同時 OGRE 也沒有提供輸入輸出相關支援,需要通過獨立模組 OIS(Object Oriented Input System)來支援輸入輸出操作。總的來說,OGRE 專註於 3D 繪製,而 3D 應用程式所需要的其它功能可以由外掛程式或其它庫完成。相對而言,OSG提供的支援會多些,如體繪製(osgVolume)、模擬類比(osgSim)、聲音支援(osgAL)等模組。
4 小結
本文簡單介紹了一些 OGRE 與 OSG 的一些特性及之間的功能對比,在簡化 3D 圖形編程在設計理念下,兩者又保持著自己獨特的設計路線。OGRE 的特色在於成熟的設計模式、出色的資源管理方式和良多的跨平台性(特別是支援 D3D);OSG 的特色在於豐富的相關開源項目和文檔、很多現成的功能模組。
同是開源項目,OSG 由一個超過 200 人的大規模開發隊伍,而 OGRE 卻擁有一個精小強悍的Team Dev(現在共 7 人)。OGRE 相對而言比較活躍,功能更新頻繁,這對於技術變化快速的圖形繪製領域是重要的。至今,已有多款商業遊戲使用了 OGRE 圖形繪製引擎,如國內的網路遊戲“天龍八部”、近期流行遊戲“火炬之光”(Torchlight 2009.10)、網遊“Zero Gear”等。OSG 偏向於虛擬模擬領域,強調庫的功能勝於程式設計理論。兩者都擁有著強大的開源社區,並是開源項目,隨時可以方便的查看原始碼,這對於開發應用程式是很有協助的。
5 參考文獻
[1]. OpenSceneGraph Quick Start Guide,Paul Martz[美],王銳 錢學雷 譯,2007
[2]. Pro OGRE 3D Programming,Gregory Juker,邸銳 李旭東 譯,2006
[3]. OGRE Manual v1.7 ('Cthugha'),http://www.ogre3d.org/docs/manual/
[4]. OGRE Features,http://www.ogre3d.org/about/features
[5]. OSG Introduction,http://www.openscenegraph.org/projects/osg/wiki/About/Introduction