接續(一)
首先,我們要分析的就是Root類,使用Ogre的程序所需要作的第一件事情就是實例化一個Root對象。如果沒有這個對象,你就無法調用(除了日誌管理以外)的任何一個功能。Root類的構造函數接受一些符串對象的參數,這些字符代表着不同作用的文件名稱。
Root * root = new Root();
Root * root = new Root("plugins.cfg");
Root * root = new Root("plugins.cfg", "ogre.cfg");
Root * root = new Root("plugins.cfg", "ogre.cfg", "ogre.log");
Root * root = new Root("", "");
上面列出了一些不同的方法來創建Root實例,這裏面任何的方法都能單獨的正確執行。參數也是系統所默認的值(“plugins.cfg”, “ogre.cfg”, “ogre.log”——當你沒有填寫參數的時候,系統就認爲採用了默認的這些值)。
plugins.cfg:插件,Ogre中所謂的插件就是符合Ogre插件接口的代碼模塊,比如場景管理(SceneManager)插件和渲染系統(RenderSystem)插件等。在啓動的Ogre時候,他會載入plugins.cfg配置文件來查看有哪些插件可以被使用。下面是一個plugins.cfg文件例子
# Defines plugins to load
# Define plugin folder
PluginFolder=.
# Define plugins
Plugin=RenderSystem_Direct3D9_d
Plugin=RenderSystem_GL_d
Plugin=Plugin_ParticleFX_d
Plugin=Plugin_BSPSceneManager_d
Plugin=Plugin_CgProgramManager_d
Plugin=Plugin_PCZSceneManager_d.dll
Plugin=Plugin_OctreeZone_d.dll
Plugin=Plugin_OctreeSceneManager_d
其中PluginFolder用於定義這些插件存在的位置(路徑), 這裏使用“.”,表示需要在“\”或者“/”(即根目錄)。在某些平臺上可以不使用“.”直接使用""(空白),ogre照樣會在“\”或者“/”中去找。而Plugin則說明了有哪些插件可以使用,但是需要注意,這些插件都沒有後綴名。
這裏需要注意:在“=”兩邊不能加入空格或者 Tab字符。
ogre.cfg則是一個屬性配置文件,主要保存用戶自定義的一些屬性,即下圖所示的界面的一些屬性。
文件如下:
Render System=Direct3D9 Rendering Subsystem
[Direct3D9 Rendering Subsystem]
Allow NVPerfHUD=No
Anti aliasing=None
Floating-point mode=Fastest
Full Screen=No
Rendering Device=Mobile Intel(R) 945 Express Chipset Family
VSync=No
Video Mode=800 x 600 @ 32-bit colour
sRGB Gamma Conversion=No
[OpenGL Rendering Subsystem]
Colour Depth=32
Display Frequency=N/A
FSAA=0
Full Screen=No
RTT Preferred Mode=FBO
VSync=No
Video Mode=1024 x 768
sRGB Gamma Conversion=No
相信這裏就不用多解釋,大家都明白了。Ogre.log :日誌文件,用於輸出一些調試信息等,比如下代碼:
LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***")
就會在 Ogre.log文件中輸出"*** Initializing OIS ***"信息。另外需要說明得就是FrameListener接口了,當Ogre渲染每一幀的開始和結束的時候會回調FrameListener接口的方法,其中主要包括如下兩個渲染方法。
class ExampleFrameListener : public FrameListener{
public:
bool frameStarted (const FrameEvent &evt);
bool frameEnded (const FrameEvent &evt );
};
bool ExampleFrameListener::frameStarted (const FrameEvent &evt){
//在每一幀畫面渲染前
return true;
}
bool ExampleFrameListener::frameEnded (const FrameEvent &evt ){
//在每一幀畫面渲染後
return true;
}
所以我們就可以根據需要來實現這兩個方式,實現渲染。 注意:在新的版本中frameRenderingQueued方法基本上取代了frameStarted,所以本例中我們就是用了frameRenderingQueued,一般在這個函數中都需要檢測各種輸入設備的情況,以進行相應的處理。
最後,當我們在程序中調用mRoot->startRendering();方法時,就告訴ogre,我們需要開始渲染了。ogre就會開始渲染。也正是ExampleApplication類中的go方法,所做的,初始化(setup)完成之後就開始渲染(mRoot->startRendering())。
之所以有了這兩個類,上一篇中我們纔可以不寫任何代碼就可以構建一個窗口,那麼本節內容,我們要顯示模型當然就很簡單了。
直接在OgreDemo1類的createScene方法中來實現,
1:設置環境光,首先需要爲整個場景設置環境光,這樣纔可以看到要顯示的內容,通過調用setAmbientLight函數並指定環境光的顏色就可以做到這些。指定的顏色由紅、綠、藍三種顏色組成,且每種色數值範圍在 0 到 1 之間。
//設置環境光
mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) )
2:創建一個
Entity (物體),通過調用 SceneManager 的 createEntity 方法來創建//創建一個物體
Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );
變量 mSceneMgr 是當前場景管理器的一個對象,createEntity 方法的第一個參數是爲所創建的實體指定一個唯一的標識,第二個參數 "robot.mesh" 指明要使用的網格實體,"robot.mesh" 網格實體在 ExampleApplication
類中被裝載。這樣,就已經創建了一個實體。3:還需要創建一個場景節點來與它綁定在一起。既然每個場景管理器都有一個根節點,那我們就在根節點下創建一個場景節點。
//創建該物體對應的場景節點
SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );
首先調用場景管理器的 getRootSceneNode 方法來獲取根節點,再使用根節點的 createChildSceneNode 方法創建一個名爲 "RobotNode" 的場景節點。與實體一樣,場景節點的名字也是唯一的。 4:最後,將實體與場景節點綁定在一起,這樣機器人(Robot)就會在指定的位置被渲染:
//將該物體和場景節點關聯起來
node1->attachObject( ent1 );
ok,現在編譯運行你的程序,就可以看到我們偉大的機器人界面了。
最後說一下,在創建Root對象時的文件一般會和程序最後的可執行文件在同一目錄(因爲有人說找不到這些文件)。祝你成功!
補充一下:
需要將sdk下的media文件夾拷貝到該項目目錄下,因爲裏面存放了一些資源文件,本文中的機器人模型也在其中。