1. 程式人生 > >OGRE 引擎官方基礎教程 (一)

OGRE 引擎官方基礎教程 (一)

先決條件:

1.本範例假設你能夠設定和編譯一個OGRE應用程式,具體方法見設定方法,並且具備一定的

C++語言程式設計基礎。

開始工作:

建立一個工程,命名為Tutorial,這裡採用 Visual Studio 2010,加入下列檔案
BaseApplication.h
BaseApplication.cpp
TutorialApplication.h
TutorialApplication.cpp
我們只對於TutorialApplication.cpp中的createScene()成員函式進行操作 如下所示:
#include "TutorialApplication.h"
 
TutorialApplication::
TutorialApplication(void) { }   TutorialApplication::~TutorialApplication(void) { }   //------------------------------------------------------------------------------------- void TutorialApplication::createScene(void) { // Set the scene's ambient light mSceneMgr->setAmbientLight(Ogre::ColourValue
(0.5f, 0.5f, 0.5f));   // Create an Entity Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");   // Create a SceneNode and attach the Entity to it Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode"); headNode->attachObject(
ogreHead);   // Create a Light and set its position Ogre::Light* light = mSceneMgr->createLight("MainLight"); light->setPosition(20.0f, 80.0f, 50.0f); }       #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #define WIN32_LEAN_AND_MEAN #include "windows.h" #endif   #ifdef __cplusplus extern "C" { #endif   #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) #else int main(int argc, char *argv[]) #endif { // Create application object TutorialApplication app;   try { app.go(); } catch( Ogre::Exception& e ) { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR| MB_TASKMODAL); #else std::cerr << "An exception has occured: " << e.getFullDescription().c_str() << std::endl; #endif }   return 0; }   #ifdef __cplusplus } #endif
編譯執行之後效果如下: Image
這是一個簡單的場景,裡面有一個物體,可以通過WSAD按鍵進行簡單的漫遊,按Esacpe鍵可以退出 關於工程配置的一些說明: 當我們執行一個OGRE工程的時候,我們需要把DLL檔案,以及.cfg配置檔案,移動到與生成的exe檔案同一 目錄下,比如在Visual Studio 2010下,[ProjectFolder]\bin\release或者[ProjectFolder]\bin\debug 注意: .cfg檔案可能需要修改,使得它們的配置指向的資原始檔的路徑是正確的,非常重要! 在exe檔案目錄下至少需要包含 resources.cfg 和 Plugins.cfg。 前者告訴OGRE採用何種渲染引擎(比如D3D或者OpenGL),後者註明使用到的資源(材質textures, 實體meshes, 指令碼scripts)等等 它們都是文字檔案,可以直接編輯修改。 如果配置不正確,可能出現找不到動態連結看,或者找不到資源的錯誤! 比如
Description: ../../Media/packs/OgreCore.zip - error whilst opening archive: Unable to read zip file
這就說明找不到資原始檔的所在,需要配置resources.h檔案

OGRE的基本工作方式:

這是一個非常寬泛的話題,我們通過“場景管理器SceneManagers ”,引入實體Entities 和場景結點SceneNodes的概念,它們是一切的基礎 場景管理器SceneManager  所有螢幕上看到的東東都被它所管理,它會記錄所有出現的東西的位置locations,當你建立相機camerers來觀看場景 的時候呢,場景管理器會追蹤這些物體。當你建立平面,光照等的時候,場景管理器也會跟蹤它們 有許多種類的場景管理器,有的負責渲染地形,有的負責渲染BSP地圖,隨著逐步深入會一步步介紹 實體Entity  代表一個被渲染在螢幕上的東西,光照,粒子,相機,等都是實體 實體不能單獨存在,必須與場景結點結合attach,才能擁有位置和方向資訊 場景結點SceneNode  場景結點跟蹤所有的與其關聯的物體,當你建立一個實體Entity的時候,只有與場景結點關聯以後,方能被 渲染到螢幕上,一個場景結點可以被任意數量的實體關聯。 建立一個場景結點 -> 建立一個實體並與場景結點關聯 ->建立一個光線並與場景結點關聯 ->  場景結點可以與其它的場景結點關聯,形成一個整體的層次結構 一個非常重要的事情是:場景結點的位置永遠都是針對它的父場景結點的! OGRE裡面的"Hello World" 我們來回顧一下上面的第一個應用程式 在createScene()函式裡面 首先我們加入一個環境光線
mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));
mScenMgr就是我們的場景管理器,呼叫設定環境光函式 然後我們建立一個實體
Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
第一個引數是實體的名稱,每個東西必須有一個獨一無二的名稱,後一個引數是實體的檔案來源 重複一遍目前我們使用的是OGRE範例裡的資源 每一個場景管理器都包含一個root場景結點,我們建立一個子結點並“貼上去”
Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");
同樣的,結點也需要一個名稱 好了,把實體跟結點關聯起來
headNode->attachObject(ogreHead);

