Irrlicht編程基礎

來源:互聯網
上載者:User

一、Irrlicht引擎簡介

Irrlicht引擎是一個用C++編寫的高效能即時3D引擎。該引擎支援底層圖形介面Direct3D和OpenGL,並且內建了軟體渲染的實現。Irrlicht引擎還提供了諸如動態陰影,粒子系統,角色動畫,室內和室外技術以及碰撞檢測等功能特性。

Irrlicht是一個德國神話故事中的一種動物的名字,它能夠發光和飛翔,可以在大部分的沼澤地附近發現它。單詞"Irrlicht"是兩個德國單詞("irr"意思是瘋狂的;而"Licht"意思是光)的組合。在英語中,它被譯為"鬼火"。 

二、Irrlicht引擎的組成結構

Irrlicht引擎共分為五部分:

1)Core

該部分由一些容器類及數學庫組成,如string、vector等。

對應的名字空間為:namespace irr::core

2)Scene

該部分主要負責三維情境的繪製及管理,包括情境節點,攝像機,粒子系統、mesh 資源,公告板,燈光,動畫器,天空體,地形等。

Irrlicht的情境中的所有的東西都是情境節點,統一由情境管理器來管理。

對應的名字空間為:namespace irr::scene

3)Video

該部分主要負責圖片紋理的載入及管理,包括紋理,材質,燈光,圖片,頂點等渲 染屬性的控制。

對應的名字空間為:namespace irr::video

4)GUI

該部分包括了一些二維GUI控制項

對應的名字空間為:namespace irr::gui

5)FileSystem

該部分負責檔案系統的讀寫。

對應的名字空間為:namespace irr::io

三、Irrlicht編程步驟

1、擷取裝置指標

在編寫任何一個Irrlicht程式時,首選需要做的就是擷取裝置指標 

IrrlichtDevice  *device :

 video::E_DRIVER_TYPE driver_type = irr::video::EDT_OPENGL;   

 core::dimension2d<s32> screen_resolution = core::dimension2d<s32>(1280, 800);   

 u32 color_depth = 32;   

 bool is_full_screen = true;   

   

 IrrlichtDevice* device = irr::createDevice(driver_type, screen_resolution, color_depth, is_full_screen); 

driver_type為驅動類型,可以選擇OPENGL,DX8 或 DX9。其餘幾個參數分別為解析度,顏色 深度,是否全屏。

獲得 device 指標以後,就可以得到屬於該 device 的四大塊功能:

video::IVideoDriver* driver = device->getVideoDriver();   

scene::ISceneManager* scene_mgr = device->getSceneManager();   

gui::IGUIEnvironment* gui_env = device->getGUIEnvironment();   

io::IFileSystem* file_system = device->getFileSystem();  

2、建立3D情境

建立3D情境有三個步驟:

(1) 通過情境管理器scene_mgr添加3D物體:

 // 為情境添加一個立方體,邊長100  

 scene::ISceneNode* cube = scene_mgr->addCubeSceneNode(100.0f);   

(2) 為3D物體貼上紋理:

 // 載入紋理  

 video::ITexture* tex = driver->getTexture("box.jpg");   

   

 // 將紋理附加到立方體上  

 cube->setMaterialTexture(0, tex);   

   

 // 將紋理EMF_LIGHTING屬性設為false  

 // 表示該紋理現實與光源無關,即為圖片自身顏色  

 cube->setMaterialFlag(video::EMF_LIGHTING, false);   

   

 // 使紋理支援半透明,半透明效果與圖片相同  

 cube->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL);   

(3) 添加Camera,使物體可見:

 // 添加一個相機,在(700,700,-700)位置,往(0,0,0)位置拍攝。  

 scene::ICameraSceneNode* camera = scene_mgr->addCameraSceneNode(0,    

     core::vector3df(700,700,-700), core::vector3df(0,0,0));  

3、進入主迴圈

通過 driver 載入圖片和 texture,通過 scene_mgr 為3d情境添加 irrlicht 內建支援的3D對象等工作後,即可進入主迴圈,主迴圈結束時,釋放 device,程式結束。其中 beginScene 的參數 SColor(alpha, r, g, b) 為背景色:

1 while (device->run())   

2 {   

3     if (device->isWindowActive())   

4     {   

5         driver->beginScene(true, true, video::SColor(0, 0, 0, 0));   

6         scene_mgr->drawAll();   

7         gui_env->drawAll();   

8         driver->endScene();   

9     }   

10 }   

11 device->drop();  

值得一提的是 drop() 函數。Irrlicht中大部分類都繼承自一個 IReferenceCounted 的介面,類似智能指標。Irrlicht 中的慣例是不使用 delete 刪除對象,而調用該介面的 drop() 函數。在添加對象的引用時,調用 grap() 函數。

