天天看點

ogre研究之第一個程式

這裡我們主要是實作在程式中裝載一個簡單的模型并顯示出來。

首先看一下效果吧,(模型就是ogre例子中的robot.mesh),如下:

例子很簡單,代碼頁不多,就4行。我們還是一步一步來分析吧。

首先我們上一個項目中的OgreDemo1類繼承自ExampleApplication類,我們之是以什麼都沒有做就能建立一個視窗,就是因為ExampleApplication為我們實作了。

首先我們打開ExampleApplication類,可以看到包含了如下幾個成員變量(下乳了少許注釋)

Cpp代碼

ogre研究之第一個程式
  1. //ogre的程式"根"任何ogre程式都會有改對象   
  2. Root *mRoot;   
  3. //錄影機鏡頭   
  4. Camera* mCamera;   
  5. //場景管理器   
  6. SceneManager* mSceneMgr;   
  7. //對于每一幀進行處理的類   
  8. ExampleFrameListener* mFrameListener;   
  9. //渲染視窗   
  10. RenderWindow* mWindow;   
  11. //資源檔案的路徑字元串   
  12. Ogre::String mResourcePath;  
//ogre的程式"根"任何ogre程式都會有改對象
Root *mRoot;
//錄影機鏡頭
Camera* mCamera;
//場景管理器
SceneManager* mSceneMgr;
//對于每一幀進行處理的類
ExampleFrameListener* mFrameListener;
//渲染視窗
RenderWindow* mWindow;
//資源檔案的路徑字元串
Ogre::String mResourcePath;
           

這裡的ExampleFrameListener類,如果你暫時還不清楚是做什麼的,不要緊,後面我們慢慢介紹。

知道了這些成員變量,我們在傳回OgreDemo1.c檔案中看看入口函數WinMain中是如何書寫的呢?很簡單就一句話:

Cpp代碼

ogre研究之第一個程式
  1. app.go();  
app.go();
           

先将源代碼貼出來,加了詳細注意:

ExampleApplication.h

Cpp代碼

ogre研究之第一個程式
  1. #ifndef __ExampleApplication_H__   
  2. #define __ExampleApplication_H__   
  3. #include "Ogre.h"   
  4. #include "OgreConfigFile.h"   
  5. #include "ExampleFrameListener.h"   
  6. #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE   
  7. #include <CoreFoundation/CoreFoundation.h>   
  8. std::string macBundlePath()   
  9. {   
  10.     char path[1024];   
  11.     CFBundleRef mainBundle = CFBundleGetMainBundle();   
  12.     assert(mainBundle);   
  13.     CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);   
  14.     assert(mainBundleURL);   
  15.     CFStringRef cfStringRef = CFURLCopyFileSystemPath( mainBundleURL, kCFURLPOSIXPathStyle);   
  16.     assert(cfStringRef);   
  17.     CFStringGetCString(cfStringRef, path, 1024, kCFStringEncodingASCII);   
  18.     CFRelease(mainBundleURL);   
  19.     CFRelease(cfStringRef);   
  20.     return std::string(path);   
  21. }   
  22. #endif   
  23. using namespace Ogre;   
  24. class ExampleApplication   
  25. {   
  26. public:   
  27.     ExampleApplication()   
  28.     {   
  29.         mFrameListener = 0;   
  30.         mRoot = 0;   
  31. #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE   
  32.         mResourcePath = macBundlePath() + "/Contents/Resources/";   
  33. #else   
  34.         mResourcePath = "";   
  35. #endif   
  36.     }   
  37.     /// Standard destructor   
  38.     virtual ~ExampleApplication()   
  39.     {   
  40.         if (mFrameListener)   
  41.             delete mFrameListener;   
  42.         if (mRoot)   
  43.             OGRE_DELETE mRoot;   
  44.     }   
  45.     /// 程式的入口   
  46.     virtual void go(void)   
  47.     {   
  48.         //進行初始化工作   
  49.         if (!setup())   
  50.             return;   
  51.         //開始渲染   
  52.         mRoot->startRendering();   
  53.         // 清理螢幕   
  54.         destroyScene();   
  55.     }   
  56. protected:   
  57.     //ogre的程式"根"任何ogre程式都會有改對象   
  58.     Root *mRoot;   
  59.     //錄影機鏡頭   
  60.     Camera* mCamera;   
  61.     //場景管理器   
  62.     SceneManager* mSceneMgr;   
  63.     //對于每一幀進行處理的類   
  64.     ExampleFrameListener* mFrameListener;   
  65.     //渲染視窗   
  66.     RenderWindow* mWindow;   
  67.     //資源檔案的路徑字元串   
  68.     Ogre::String mResourcePath;   
  69.     //初始化應用程式   
  70.     virtual bool setup(void)   
  71.     {   
  72.         String pluginsPath;   
  73. #ifndef OGRE_STATIC_LIB   
  74.         pluginsPath = mResourcePath + "plugins.cfg";   
  75. #endif   
  76.         //建構Root對象   
  77.         mRoot = OGRE_NEW Root(pluginsPath,    
  78.             mResourcePath + "ogre.cfg", mResourcePath + "Ogre.log");   
  79.         //配置資源檔案相關   
  80.         setupResources();   
  81.         //配置,主要用于初始化渲染視窗   
  82.         bool carryOn = configure();   
  83.         if (!carryOn) return false;   
  84.         //建立場景管理器   
  85.         chooseSceneManager();   
  86.         //建立錄影機   
  87.         createCamera();   
  88.         //建立視口   
  89.         createViewports();   
  90.         TextureManager::getSingleton().setDefaultNumMipmaps(5);   
  91.         //建立資源監聽   
  92.         createResourceListener();   
  93.         //床在資源   
  94.         loadResources();   
  95.         //建立螢幕,必須重寫,也就是我們OgreDemo1類中(我們現實模型需要實作的)   
  96.         createScene();   
  97.         //建立幀監聽   
  98.         createFrameListener();   
  99.         return true;   
  100.     }   
  101.     virtual bool configure(void)   
  102.     {   
  103.         //判斷是否進入(即運作過了配置視窗,進入demo視窗)   
  104.         if(mRoot->showConfigDialog())   
  105.         {   
  106.             //初始化系統,得到一個渲染視窗對象   
  107.             mWindow = mRoot->initialise(true);   
  108.             return true;   
  109.         }   
  110.         else  
  111.         {   
  112.             return false;   
  113.         }   
  114.     }   
  115.     virtual void chooseSceneManager(void)   
  116.     {   
  117.         // 建立一個場景管理器(場景類型,視窗标題)   
  118.         mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "ExampleSMInstance");   
  119.     }   
  120.     virtual void createCamera(void)   
  121.     {   
  122.         // 建立一個錄影機   
  123.         mCamera = mSceneMgr->createCamera("PlayerCam");   
  124.         // 設定錄影機的位置   
  125.         mCamera->setPosition(Vector3(0,0,500));   
  126.         // 設定觀察點   
  127.         mCamera->lookAt(Vector3(0,0,-300));   
  128.         // 設定最近裁剪距離,如果超出則不顯示   
  129.         mCamera->setNearClipDistance(5);   
  130.         //同樣還有設定最遠裁剪距離   
  131.         //mCamera->setFarClipDistance(1000);   
  132.     }   
  133.     //建立幀監聽   
  134.     virtual void createFrameListener(void)   
  135.     {   
  136.         //執行個體化幀監聽,(渲染視窗,錄影機)   
  137.         mFrameListener= new ExampleFrameListener(mWindow, mCamera);   
  138.         //設定是否顯示調試資訊(比如:fps...)   
  139.         mFrameListener->showDebugOverlay(true);   
  140.         //添加幀監聽到root中   
  141.         mRoot->addFrameListener(mFrameListener);   
  142.     }   
  143.     //建立螢幕   
  144.     virtual void createScene(void) = 0;    
  145.     //清屏   
  146.     virtual void destroyScene(void){}   
  147.     virtual void createViewports(void)   
  148.     {   
  149.         // 建立一個“視口”   
  150.         Viewport* vp = mWindow->addViewport(mCamera);   
  151.         //設定背景顔色   
  152.         vp->setBackgroundColour(ColourValue(0,0,0));   
  153.         //設定螢幕的長寬比(視口的寬度和高度比,目前的寬屏電腦)   
  154.         mCamera->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));   
  155.     }   
  156.     /// 初始化資源,比如:模型、貼圖等資源   
  157.     virtual void setupResources(void)   
  158.     {   
  159.         ConfigFile cf;   
  160.         //讀取配置檔案   
  161.         cf.load(mResourcePath + "resources.cfg");   
  162.         ConfigFile::SectionIterator seci = cf.getSectionIterator();   
  163.         String secName, typeName, archName;   
  164.         while (seci.hasMoreElements())   
  165.         {   
  166.             secName = seci.peekNextKey();   
  167.             ConfigFile::SettingsMultiMap *settings = seci.getNext();   
  168.             ConfigFile::SettingsMultiMap::iterator i;   
  169.             for (i = settings->begin(); i != settings->end(); ++i)   
  170.             {   
  171.                 //取得并添加資源檔案   
  172.                 typeName = i->first;   
  173.                 archName = i->second;   
  174. #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE   
  175.                 ResourceGroupManager::getSingleton().addResourceLocation(   
  176.                     String(macBundlePath() + "/" + archName), typeName, secName);   
  177. #else   
  178.                 ResourceGroupManager::getSingleton().addResourceLocation(   
  179.                     archName, typeName, secName);   
  180. #endif   
  181.             }   
  182.         }   
  183.     }   
  184.     //建立資源監聽,比如(正在裝載資源,請稍等界面)   
  185.     virtual void createResourceListener(void)   
  186.     {   
  187.     }   
  188.     //裝載資源   
  189.     virtual void loadResources(void)   
  190.     {   
  191.         ResourceGroupManager::getSingleton().initialiseAllResourceGroups();   
  192.     }   
  193. };   
  194. #endif  
