2011年11月21日 星期一

真-OGRE菜鳥教程(2)---基本OGRE程式運作解說

FRIST:瞭解OGRE的架構

OGRE由Root與三大子系統組成,分別是

1.Render Systems:負責Ogre繪圖與底層描繪硬體API(OpenGL, Direct3D)之間的溝通。
2.Scene Management:負責管理3D物件的場景,例如物件的類型、位置、姿態等等。
3.Resource Management:負責3D場景中相關的資源,包括模型、材質、字型等等,資源通常以檔案甚至壓縮檔案的形式存在,因此也包含載入、分配等管理。

OGRE藉著三大系統以及PLUGIN功能,形成了提供穩固核心及擴充彈性的黃金四角!!!

接下來要講解的程式碼與真-OGRE菜鳥教程(1)中的完全相同,只是在這裡筆者分段解釋

首先是第一部份

#include <Ogre.h>//line 0
using namespace Ogre;

int main(int argc, char *argv[])
{

這一部份首先引入的OGRE的表頭檔,並宣告使用OGRE的名稱空間,然後開始main函數,尚無特別之處

/**** **** **** **** **** **** **** ****/

2TH:重要的ROOT

Root *root = new Root( "", "" );     #傳空字串表示不載入資源甘plugin
                                                        #Root()將會載入預設引數的Root(plugins.cfg, ogre.cfg)

接下來的這一行定義了一個Root物件,但是Root物件有啥功能呢?事實上,Root物件代表了Ogre的一切!一旦Root物件被建立,Ogre就算是被啟動。而當Root物件被消滅時,Ogre也就完全結束了。

Root管理所有其他的子系統,提供存取方式,負責取得RenderSystem與創建SceneManager等,在本範例程式中,先呈現Root跟RenderSystem的關係,建立一個單純的Ogre視窗。

/**** **** **** **** **** **** **** ****/
3TH:loadPlugin()

函式將由Root物件呼叫,就像函式名稱一樣,他會載入一個Plugin給Root,而範例程式中


#ifdef _DEBUG                                                        #表示在Debug模式時
    root->loadPlugin( "RenderSystem_GL_d" );     #載入"RenderSystem_GL_d"渲染系統
#else                                                                          #否則(就是Release模式時)
    root->loadPlugin( "RenderSystem_GL" );         #載入"RenderSystem_GL"渲染系統
#endif


是的,RenderSystem是可以作為Plugin一樣由外部插入的,這裡顯示了OGRE的彈性


另外,Plugin是可以重複載入多次的,以下的程式表示要載入Direct3D9的渲染系統,即使直接插入範例中也不會出錯(雖然也沒用)


#ifdef _DEBUG
    root->loadPlugin( "RenderSystem_Direct3D9_d" );
#else
    root->loadPlugin( "RenderSystem_Direct3D9" );
#endif


另外,像"RenderSystem_GL"事實上是一個簡稱,在Windows系統下等同於"RenderSystem_GL.dll",在Linux系統下等同於"RenderSystem_GL.so"(皆表示動態函式庫)


/**** **** **** **** **** **** **** ****/

4TH:設定Root要用的RenderSystem

如同上方的說明,事實上RenderSystem是可以重複載入多個的,因此接下來的

const RenderSystemList &render_sys_list = root->getAvailableRenderers();

#render_sys_list會從root->getAvailableRenderers()那裡取得可用的RenderSystem列表,此表的內容當然就是我們經Plugin給他的東西


RenderSystemList::const_iterator it_rs( render_sys_list.begin() );//line 15

#建立一個佚代器,用於遍歷render_sys_list

while ( it_rs != render_sys_list.end() )//line 17
{
    RenderSystem *render_sys = *(it_rs++);
    if ( render_sys->getName().find( "GL" ) != String::npos )
    {
        root->setRenderSystem( render_sys );
        break;
    }
}
#說白了就是一直找一個叫"GL"的RenderSystem直到找完整個render_sys_list

接著為了預防沒有找到
if ( root->getRenderSystem() == NULL )
{
    delete root;
    return -1;
}
#做一點例外處理


/**** **** **** **** **** **** **** ****/

5TH:來設定視窗囉

接下來的
root->initialise( false );

#root->initialise()函數預設引數為true,刻意改成false表示不使用預設的視窗,而是要自己手動設定,也就是用

RenderWindow *render_win = root->createRenderWindow( "Hello, Ogre!",            320,             240,                              false);
#                                                                                         視窗標題           視窗寬度     視窗高度    是否使用全螢幕狀態
來設定我們的螢幕

但是這只是設定,並不是啟動視窗的指令啊,我們要只是Root該開始渲染了,所以下一行

root->startRendering();     #就是startRendering()讓視窗開始執行囉~~~

    return 0;
}

END:/*心悸了...熬到三點就快掛了*/
接下來來嘗試加點東西到視窗裡吧

沒有留言:

張貼留言