我們加入一個光源light
Ogre::Light* light = mSceneMgr->createLight( "MainLight" );

設定光源的位置
light->setPosition(20, 80, 50);

好了我們可以看到實際情況了 Image
一個重要的問題,座標系和向量 x軸從左往右,y軸從下往上,z軸從進入顯示器到出顯示器 Cartesian coordinate system on a computer screen
我們剛才建立的物體就在(0, 0, 0)這個位置上 建立一個新的物體: 在有了座標系基礎之後,我們繼續新增新的物體,在原有的程式上繼續進行修改
Ogre::Entity* ogreHead2 = mSceneMgr->createEntity( "Head2", "ogrehead.mesh" );
Ogre::SceneNode* headNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "HeadNode2", Ogre::Vector3( 100, 0, 0 ) );
headNode2->attachObject( ogreHead2 );

是不是和之前看到的程式很像呢?就不在贅述了,不同之處在於,初始位置變化了 你不需要銷燬什麼,getName函式可以返回實體的名稱,getParentSceneNode可以返回它所關聯的結點 SceneNode類就非常複雜了,可以通過getPosition and setPosition來設定場景結點的位置 通過translate函式對其進行移動。除了管理位置本身以外,它還管理著放大縮小與旋轉,你可以通過pitchyaw, 和roll 函式可以幫助我們進行更為複雜的變換操作。 如果我們把剛才的程式碼做一些修改 把這幾句
Ogre::SceneNode* headNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "HeadNode2", Ogre::Vector3( 100, 0, 0 ) );
改為
Ogre::SceneNode* headNode2 = headNode->createChildSceneNode( "HeadNode2", Ogre::Vector3( 100, 0, 0 ) );
那麼第二個結點就成為了第一個結點的子結點,如果執行
headNode2->translate( Ogre::Vector3( 10, 0, 10 ) );
移動的只有第二個結點,but 如果執行
headNode->translate( Ogre::Vector3( 25, 0, 0 ) );

兩個結點都會一起移動 解釋一下: 場景根結點的位置永遠都是(0, 0, 0)世界座標系 headNode 起始位置是(0, 0, 0),移動(25, 0, 0),那麼現在的位置是(25, 0, 0)
headNode2 是它的子結點那麼它的位置是(0, 0, 0) + (25, 0, 0) + (100, 0, 0)
這就是OGRE的一個非常重要的核心,結點的層次結構性,這對於開發來說是一個非常重要的概念! 縮放的範例
mSceneMgr->setAmbientLight(Ogre::ColourValue(1.0, 1.0, 1.0));
 
Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");
headNode->attachObject(ogreHead);
 
headNode->scale( .5, 1, 2 ); 
 
Ogre::Entity* ogreHead2 = mSceneMgr->createEntity( "Head2", "ogrehead.mesh" );
Ogre::SceneNode* headNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "HeadNode2", Ogre::Vector3( 100, 0, 0 ) );
headNode2->attachObject( ogreHead2 );
 
headNode2->scale( 1, 2, 1 );