#ifndef __ExampleApplication_H__
#define __ExampleApplication_H__

#include "Ogre.h"
#include "OgreConfigFile.h"
#include "ExampleFrameListener.h"

#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#include <CoreFoundation/CoreFoundation.h>

std::string macBundlePath()
{
    char path[1024];
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    assert(mainBundle);

    CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
    assert(mainBundleURL);

    CFStringRef cfStringRef = CFURLCopyFileSystemPath( mainBundleURL, kCFURLPOSIXPathStyle);
    assert(cfStringRef);

    CFStringGetCString(cfStringRef, path, 1024, kCFStringEncodingASCII);

    CFRelease(mainBundleURL);
    CFRelease(cfStringRef);

    return std::string(path);
}
#endif

using namespace Ogre;

/** Base class which manages the standard startup of an Ogre application.
    Designed to be subclassed for specific examples if required.
*/
class ExampleApplication
{
public:
    ExampleApplication()
    {
        mFrameListener = 0;
        mRoot = 0;
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
		mResourcePath = macBundlePath() + "/Contents/Resources/";
#else
		mResourcePath = "";
#endif
    }
    /// Standard destructor
    virtual ~ExampleApplication()
    {
        if (mFrameListener)
            delete mFrameListener;
        if (mRoot)
            OGRE_DELETE mRoot;
    }

    /// 程式的入口
    virtual void go(void)
    {
		//進行初始化工作
        if (!setup())
            return;
		//開始渲染
        mRoot->startRendering();
        // 清理螢幕
        destroyScene();
    }

protected:
	//ogre的程式"根"任何ogre程式都會有改對象
    Root *mRoot;
	//錄影機鏡頭
    Camera* mCamera;
	//場景管理器
    SceneManager* mSceneMgr;
	//對于每一幀進行處理的類
    ExampleFrameListener* mFrameListener;
	//渲染視窗
    RenderWindow* mWindow;
	//資源檔案的路徑字元串
	Ogre::String mResourcePath;
    //初始化應用程式
    virtual bool setup(void)
    {
		String pluginsPath;
#ifndef OGRE_STATIC_LIB
		pluginsPath = mResourcePath + "plugins.cfg";
#endif
		//建構Root對象
        mRoot = OGRE_NEW Root(pluginsPath, 
            mResourcePath + "ogre.cfg", mResourcePath + "Ogre.log");
		//配置資源檔案相關
        setupResources();
		//配置,主要用于初始化渲染視窗
        bool carryOn = configure();
        if (!carryOn) return false;
		//建立場景管理器
        chooseSceneManager();
		//建立錄影機
        createCamera();
		//建立視口
        createViewports();
		
        TextureManager::getSingleton().setDefaultNumMipmaps(5);
		//建立資源監聽
		createResourceListener();
		//床在資源
		loadResources();
		//建立螢幕,必須重寫,也就是我們OgreDemo1類中(我們現實模型需要實作的)
        createScene();
		//建立幀監聽
        createFrameListener();
        return true;
    }
    /** 是否配置完成,完成則初始化系統 */
    virtual bool configure(void)
    {
        //判斷是否進入(即運作過了配置視窗,進入demo視窗)
        if(mRoot->showConfigDialog())
        {
            //初始化系統,得到一個渲染視窗對象
            mWindow = mRoot->initialise(true);
            return true;
        }
        else
        {
            return false;
        }
    }

