irrlicht是跨平台,支援多種圖形庫的開源3d引擎。irrlicht的設計很好的體現了介面和實現分離的原則,整個架構設計精巧清晰,是學習3d引擎設計的不錯的教材。
先看下名字空間的劃分,可以看到irr具有非常清晰的結構:
irr Everything in the Irrlicht Engine can be found in this namespace
irr::core In this namespace can be found basic classes like vectors, planes, arrays, lists and so on
irr::gui The gui namespace contains useful classes for easy creation of a graphical user interface
irr::io
irr::scene
irr::scene::quake3
irr::video The video namespace contains classes for accessing the video driver. All 2d and 3d rendering is done here
irr空間中提供了引擎的一些底層構架的支援,如事件處理系統,作業系統抽象,引用計數,裝置抽象等。
irr::core空間中提供了基礎的數學和資料結構構件,如向量,矩陣,四元數,列表,數組,紅/黑樹狀結構等。
irr::io空間提供了io操作的構件並提供對象屬性序列化和xml支援。
irr::video空間包含了3d圖形功能介面和構件。如對圖形驅動,材質渲染的抽象。
irr::scene空間包含了基於scene graph的3d引擎渲染和管理,並提供了camera,骨骼動畫,粒子系統等的豐富支援。
irr::gui空間包含了irrlicht的GUI模組,同樣也是基於介面的設計。
我想重點剖析的是irr::video和irr::scene,這是3d引擎的核心部分,目的是分析irrlicht是如何將不同的圖形API進行抽象的,以及如何使用scene graph-material體系進行引擎的運轉,並將各種3d技術融入到這個體系中的。另外irr如何做到跨平台支援的也會進行剖析。
作為引擎的概覽,首先看下文檔中的short example:
IrrlichtDevice *device = createDevice (video::EDT_DIRECT3D8 , core::dimension2d(640,480)); video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* scenemgr = device->getSceneManager();
這三句代碼顯示了irrlicht最基本的三個對象-裝置,圖形驅動和情境管理器。簡單看來,通過全域函數createDevice根據指定的驅動類型建立一個裝置,之後可通過裝置對象得到驅動對象以及情境管理器對象。
device->setWindowCaption(L"Hello World!" );
裝置對象具有一些裝置相關的能力,比如這兒可以設定視窗標題。
// load and show quake2 .md2 model
scene::ISceneNode* node=scenemgr->addAnimatedMeshSceneNode(scenemgr->getMesh("quake2model.md2" ));
// if everything worked, add a texture and disable lighting
if (node)
{
node->setMaterialTexture(0, driver->getTexture("texture.bmp" ));
node->setMaterialFlag(video::EMF_LIGHTING , false );
}
// add a first person shooter style user controlled camera
scenemgr->addCameraSceneNodeFPS();
這幾行代碼顯示了scene graph體系,ISceneNode是irrlicht情境中基礎組成部分節點的抽象,這兒添加了一個動畫mesh節點,和一個camera節點。節點具有材質屬性(當然camera並不需要材質,但是ISceneNode作為一個抽象要盡量兼顧各種節點,為了讓介面的層次簡單些,這樣做也是一個實用的方法)
// draw everything
while (device->run() && driver)
{
driver->beginScene(true , true , video::SColor(255,0,0,255));
scenemgr->drawAll();
driver->endScene();
}
這幾行是引擎運轉的過程,首先引擎運轉的條件是裝置仍然在運轉:device->run(),可通過closeDevice關閉裝置。 scenemgr->drawAll()執行了所有節點的渲染,節點的渲染不僅僅是draw,節點的transform計算,動畫計算(包括骨骼動畫),camera這種特殊節點的操作(特殊的節點還有光源等),都包含在渲染的範疇中,在drawAll中統一調用,各種節點實現各自的渲染,最終由 scenemgr統一管理(如排序)繪製,這正是基於scene graph架構的引擎的特點之一。
device->drop();
這一句體現了irrlicht的引用計數機制,通過grab,drop管理對象引用次數。這兒如果一切正常應該是引用drop為0,device銷毀自己,退出程式。
從這個很短的例子可以看到irrlicht的基本構件和運行過程。irrlicht提供了scene的管理機制,並提供了大量預定義好的scene nodes,實現了很多的功能,這樣你就可以很方便的使用引擎。並且這種機制的好處是,節點可以不斷的擴充,並可以在以後的項目中複用。
當然,irrlicht引擎不是完美的,我準備在這個源碼剖析的系列的最後,分析一下irrlicht的一些具體問題和不足,當然作為一個開源引擎,irrlicht已經非常好了,我的主要目的正是通過分析學習irrlicht給自己設計3d引擎打一個基礎。
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/n5/archive/2009/07/05/4323332.aspx