旋轉的範例 Image
mSceneMgr->setAmbientLight(Ogre::ColourValue(1.0, 1.0, 1.0));
 
Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");
headNode->attachObject(ogreHead);
 
headNode->yaw( Ogre::Degree( -90 ) );
 
Ogre::Entity* ogreHead2 = mSceneMgr->createEntity( "Head2", "ogrehead.mesh" );
Ogre::SceneNode* headNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "HeadNode2", Ogre::Vector3( 100, 0, 0 ) );
headNode2->attachObject( ogreHead2 );
 
headNode2->pitch( Ogre::Degree( -90 ) );
 
Ogre::Entity* ogreHead3 = mSceneMgr->createEntity( "Head3", "ogrehead.mesh" );
Ogre::SceneNode* headNode3 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "HeadNode3", Ogre::Vector3( 200, 0, 0 ) );
headNode3->attachObject( ogreHead3 );
 
headNode3->roll( Ogre::Degree( -90 ) );
Image
注意VS2010下 degree可能沒有宣告,使用名空間Ogre::Degree OGRE環境的資訊MORE 大部分的 (.DLL and .CFG) 可以在ogre sdk的bin目錄下找到

DLLs and Plugins 關於庫檔案和外掛的介紹

OGRE主要包括三個部分main library, plugins 和 third-party libraries.

Main library

必須被包含的庫 OgreMain.dll和其它的比如 cg.dll

Plugins

你可以在需要或者不想使用的時候開啟或者關閉第三方外掛,Ogre中檔名以"Plugin_" 開頭的就是外掛檔案 Ogre同樣的採用外掛進行渲染,比如D3D或者OpenGL,它們以RenderSystem_開頭。例如,當你需要寫 一些shaders相關的OpenGL東西,但是你需要在執行D3D的環境下跑程式時,就可以關閉這些渲染特性

Third party libraries and helper libraries

Ogre本身並不包含比如GUI,I/O,物理引擎等東西,它只是一個繪圖引擎,你可以使用其它第三方庫來進行操作 ogre的demos裡面包含了如下的第三方庫: 1.鍵盤和滑鼠採用 OIS庫,OIS.dll 2.CgProgramManager使用了Cg.dll 可以再Ogre官方Wiki或者論壇上看一看其它的外掛或者是庫檔案 關於配置檔案 Ogre使用了若干配置檔案,它們控制著外掛的載入,資源的載入以及其它。我們簡單地來看一下這些配置檔案都 做了些什麼 plugins.cfg: 這個檔案包含了你的程式所需要的外掛,如果你想新增或者去掉外掛,需要通過修改這個檔案來完成
刪除外掛,只需要將相應的行刪除,或者通過在前面加一個"#"來註釋掉。新增外掛,你需要重寫一行,"Plugin=[PluginName]" 類似這樣的形式,注意不要新增dll字尾。可以通過改變"PluginFolder"變數來改變Ogre尋找外掛的位置,可以使用絕對和相對 路徑,但不可以使用環境變數。 resources.cfg:這個檔案包含了Ogre尋找資源的目錄的列表,主要資源包含指令碼scripts,meshes,textures等等。可以使用
絕對或者相對路徑,不可以使用環境變數。注意Ogre是不會掃描子目錄的,必須手動進行新增。比如,你需要同時新增 "res\meshes"  和 "res\meshes\small"。 media.cfg:這個檔案告訴Ogre一些細節性的關於資源的東西,現在暫時不討論關於它的問題。
ogre.cfg:這個檔案由Ogre的配置螢幕生成,這個檔案不是通用的,只針對你個人的機器環境而言
quake3settings.cfg:這個檔案被BSPSceneManager所使用,當使用這種SceneManager的時候才有用
以上是配置檔案的一些介紹,Ogre至少需要找到"plugins.cfg", "resources.cfg", 和"media.cfg"才能夠正常執行 在以後的教程中我們會繼續介紹關於它的資訊 總結 我們在本教程中接觸到了場景管理器SceneManager,場景結點SceneNode,實體Entity 類。通過以後的教程我們會進一步熟悉它們的使用