    virtual void chooseSceneManager(void)
    {
        // 建立一個場景管理器(場景類型,視窗标題)
        mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "ExampleSMInstance");
    }
    virtual void createCamera(void)
    {
        // 建立一個錄影機
        mCamera = mSceneMgr->createCamera("PlayerCam");

        // 設定錄影機的位置
        mCamera->setPosition(Vector3(0,0,500));
        // 設定觀察點
        mCamera->lookAt(Vector3(0,0,-300));
		// 設定最近裁剪距離,如果超出則不顯示
        mCamera->setNearClipDistance(5);
		//同樣還有設定最遠裁剪距離
		//mCamera->setFarClipDistance(1000);
    }
	//建立幀監聽
    virtual void createFrameListener(void)
    {
		//執行個體化幀監聽,(渲染視窗,錄影機)
        mFrameListener= new ExampleFrameListener(mWindow, mCamera);
		//設定是否顯示調試資訊(比如:fps...)
        mFrameListener->showDebugOverlay(true);
		//添加幀監聽到root中
        mRoot->addFrameListener(mFrameListener);
    }
	//建立螢幕
    virtual void createScene(void) = 0; 
	//清屏
    virtual void destroyScene(void){}
	/* 建立視口并初始化 */
    virtual void createViewports(void)
    {
        // 建立一個“視口”
        Viewport* vp = mWindow->addViewport(mCamera);
		//設定背景顔色
        vp->setBackgroundColour(ColourValue(0,0,0));

        //設定螢幕的長寬比(視口的寬度和高度比,目前的寬屏電腦)
        mCamera->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
    }

    /// 初始化資源,比如:模型、貼圖等資源
    virtual void setupResources(void)
    {
        ConfigFile cf;
		//讀取配置檔案
        cf.load(mResourcePath + "resources.cfg");
        ConfigFile::SectionIterator seci = cf.getSectionIterator();
        String secName, typeName, archName;
        while (seci.hasMoreElements())
        {
            secName = seci.peekNextKey();
            ConfigFile::SettingsMultiMap *settings = seci.getNext();
            ConfigFile::SettingsMultiMap::iterator i;
            for (i = settings->begin(); i != settings->end(); ++i)
            {
				//取得并添加資源檔案
                typeName = i->first;
                archName = i->second;
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
                ResourceGroupManager::getSingleton().addResourceLocation(
                    String(macBundlePath() + "/" + archName), typeName, secName);
#else
                ResourceGroupManager::getSingleton().addResourceLocation(
                    archName, typeName, secName);
#endif
            }
        }
    }

	//建立資源監聽,比如(正在裝載資源,請稍等界面)
	virtual void createResourceListener(void)
	{
	}

	//裝載資源
	virtual void loadResources(void)
	{
		ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
	}
};


#endif
           

ExampleFrameListener.h 

Cpp代碼

