Awen's Blog

Sharing, Always Sharing ...
  首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1. Abstract
建立最基礎的 Irrlicht 3D 引擎的應用框架。(for vc2008)

2. Introduction
2-1. 這個框架是我們在讀 Irrlicht 的一系列範例教學最基礎的部份,在官方的教學範例中大部份都由這個框架開始展開。

2-2. 關於專案檔的建立請參考這邊:
http://www.gamelife.idv.tw/viewtopic.php?t=1617

2-3. 現在讓我們一步一步來慢慢完成這框架。

STEP1. 應用程式的入口函式:

int main(int argc, char **argv)
{
    return 0;
}

a. 加入專案的第一隻檔案也是唯一的叫 "main.cpp"
b. 加入入口函式 (the entry point of application)
 

STEP2. 引入 Irrlicht 3D 引擎的表頭檔:

#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
#include <irrlicht.h>

int main(int argc, char **argv)
{
    return 0;
}

a. _MSC_VER 這個 Macro 表明我們是使用 vc 系列的編譯器,它表示 vc 編譯器的版本資訊。
b. #pragma comment(lib, "Irrlicht.lib") 告訴 Linker 我們要需要聯結這個函式庫進來。

STEP3. 建立 Irrlicht 3D 引擎最重要的物件 irr::IrrlichtDevice:

#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
#include <irrlicht.h>

int main(int argc, char **argv)
{
    irr::IrrlichtDevice *device = irr::createDevice(irr::video::E_DRIVER_TYPE::EDT_DIRECT3D9,
                                                    irr::core::dimension2du(1024,768),
                                                    32, false, false, false, 0);
    if(!device)
        return 1;

    return 0;
}

a. 這裡我們不用 namespace 將 Irrlicht 3D 引擎中相關的名稱空間都 export 出來,而是全都都寫上讓大家可以知道他在那個 namespace 中。
b. 關於 createDevice 函式說明如下:
param1: irr::video::E_DRIVER_TYPE::EDT_DIRECT3D9 表示我們希望用 direct3d9 當我們底層的3D處理函式庫。除了d3d9我們還可以選 OpenGL 等...。
param2: 視窗的大小, 這裡我們希望有一個 1024x768 大小的視窗。
param3: 顏色深度。
param4: 是否使用全螢幕模式。
param5: 是否使用 Stencil Buffer。(如果我們希望有陰影時這個要打開)
param6: 是否使用垂直同步。(一般而言我們希望自己控制 rendering 的速度)
param7: 這裡是一個 irr::IEventReceiver 的指標, 當我們需要自定一些我們自己的鍵盤或滑鼠的控制,我們需要寫一個繼承於 irr::EventReceiver 的類別。


STEP4. 取得 Irrlicht 3D 引擎中的相關的管理器。

#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
#include <irrlicht.h>

int main(int argc, char **argv)
{
    irr::IrrlichtDevice *device = irr::createDevice(irr::video::E_DRIVER_TYPE::EDT_DIRECT3D9,
                                                    irr::core::dimension2du(1024,768),
                                                    32, false, false, false, 0);
    if(!device)
        return 1;

    irr::video::IVideoDriver  *driver = device->getVideoDriver();    // 取得影像驅動器: 管理底層的 3D API 處理函式庫。
    irr::scene::ISceneManager *smgr   = device->getSceneManager();   // 取得場景管理器: 管理場景中的 Mesh, Node, Camera 等等...
    irr::gui::IGUIEnvironment *guienv = device->getGUIEnvironment(); // 取得GUI管理器: 管理UI的。

    return 0;
}

 
STEP5. 建立遊戲迴圈: Game-Loop

#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
#include <irrlicht.h>

int main(int argc, char **argv)
{
    irr::IrrlichtDevice *device = irr::createDevice(irr::video::E_DRIVER_TYPE::EDT_DIRECT3D9,
                                                    irr::core::dimension2du(1024,768),
                                                    32, false, false, false, 0);
    if(!device)
        return 1;

    irr::video::IVideoDriver  *driver = device->getVideoDriver();    // 取得影像驅動器: 管理底層的 3D API 處理函式庫。
    irr::scene::ISceneManager *smgr   = device->getSceneManager();   // 取得場景管理器: 管理場景中的 Mesh, Node, Camera 等等...
    irr::gui::IGUIEnvironment *guienv = device->getGUIEnvironment(); // 取得GUI管理器: 管理UI的。

    while(device->run())
    {
        if(device->isWindowActive())
        {
            driver->beginScene(true, true, irr::video::SColor(255,100,100,140));
            smgr->drawAll();
            guienv->drawAll();
            driver->endScene();
        }
        else
        {
            device->yield();
        }
    }

    return 0;
}

a. 遊戲迴圈從一個 while(device->run()) 開始,當收到 WM_QUIT 結束迴圈。
b. if(device->isWindowActive()) 表示我們希望當視窗是作用中的狀態才去做繪圖。
c. 真正的繪圖發生在 driver->beginScene() 跟 driver->endScene() 中。
d. irr::video::SColor(255,100,100,140) 它的格式為 A,R,G,B 這裡表示我們希望在繪圖前先把畫布清為我們指定的顏色。

STEP6. 釋放資源

#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
#include <irrlicht.h>

int main(int argc, char **argv)
{
    irr::IrrlichtDevice *device = irr::createDevice(irr::video::E_DRIVER_TYPE::EDT_DIRECT3D9,
                                                    irr::core::dimension2du(1024,768),
                                                    32, false, false, false, 0);
    if(!device)
        return 1;

    irr::video::IVideoDriver  *driver = device->getVideoDriver();    // 取得影像驅動器: 管理底層的 3D API 處理函式庫。
    irr::scene::ISceneManager *smgr   = device->getSceneManager();   // 取得場景管理器: 管理場景中的 Mesh, Node, Camera 等等...
    irr::gui::IGUIEnvironment *guienv = device->getGUIEnvironment(); // 取得GUI管理器: 管理UI的。

    while(device->run())
    {
        if(device->isWindowActive())
        {
            driver->beginScene(true, true, irr::video::SColor(255,100,100,140));
            smgr->drawAll();
            guienv->drawAll();
            driver->endScene();
        }
        else
        {
            device->yield();
        }
    }

    device->drop();
    return 0;
}

a. device->drop() 釋放掉先前由 createDevice 所建立的相關資源。像是影像驅動器、場景管理器、場景管理器等。當然由自己建立就自己去Release了。
b. 關於釋放資源這個部份,就要請大家自己參考 irr::IReferenceCounted。Irrlicht 3D 引擎採用一種引用計數的策略來做管理,這個部份就不在今日的主題上了。
c. 整個來說這就完成最基礎的 Irrlicht 3D 引擎的應用框架。

3. Conclusion
1.在學習 Irrlicht 3D 引擎您必須要會C++,這是必須的因為它是用C++寫的。
2.在學習 Irrlicht 3D 引擎是否需要先學 Direct3D 或 OpenGL與電腦圖學,就小弟的經驗上來說他是可以同時進行的,但學習沒有法則因人而異
3.一般來說就入門來講,不懂 Direct3D 或 OpenGL 或電腦圖學並不影響,但要深入的話左述所提的部份還是須要的。

4. Reference
1. http://irrlicht.sourceforge.net/

 

範例檔