四、Irrlicht引擎之情境中的對象結構

3D對象在情境中被組織成一個樹形結構,在該樹中,僅有一個根節點。當在程式的主迴圈中調用scene_mgr->drawAll()時,系統會從情境的樹形結構的根節點開始遞迴繪製所有的節點對象。

每一個節點對象都維護了一個“動畫效果”ISceneNodeAnimator列表:

core::list<ISceneNodeAnimator*> Animators;

在繪製每一個節點對象之前,都會將其所維護的所有動畫效果應用到該節點上。

“動畫效果”的原理是,當節點每次被繪製之前,均先根據其維護的動畫對象Animators來計算出該節點的位置、大小、紋理。這樣,當一個節點不斷被繪製時,就產生了動畫效果。

五、Irrlicht引擎之3D對象運動原理

所謂運動,實際上是電腦在不停地繪製情境,每繪製一次稱之為一幀。 當各幀中物體的位置或外觀有所變化,那麼它就動起來了。 在irrlicht中,繪製一幀是在run迴圈中完成的:

1 while (device->run())   

2 {   

3     if (device->isWindowActive())   

4     {   

5         driver->beginScene(true, true, video::SColor(0, 0, 0, 0));   

6         scene_mgr->drawAll();  // 繪製一幀  

7         driver->endScene();   

8     }   

9 }   

10 device->drop();  

我們所要做的,就是在 drawAll() 函數中,更新物體的位置及大小等屬性,那麼情境就動起來了。

在Irrlicht中,所有與運動相關的一切,都與 scene::ISecenNodeAnimator 這個介面相關。凡是實現這個介面的類執行個體,都可以通過 addAnimator() 函數加入到 ISceneNode 所維護的animators列表中。 

SceneManager 的drawAll() 函數在渲染(render)情境前,會調用其OnAnimate() 函數。這個函數是遞迴的,以保證加入情境中的每個 SceneNode 都會被調用。 在OnAnimate() 函數中, SceneNode 的每一個 ISecenNodeAnimator 的 animateNode() 函數都會被調用,以更新 SceneNode 的位置、大小或紋理等屬性。 

其具體的調用順序如下: 

1. SceneManager           --> drawAll()                 繪製一幀畫面

2. ISceneNode             --> OnAnimate()              SceneNode運動  

3. ISceneNodeAnimator --> animateNode(ISceneNode)      實現運動的具體函數

4. SceneManager           --> render()                  渲染

 

可見,只要實現 ISecenNodeAnimator 介面,並加入到 SceneNode 中,就能夠讓該SceneNode 運動起來。而至於具體如何運動,完全可由自己來定義。

六、Irrlicht引擎之訊息傳遞原理

Irrlicht引擎中訊息的傳遞是從device->run()開始的,首先由具體平台的作業系統介面將接收到的使用者訊息打包成Irrlicht的SEvent結構(這一步打包過程是在device->run()中完成的),再由postEventFromUser()將該訊息依次傳遞給UserReceiver, GUI 和 3D Scene。

Irrlicht 中所有處理訊息的類都必須實現 IEventReciever 介面。UserReceiver 就是在CreateDevice函數中指定的一個 IEventReceiver。 也就是說,訊息處理的優先順序為 UserReceiver > GUI > 3D Scene。

如果在程式中,沒有指定UserReceiver和GUI,訊息就會直接交給SceneManager。

SceneManager 的訊息,也由 ISceneManager 的 postEventFromUser() 傳遞。 這個函數的實現如下:

1 bool CSceneManager::postEventFromUser(const SEvent& event)   

2 {   

3     bool ret = false;   

4     ICameraSceneNode* cam = getActiveCamera();   

5     if (cam)   

6         ret = cam->OnEvent(event);   

7   

8     _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;   

9     return ret;   

10 }  

也就是說,只有當前Active(有效)的 ICameraSceneNode 才會接收到訊息。ICameraSceneNode 會檢測ISceneNodeAnimator 的isEventReceiverEnabled(), 如果為真則調用其OnEvent 函數。 

整理訊息傳遞的機制如下:

 

1. IrrlichtDevice           --> run()                      搜集訊息並打包

2. IrrlichtDevice           --> postEventFromUser()    傳遞訊息到userReceiver     GUI 和 Scene

3. ISceneManager         --> postEventFromUser()       傳遞訊息到CameraNode

4. ICameraSceneNode     --> onEvent()                  調用 Animator 的onEvent

5. ISceneNodeAnimator    --> onEvent()  // if enabled      響應訊息。

 

可見,實現 ISceneNodeAnimator 雖然可以 SceneNode 動起來,但只有在 ICameraSceneNode 上,才能夠接收和處理訊息。

 

參考資料:http://arec.iteye.com/blog/338135

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.