ogre研究之第一個程式
  1. #ifndef __ExampleFrameListener_H__   
  2. #define __ExampleFrameListener_H__   
  3. #include "Ogre.h"   
  4. #include "OgreStringConverter.h"   
  5. #include "OgreException.h"   
  6. #define OIS_DYNAMIC_LIB   
  7. #include <OIS/OIS.h>   
  8. using namespace Ogre;   
  9. class ExampleFrameListener: public FrameListener, public WindowEventListener   
  10. {   
  11. protected:   
  12.     virtual void updateStats(void)   
  13.     {   
  14.         static String currFps = "Current FPS: ";   
  15.         static String avgFps = "Average FPS: ";   
  16.         static String bestFps = "Best FPS: ";   
  17.         static String worstFps = "Worst FPS: ";   
  18.         static String tris = "Triangle Count: ";   
  19.         static String batches = "Batch Count: ";   
  20.         // 需要更新debug資訊時更新   
  21.         try {   
  22.             OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");   
  23.             OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");   
  24.             OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");   
  25.             OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");   
  26.             const RenderTarget::FrameStats& stats = mWindow->getStatistics();   
  27.             guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));   
  28.             guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS));   
  29.             guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS)   
  30.                 +" "+StringConverter::toString(stats.bestFrameTime)+" ms");   
  31.             guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS)   
  32.                 +" "+StringConverter::toString(stats.worstFrameTime)+" ms");   
  33.             OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");   
  34.             guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount));   
  35.             OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches");   
  36.             guiBatches->setCaption(batches + StringConverter::toString(stats.batchCount));   
  37.             OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");   
  38.             guiDbg->setCaption(mDebugText);   
  39.         }   
  40.         catch(...) {  }   
  41.     }   
  42. public:   
  43.     // 構造函數,初始化成員變量   
  44.     ExampleFrameListener(RenderWindow* win, Camera* cam, bool bufferedKeys = false, bool bufferedMouse = false,   
  45.                  bool bufferedJoy = false ) :   
  46.         mCamera(cam), mTranslateVector(Vector3::ZERO), mCurrentSpeed(0), mWindow(win), mStatsOn(true), mNumScreenShots(0),   
  47.         mMoveScale(0.0f), mRotScale(0.0f), mTimeUntilNextToggle(0), mFiltering(TFO_BILINEAR),   
  48.         mAniso(1), mSceneDetailIndex(0), mMoveSpeed(100), mRotateSpeed(36), mDebugOverlay(0),   
  49.         mInputManager(0), mMouse(0), mKeyboard(0), mJoy(0)   
  50.     {   
  51.         //得到debug視圖   
  52.         mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");   
  53.         //日志管理器   
  54.         LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");   
  55.         OIS::ParamList pl;   
  56.         size_t windowHnd = 0;   
  57.         std::ostringstream windowHndStr;   
  58.         //取得自定義的屬性   
  59.         win->getCustomAttribute("WINDOW", &windowHnd);   
  60.         windowHndStr << windowHnd;   
  61.         pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));   
  62.         //建立輸入管理器   
  63.         mInputManager = OIS::InputManager::createInputSystem( pl );   
  64.         //建立輸入裝置、滑鼠、鍵盤、搖杆   
  65.         mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, bufferedKeys ));   
  66.         mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, bufferedMouse ));   
  67.         try {   
  68.             mJoy = static_cast<OIS::JoyStick*>(mInputManager->createInputObject( OIS::OISJoyStick, bufferedJoy ));   
  69.         }   
  70.         catch(...) {   
  71.             mJoy = 0;   
  72.         }   
  73.         //根據視窗的大小來設定滑鼠的初始裁剪區域   
  74.         windowResized(mWindow);   
  75.         //顯示debug資訊   
  76.         showDebugOverlay(true);   
  77.         //注冊一個windows視窗事件監聽   
  78.         WindowEventUtilities::addWindowEventListener(mWindow, this);   
  79.     }   
  80.     //調整滑鼠裁剪區域   
  81.     virtual void windowResized(RenderWindow* rw)   
  82.     {   
  83.         unsigned int width, height, depth;   
  84.         int left, top;   
  85.         //取得視窗矩陣   
  86.         rw->getMetrics(width, height, depth, left, top);   
  87.         //得到滑鼠   
  88.         const OIS::MouseState &ms = mMouse->getMouseState();   
  89.         ms.width = width;   
  90.         ms.height = height;   
  91.     }   
  92.     //關閉視窗之前進行的處理   
  93.     virtual void windowClosed(RenderWindow* rw)   
  94.     {   
  95.         //檢測是否關閉了我們的渲染視窗   
  96.         if( rw == mWindow )   
  97.         {   
  98.             if( mInputManager )   
  99.             {   
  100.                 //清除輸入裝置   
  101.                 mInputManager->destroyInputObject( mMouse );   
  102.                 mInputManager->destroyInputObject( mKeyboard );   
  103.                 mInputManager->destroyInputObject( mJoy );   
  104.                 //銷毀輸入管理器   
  105.                 OIS::InputManager::destroyInputSystem(mInputManager);   
  106.                 mInputManager = 0;   
  107.             }   
  108.         }   
  109.     }   
  110.     virtual ~ExampleFrameListener()   
  111.     {   
  112.         //移除所有的視窗事件監聽   
  113.         WindowEventUtilities::removeWindowEventListener(mWindow, this);   
  114.         //關閉視窗   
  115.         windowClosed(mWindow);   
  116.     }   
  117.     //按鍵事件處理   
  118.     virtual bool processUnbufferedKeyInput(const FrameEvent& evt)   
  119.     {   
  120.         if(mKeyboard->isKeyDown(OIS::KC_A))   
  121.             mTranslateVector.x = -mMoveScale;   // 向左移動攝像頭矩陣   
  122.         if(mKeyboard->isKeyDown(OIS::KC_D))   
  123.             mTranslateVector.x = mMoveScale;    // Move camera RIGHT   
  124.         if(mKeyboard->isKeyDown(OIS::KC_UP) || mKeyboard->isKeyDown(OIS::KC_W) )   
  125.             mTranslateVector.z = -mMoveScale;   // Move camera forward   
  126.         if(mKeyboard->isKeyDown(OIS::KC_DOWN) || mKeyboard->isKeyDown(OIS::KC_S) )   
  127.             mTranslateVector.z = mMoveScale;    // Move camera backward   
  128.         if(mKeyboard->isKeyDown(OIS::KC_PGUP))   
  129.             mTranslateVector.y = mMoveScale;    // Move camera up   
  130.         if(mKeyboard->isKeyDown(OIS::KC_PGDOWN))   
  131.             mTranslateVector.y = -mMoveScale;   // Move camera down   
  132.         if(mKeyboard->isKeyDown(OIS::KC_RIGHT))   
  133.             mCamera->yaw(-mRotScale);   
  134.         if(mKeyboard->isKeyDown(OIS::KC_LEFT))   
  135.             mCamera->yaw(mRotScale);   
  136.         if( mKeyboard->isKeyDown(OIS::KC_ESCAPE) || mKeyboard->isKeyDown(OIS::KC_Q) )   
  137.             return false;   
  138.         if( mKeyboard->isKeyDown(OIS::KC_F) && mTimeUntilNextToggle <= 0 )   
  139.         {   
  140.             mStatsOn = !mStatsOn;   
  141.             showDebugOverlay(mStatsOn);   
  142.             mTimeUntilNextToggle = 1;   
  143.         }   
  144.         if( mKeyboard->isKeyDown(OIS::KC_T) && mTimeUntilNextToggle <= 0 )   
  145.         {   
  146.             switch(mFiltering)   
  147.             {   
  148.             case TFO_BILINEAR:   
  149.                 mFiltering = TFO_TRILINEAR;   
  150.                 mAniso = 1;   
  151.                 break;   
  152.             case TFO_TRILINEAR:   
  153.                 mFiltering = TFO_ANISOTROPIC;   
  154.                 mAniso = 8;   
  155.                 break;   
  156.             case TFO_ANISOTROPIC:   
  157.                 mFiltering = TFO_BILINEAR;   
  158.                 mAniso = 1;   
  159.                 break;   
  160.             default: break;   
  161.             }   
  162.             MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);   
  163.             MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);   
  164.             showDebugOverlay(mStatsOn);   
  165.             mTimeUntilNextToggle = 1;   
  166.         }   
  167.         if(mKeyboard->isKeyDown(OIS::KC_SYSRQ) && mTimeUntilNextToggle <= 0)   
  168.         {   
  169.             std::ostringstream ss;   
  170.             ss << "screenshot_" << ++mNumScreenShots << ".png";   
  171.             mWindow->writeContentsToFile(ss.str());   
  172.             mTimeUntilNextToggle = 0.5;   
  173.             mDebugText = "Saved: " + ss.str();   
  174.         }   
  175.         if(mKeyboard->isKeyDown(OIS::KC_R) && mTimeUntilNextToggle <=0)   
  176.         {   
  177.             mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;   
  178.             switch(mSceneDetailIndex) {   
  179.                 case 0 : mCamera->setPolygonMode(PM_SOLID); break;//設定多邊形的模式   
  180.                 case 1 : mCamera->setPolygonMode(PM_WIREFRAME); break;   
  181.                 case 2 : mCamera->setPolygonMode(PM_POINTS); break;   
  182.             }   
  183.             mTimeUntilNextToggle = 0.5;   
  184.         }   
  185.         static bool displayCameraDetails = false;   
  186.         if(mKeyboard->isKeyDown(OIS::KC_P) && mTimeUntilNextToggle <= 0)   
  187.         {   
  188.             displayCameraDetails = !displayCameraDetails;   
  189.             mTimeUntilNextToggle = 0.5;   
  190.             if (!displayCameraDetails)   
  191.                 mDebugText = "";   
  192.         }   
  193.         if(displayCameraDetails)   
  194.             mDebugText = "P: " + StringConverter::toString(mCamera->getDerivedPosition()) +   
  195.                          " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation());   
  196.         return true;   
  197.     }   
  198.     //滑鼠事件處理   
  199.     virtual bool processUnbufferedMouseInput(const FrameEvent& evt)   
  200.     {   
  201.         // Rotation factors, may not be used if the second mouse button is pressed   
  202.         // 2nd mouse button - slide, otherwise rotate   
  203.         const OIS::MouseState &ms = mMouse->getMouseState();   
  204.         if( ms.buttonDown( OIS::MB_Right ) )   
  205.         {   
  206.             mTranslateVector.x += ms.X.rel * 0.13;   
  207.             mTranslateVector.y -= ms.Y.rel * 0.13;   
  208.         }   
  209.         else  
  210.         {   
  211.             mRotX = Degree(-ms.X.rel * 0.13);   
  212.             mRotY = Degree(-ms.Y.rel * 0.13);   
  213.         }   
  214.         return true;   
  215.     }   
  216.     //移動攝像頭   
  217.     virtual void moveCamera()   
  218.     {   
  219.         //偏移   
  220.         mCamera->yaw(mRotX);   
  221.         //傾斜   
  222.         mCamera->pitch(mRotY);   
  223.         //移動錄影機到指定位置   
  224.         mCamera->moveRelative(mTranslateVector);   
  225.     }   
  226.     //顯示debug資訊   
  227.     virtual void showDebugOverlay(bool show)   
  228.     {   
  229.         if (mDebugOverlay)   
  230.         {   
  231.             if (show)   
  232.                 mDebugOverlay->show();   
  233.             else  
  234.                 mDebugOverlay->hide();   
  235.         }   
  236.     }   
  237.     // 渲染隊列   
  238.     bool frameRenderingQueued(const FrameEvent& evt)   
  239.     {   
  240.         if(mWindow->isClosed())  return false;   
  241.         mSpeedLimit = mMoveScale * evt.timeSinceLastFrame;   
  242.         //捕獲、更新裝置   
  243.         mKeyboard->capture();   
  244.         mMouse->capture();   
  245.         if( mJoy ) mJoy->capture();   
  246.         bool buffJ = (mJoy) ? mJoy->buffered() : true;   
  247.         Ogre::Vector3 lastMotion = mTranslateVector;   
  248.         if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )   
  249.         {   
  250.             // one of the input modes is immediate, so setup what is needed for immediate movement   
  251.             if (mTimeUntilNextToggle >= 0)   
  252.                 mTimeUntilNextToggle -= evt.timeSinceLastFrame;   
  253.             // Move about 100 units per second   
  254.             mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;   
  255.             // Take about 10 seconds for full rotation   
  256.             mRotScale = mRotateSpeed * evt.timeSinceLastFrame;   
  257.             mRotX = 0;   
  258.             mRotY = 0;   
  259.             mTranslateVector = Ogre::Vector3::ZERO;   
  260.         }   
  261.         //Check to see which device is not buffered, and handle it   
  262.         if( !mKeyboard->buffered() )   
  263.             if( processUnbufferedKeyInput(evt) == false )   
  264.                 return false;   
  265.         if( !mMouse->buffered() )   
  266.             if( processUnbufferedMouseInput(evt) == false )   
  267.                 return false;   
  268.         // ramp up / ramp down speed   
  269.         if (mTranslateVector == Ogre::Vector3::ZERO)   
  270.         {   
  271.             // decay (one third speed)   
  272.             mCurrentSpeed -= evt.timeSinceLastFrame * 0.3;   
  273.             mTranslateVector = lastMotion;   
  274.         }   
  275.         else  
  276.         {   
  277.             // ramp up   
  278.             mCurrentSpeed += evt.timeSinceLastFrame;   
  279.         }   
  280.         // Limit motion speed   
  281.         if (mCurrentSpeed > 1.0)   
  282.             mCurrentSpeed = 1.0;   
  283.         if (mCurrentSpeed < 0.0)   
  284.             mCurrentSpeed = 0.0;   
  285.         mTranslateVector *= mCurrentSpeed;   
  286.         if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )   
  287.             moveCamera();   
  288.         return true;   
  289.     }   
  290.     //幀結束,更新狀态   
  291.     bool frameEnded(const FrameEvent& evt)   
  292.     {   
  293.         updateStats();   
  294.         return true;   
  295.     }   
  296. protected:   
  297.     //指向錄影機的指針   
  298.     Camera* mCamera;   
  299.     //一個3維向量,用于錄影機的位置變換   
  300.     Vector3 mTranslateVector;   
  301.     Real mCurrentSpeed;   
  302.     //指向渲染視窗的指針   
  303.     RenderWindow* mWindow;   
  304.     //是否顯示調試資訊   
  305.     bool mStatsOn;   
  306.     //debug資訊   
  307.     std::string mDebugText;   
  308.     //主要用于截圖   
  309.     unsigned int mNumScreenShots;   
  310.     //該demo中,錄影機會旋轉   
  311.     float mMoveScale;   
  312.     //速度限制   
  313.     float mSpeedLimit;   
  314.     //同樣用于錄影機變換   
  315.     Degree mRotScale;   
  316.     //延時   
  317.     Real mTimeUntilNextToggle ;   
  318.     //滑鼠旋轉的角度,用于錄影機的更新   
  319.     Radian mRotX, mRotY;   
  320.     //紋理內插補點的類型,枚舉類型   
  321.     TextureFilterOptions mFiltering;   
  322.     int mAniso;   
  323.     int mSceneDetailIndex ;   
  324.     //移動速度   
  325.     Real mMoveSpeed;   
  326.     //旋轉速度   
  327.     Degree mRotateSpeed;   
  328.     //debug視圖   
  329.     Overlay* mDebugOverlay;   
  330.     //一些輸入裝置(輸入裝置管理器)   
  331.     OIS::InputManager* mInputManager;   
  332.     //滑鼠   
  333.     OIS::Mouse*    mMouse;   
  334.     //鍵盤   
  335.     OIS::Keyboard* mKeyboard;   
  336.     //搖杆   
  337.     OIS::JoyStick* mJoy;   
  338. };   
  339. #endif  
#ifndef __ExampleFrameListener_H__
#define __ExampleFrameListener_H__

#include "Ogre.h"
#include "OgreStringConverter.h"
#include "OgreException.h"
#define OIS_DYNAMIC_LIB
#include <OIS/OIS.h>

using namespace Ogre;

class ExampleFrameListener: public FrameListener, public WindowEventListener
{
protected:
	virtual void updateStats(void)
	{
		static String currFps = "Current FPS: ";
		static String avgFps = "Average FPS: ";
		static String bestFps = "Best FPS: ";
		static String worstFps = "Worst FPS: ";
		static String tris = "Triangle Count: ";
		static String batches = "Batch Count: ";

		// 需要更新debug資訊時更新
		try {
			OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
			OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
			OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
			OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");

			const RenderTarget::FrameStats& stats = mWindow->getStatistics();
			guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
			guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS));
			guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS)
				+" "+StringConverter::toString(stats.bestFrameTime)+" ms");
			guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS)
				+" "+StringConverter::toString(stats.worstFrameTime)+" ms");

			OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
			guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount));

			OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches");
			guiBatches->setCaption(batches + StringConverter::toString(stats.batchCount));

			OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
			guiDbg->setCaption(mDebugText);
		}
		catch(...) { /* ignore */ }
	}

public:
	// 構造函數,初始化成員變量
	ExampleFrameListener(RenderWindow* win, Camera* cam, bool bufferedKeys = false, bool bufferedMouse = false,
			     bool bufferedJoy = false ) :
		mCamera(cam), mTranslateVector(Vector3::ZERO), mCurrentSpeed(0), mWindow(win), mStatsOn(true), mNumScreenShots(0),
		mMoveScale(0.0f), mRotScale(0.0f), mTimeUntilNextToggle(0), mFiltering(TFO_BILINEAR),
		mAniso(1), mSceneDetailIndex(0), mMoveSpeed(100), mRotateSpeed(36), mDebugOverlay(0),
		mInputManager(0), mMouse(0), mKeyboard(0), mJoy(0)
	{
		//得到debug視圖
		mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
		//日志管理器
		LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
		OIS::ParamList pl;
		size_t windowHnd = 0;
		std::ostringstream windowHndStr;
		//取得自定義的屬性
		win->getCustomAttribute("WINDOW", &windowHnd);
		windowHndStr << windowHnd;
		pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
		//建立輸入管理器
		mInputManager = OIS::InputManager::createInputSystem( pl );

		//建立輸入裝置、滑鼠、鍵盤、搖杆
		mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, bufferedKeys ));
		mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, bufferedMouse ));
		try {
			mJoy = static_cast<OIS::JoyStick*>(mInputManager->createInputObject( OIS::OISJoyStick, bufferedJoy ));
		}
		catch(...) {
			mJoy = 0;
		}

		//根據視窗的大小來設定滑鼠的初始裁剪區域
		windowResized(mWindow);
		//顯示debug資訊
		showDebugOverlay(true);

		//注冊一個windows視窗事件監聽
		WindowEventUtilities::addWindowEventListener(mWindow, this);
	}

	//調整滑鼠裁剪區域
	virtual void windowResized(RenderWindow* rw)
	{
		unsigned int width, height, depth;
		int left, top;
		//取得視窗矩陣
		rw->getMetrics(width, height, depth, left, top);
		//得到滑鼠
		const OIS::MouseState &ms = mMouse->getMouseState();
		ms.width = width;
		ms.height = height;
	}

	//關閉視窗之前進行的處理
	virtual void windowClosed(RenderWindow* rw)
	{
		//檢測是否關閉了我們的渲染視窗
		if( rw == mWindow )
		{
			if( mInputManager )
			{
				//清除輸入裝置
				mInputManager->destroyInputObject( mMouse );
				mInputManager->destroyInputObject( mKeyboard );
				mInputManager->destroyInputObject( mJoy );
				//銷毀輸入管理器
				OIS::InputManager::destroyInputSystem(mInputManager);
				mInputManager = 0;
			}
		}
	}

	virtual ~ExampleFrameListener()
	{
		//移除所有的視窗事件監聽
		WindowEventUtilities::removeWindowEventListener(mWindow, this);
		//關閉視窗
		windowClosed(mWindow);
	}
	//按鍵事件處理
	virtual bool processUnbufferedKeyInput(const FrameEvent& evt)
	{

		if(mKeyboard->isKeyDown(OIS::KC_A))
			mTranslateVector.x = -mMoveScale;	// 向左移動攝像頭矩陣

		if(mKeyboard->isKeyDown(OIS::KC_D))
			mTranslateVector.x = mMoveScale;	// Move camera RIGHT

		if(mKeyboard->isKeyDown(OIS::KC_UP) || mKeyboard->isKeyDown(OIS::KC_W) )
			mTranslateVector.z = -mMoveScale;	// Move camera forward

		if(mKeyboard->isKeyDown(OIS::KC_DOWN) || mKeyboard->isKeyDown(OIS::KC_S) )
			mTranslateVector.z = mMoveScale;	// Move camera backward

		if(mKeyboard->isKeyDown(OIS::KC_PGUP))
			mTranslateVector.y = mMoveScale;	// Move camera up

		if(mKeyboard->isKeyDown(OIS::KC_PGDOWN))
			mTranslateVector.y = -mMoveScale;	// Move camera down

		if(mKeyboard->isKeyDown(OIS::KC_RIGHT))
			mCamera->yaw(-mRotScale);

		if(mKeyboard->isKeyDown(OIS::KC_LEFT))
			mCamera->yaw(mRotScale);

		if( mKeyboard->isKeyDown(OIS::KC_ESCAPE) || mKeyboard->isKeyDown(OIS::KC_Q) )
			return false;

       	if( mKeyboard->isKeyDown(OIS::KC_F) && mTimeUntilNextToggle <= 0 )
		{
			mStatsOn = !mStatsOn;
			showDebugOverlay(mStatsOn);
			mTimeUntilNextToggle = 1;
		}

		if( mKeyboard->isKeyDown(OIS::KC_T) && mTimeUntilNextToggle <= 0 )
		{
			switch(mFiltering)
			{
			case TFO_BILINEAR:
				mFiltering = TFO_TRILINEAR;
				mAniso = 1;
				break;
			case TFO_TRILINEAR:
				mFiltering = TFO_ANISOTROPIC;
				mAniso = 8;
				break;
			case TFO_ANISOTROPIC:
				mFiltering = TFO_BILINEAR;
				mAniso = 1;
				break;
			default: break;
			}
			MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
			MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);

			showDebugOverlay(mStatsOn);
			mTimeUntilNextToggle = 1;
		}

		if(mKeyboard->isKeyDown(OIS::KC_SYSRQ) && mTimeUntilNextToggle <= 0)
		{
			std::ostringstream ss;
			ss << "screenshot_" << ++mNumScreenShots << ".png";
			mWindow->writeContentsToFile(ss.str());
			mTimeUntilNextToggle = 0.5;
			mDebugText = "Saved: " + ss.str();
		}

		if(mKeyboard->isKeyDown(OIS::KC_R) && mTimeUntilNextToggle <=0)
		{
			mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;
			switch(mSceneDetailIndex) {
				case 0 : mCamera->setPolygonMode(PM_SOLID); break;//設定多邊形的模式
				case 1 : mCamera->setPolygonMode(PM_WIREFRAME); break;
				case 2 : mCamera->setPolygonMode(PM_POINTS); break;
			}
			mTimeUntilNextToggle = 0.5;
		}

		static bool displayCameraDetails = false;
		if(mKeyboard->isKeyDown(OIS::KC_P) && mTimeUntilNextToggle <= 0)
		{
			displayCameraDetails = !displayCameraDetails;
			mTimeUntilNextToggle = 0.5;
			if (!displayCameraDetails)
				mDebugText = "";
		}

		if(displayCameraDetails)
			mDebugText = "P: " + StringConverter::toString(mCamera->getDerivedPosition()) +
						 " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation());
		return true;
	}
	//滑鼠事件處理
	virtual bool processUnbufferedMouseInput(const FrameEvent& evt)
	{

		// Rotation factors, may not be used if the second mouse button is pressed
		// 2nd mouse button - slide, otherwise rotate
		const OIS::MouseState &ms = mMouse->getMouseState();
		if( ms.buttonDown( OIS::MB_Right ) )
		{
			mTranslateVector.x += ms.X.rel * 0.13;
			mTranslateVector.y -= ms.Y.rel * 0.13;
		}
		else
		{
			mRotX = Degree(-ms.X.rel * 0.13);
			mRotY = Degree(-ms.Y.rel * 0.13);
		}

		return true;
	}

	//移動攝像頭
	virtual void moveCamera()
	{
		//偏移
		mCamera->yaw(mRotX);
		//傾斜
		mCamera->pitch(mRotY);
		//移動錄影機到指定位置
		mCamera->moveRelative(mTranslateVector);
	}
	//顯示debug資訊
	virtual void showDebugOverlay(bool show)
	{
		if (mDebugOverlay)
		{
			if (show)
				mDebugOverlay->show();
			else
				mDebugOverlay->hide();
		}
	}

	// 渲染隊列
	bool frameRenderingQueued(const FrameEvent& evt)
	{

		if(mWindow->isClosed())	return false;

		mSpeedLimit = mMoveScale * evt.timeSinceLastFrame;

		//捕獲、更新裝置
		mKeyboard->capture();
		mMouse->capture();
		if( mJoy ) mJoy->capture();

		bool buffJ = (mJoy) ? mJoy->buffered() : true;

    	Ogre::Vector3 lastMotion = mTranslateVector;
		if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
		{
			// one of the input modes is immediate, so setup what is needed for immediate movement
			if (mTimeUntilNextToggle >= 0)
				mTimeUntilNextToggle -= evt.timeSinceLastFrame;

			// Move about 100 units per second
			mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
			// Take about 10 seconds for full rotation
			mRotScale = mRotateSpeed * evt.timeSinceLastFrame;

			mRotX = 0;
			mRotY = 0;
			mTranslateVector = Ogre::Vector3::ZERO;

		}

		//Check to see which device is not buffered, and handle it
		if( !mKeyboard->buffered() )
			if( processUnbufferedKeyInput(evt) == false )
				return false;
		if( !mMouse->buffered() )
			if( processUnbufferedMouseInput(evt) == false )
				return false;

		// ramp up / ramp down speed
    	if (mTranslateVector == Ogre::Vector3::ZERO)
		{
			// decay (one third speed)
			mCurrentSpeed -= evt.timeSinceLastFrame * 0.3;
			mTranslateVector = lastMotion;
		}
		else
		{
			// ramp up
			mCurrentSpeed += evt.timeSinceLastFrame;

		}
		// Limit motion speed
		if (mCurrentSpeed > 1.0)
			mCurrentSpeed = 1.0;
		if (mCurrentSpeed < 0.0)
			mCurrentSpeed = 0.0;

		mTranslateVector *= mCurrentSpeed;


		if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
			moveCamera();

		return true;
	}

	//幀結束,更新狀态
	bool frameEnded(const FrameEvent& evt)
	{
		updateStats();
		return true;
	}

protected:
	//指向錄影機的指針
	Camera* mCamera;
	//一個3維向量,用于錄影機的位置變換
	Vector3 mTranslateVector;
	Real mCurrentSpeed;
	//指向渲染視窗的指針
	RenderWindow* mWindow;
	//是否顯示調試資訊
	bool mStatsOn;
	//debug資訊
	std::string mDebugText;
	//主要用于截圖
	unsigned int mNumScreenShots;
	//該demo中,錄影機會旋轉
	float mMoveScale;
	//速度限制
	float mSpeedLimit;
	//同樣用于錄影機變換
	Degree mRotScale;
	//延時
	Real mTimeUntilNextToggle ;
	//滑鼠旋轉的角度,用于錄影機的更新
	Radian mRotX, mRotY;
	//紋理內插補點的類型,枚舉類型
	TextureFilterOptions mFiltering;
	int mAniso;
	int mSceneDetailIndex ;
	//移動速度
	Real mMoveSpeed;
	//旋轉速度
	Degree mRotateSpeed;
	//debug視圖
	Overlay* mDebugOverlay;

	//一些輸入裝置(輸入裝置管理器)
	OIS::InputManager* mInputManager;
	//滑鼠
	OIS::Mouse*    mMouse;
	//鍵盤
	OIS::Keyboard* mKeyboard;
	//搖杆
	OIS::JoyStick* mJoy;
};

#endif
           

首先,我們要分析的就是Root類,使用Ogre的程式所需要作的第一件事情就是執行個體化一個Root對象。如果沒有這個對象,你就無法調用(除了日志管理以外)的任何一個功能。Root類的構造函數接受一些符串對象的參數,這些字元代表着不同作用的檔案名稱。

Cpp代碼

ogre研究之第一個程式
  1. Root * root = new Root();   
  2. Root * root = new Root("plugins.cfg");    
  3. Root * root = new Root("plugins.cfg", "ogre.cfg");   
  4. Root * root = new Root("plugins.cfg", "ogre.cfg", "ogre.log");   
  5. Root * root = new 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檔案例子

Java代碼

ogre研究之第一個程式
  1. # Defines plugins to load   
  2. # Define plugin folder   
  3. PluginFolder=.   
  4. # Define plugins   
  5. Plugin=RenderSystem_Direct3D9_d   
  6. Plugin=RenderSystem_GL_d   
  7. Plugin=Plugin_ParticleFX_d   
  8. Plugin=Plugin_BSPSceneManager_d   
  9. Plugin=Plugin_CgProgramManager_d   
  10. Plugin=Plugin_PCZSceneManager_d.dll   
  11. Plugin=Plugin_OctreeZone_d.dll   
  12. Plugin=Plugin_OctreeSceneManager_d  
# 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則是一個屬性配置檔案,主要儲存使用者自定義的一些屬性,即下圖所示的界面的一些屬性。

ogre研究之第一個程式

檔案如下:

Java代碼

ogre研究之第一個程式
  1. Render System=Direct3D9 Rendering Subsystem   
  2. [Direct3D9 Rendering Subsystem]   
  3. Allow NVPerfHUD=No   
  4. Anti aliasing=None   
  5. Floating-point mode=Fastest   
  6. Full Screen=No   
  7. Rendering Device=Mobile Intel(R) 945 Express Chipset Family   
  8. VSync=No   
  9. Video Mode=800 x 600 @ 32-bit colour   
  10. sRGB Gamma Conversion=No   
  11. [OpenGL Rendering Subsystem]   
  12. Colour Depth=32  
  13. Display Frequency=N/A   
  14. FSAA=0  
  15. Full Screen=No   
  16. RTT Preferred Mode=FBO   
  17. VSync=No   
  18. Video Mode=1024 x 768  
  19. sRGB Gamma Conversion=No  
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 :日志檔案,用于輸出一些調試資訊等,比如下代碼:

Cpp代碼

ogre研究之第一個程式
  1. LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***")  
LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***")
           

就會在 Ogre.log檔案中輸出"*** Initializing OIS ***"資訊。

另外需要說明得就是FrameListener接口了,當Ogre渲染每一幀的開始和結束的時候會回調FrameListener接口的方法,其中主要包括如下兩個渲染方法。

Cpp代碼

ogre研究之第一個程式
  1. class ExampleFrameListener : public FrameListener{   
  2. public:   
  3.     bool frameStarted (const FrameEvent &evt);   
  4.     bool frameEnded (const FrameEvent &evt );   
  5. };   
  6. bool ExampleFrameListener::frameStarted (const FrameEvent &evt){   
  7.     //在每一幀畫面渲染前   
  8.     return true;   
  9. }   
  10. bool ExampleFrameListener::frameEnded (const FrameEvent &evt ){   
  11.     //在每一幀畫面渲染後   
  12.     return true;   
  13. }  
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 之間。

Cpp代碼

ogre研究之第一個程式
  1. //設定環境光     
  2. mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) )   
//設定環境光  
mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) ) 
           

2:建立一個 Entity (物體),通過調用 SceneManager 的 createEntity 方法來建立

Cpp代碼

ogre研究之第一個程式
  1. //建立一個物體   
  2. Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );  
//建立一個物體
Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );
           

變量 mSceneMgr 是目前場景管理器的一個對象,createEntity 方法的第一個參數是為所建立的實體指定一個唯一的辨別,第二個參數 "robot.mesh" 指明要使用的網格實體,"robot.mesh" 網格實體在 ExampleApplication 類中被裝載。這樣,就已經建立了一個實體。

3:還需要建立一個場景節點來與它綁定在一起。既然每個場景管理器都有一個根節點,那我們就在根節點下建立一個場景節點。

Cpp代碼

ogre研究之第一個程式
  1. //建立該物體對應的場景節點   
  2. SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );  
//建立該物體對應的場景節點
SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );
           

 首先調用場景管理器的 getRootSceneNode 方法來擷取根節點,再使用根節點的 createChildSceneNode 方法建立一個名為 "RobotNode" 的場景節點。與實體一樣,場景節點的名字也是唯一的。

4:最後,将實體與場景節點綁定在一起,這樣機器人(Robot)就會在指定的位置被渲染:

Cpp代碼

  1. //将該物體和場景節點關聯起來   
  2. node1->attachObject( ent1 );  
//将該物體和場景節點關聯起來
node1->attachObject( ent1 );
           

ok,現在編譯運作你的程式,就可以看到我們偉大的機器人界面了。 

最後說一下,在建立Root對象時的檔案一般會和程式最後的可執行檔案在同一目錄(因為有人說找不到這些檔案)。祝你成功!