ogre研究之第一个程序

来源:互联网 发布:淘宝超级会员 iphone 编辑:程序博客网 时间:2024/04/27 17:03

这里我们主要是实现在程序中装载一个简单的模型并显示出来。

 

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



 

例子很简单,代码页不多,就4行。我们还是一步一步来分析吧。

 

首先我们上一个项目中的OgreDemo1类继承自ExampleApplication类,我们之所以什么都没有做就能创建一个窗口,就是因为ExampleApplication为我们实现了。

 

首先我们打开ExampleApplication类,可以看到包含了如下几个成员变量(下乳了少许注释)

 

Cpp代码 复制代码
  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;  

这里的ExampleFrameListener类,如果你暂时还不清楚是做什么的,不要紧,后面我们慢慢介绍。

 

知道了这些成员变量,我们在返回OgreDemo1.c文件中看看入口函数WinMain中是如何书写的呢?很简单就一句话:

Cpp代码 复制代码
  1. app.go();  

先将源代码贴出来,加了详细注意:

ExampleApplication.h

Cpp代码 复制代码
  1. #ifndef __ExampleApplication_H__   
  2. #define __ExampleApplication_H__   
  3.   
  4. #include "Ogre.h"   
  5. #include "OgreConfigFile.h"   
  6. #include "ExampleFrameListener.h"   
  7.   
  8. #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE   
  9. #include <CoreFoundation/CoreFoundation.h>   
  10.   
  11. std::string macBundlePath()   
  12. {   
  13.     char path[1024];   
  14.     CFBundleRef mainBundle = CFBundleGetMainBundle();   
  15.     assert(mainBundle);   
  16.   
  17.     CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);   
  18.     assert(mainBundleURL);   
  19.   
  20.     CFStringRef cfStringRef = CFURLCopyFileSystemPath( mainBundleURL, kCFURLPOSIXPathStyle);   
  21.     assert(cfStringRef);   
  22.   
  23.     CFStringGetCString(cfStringRef, path, 1024, kCFStringEncodingASCII);   
  24.   
  25.     CFRelease(mainBundleURL);   
  26.     CFRelease(cfStringRef);   
  27.   
  28.     return std::string(path);   
  29. }   
  30. #endif   
  31.   
  32. using namespace Ogre;   
  33.   
  34. /** Base class which manages the standard startup of an Ogre application.  
  35.     Designed to be subclassed for specific examples if required.  
  36. */  
  37. class ExampleApplication   
  38. {   
  39. public:   
  40.     ExampleApplication()   
  41.     {   
  42.         mFrameListener = 0;   
  43.         mRoot = 0;   
  44. #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE   
  45.         mResourcePath = macBundlePath() + "/Contents/Resources/";   
  46. #else   
  47.         mResourcePath = "";   
  48. #endif   
  49.     }   
  50.     /// Standard destructor   
  51.     virtual ~ExampleApplication()   
  52.     {   
  53.         if (mFrameListener)   
  54.             delete mFrameListener;   
  55.         if (mRoot)   
  56.             OGRE_DELETE mRoot;   
  57.     }   
  58.   
  59.     /// 程序的入口   
  60.     virtual void go(void)   
  61.     {   
  62.         //进行初始化工作   
  63.         if (!setup())   
  64.             return;   
  65.         //开始渲染   
  66.         mRoot->startRendering();   
  67.         // 清理屏幕   
  68.         destroyScene();   
  69.     }   
  70.   
  71. protected:   
  72.     //ogre的程序"根"任何ogre程序都会有改对象   
  73.     Root *mRoot;   
  74.     //摄像机镜头   
  75.     Camera* mCamera;   
  76.     //场景管理器   
  77.     SceneManager* mSceneMgr;   
  78.     //对于每一帧进行处理的类   
  79.     ExampleFrameListener* mFrameListener;   
  80.     //渲染窗口   
  81.     RenderWindow* mWindow;   
  82.     //资源文件的路径字符串   
  83.     Ogre::String mResourcePath;   
  84.     //初始化应用程序   
  85.     virtual bool setup(void)   
  86.     {   
  87.         String pluginsPath;   
  88. #ifndef OGRE_STATIC_LIB   
  89.         pluginsPath = mResourcePath + "plugins.cfg";   
  90. #endif   
  91.         //构建Root对象   
  92.         mRoot = OGRE_NEW Root(pluginsPath,    
  93.             mResourcePath + "ogre.cfg", mResourcePath + "Ogre.log");   
  94.         //配置资源文件相关   
  95.         setupResources();   
  96.         //配置,主要用于初始化渲染窗口   
  97.         bool carryOn = configure();   
  98.         if (!carryOn) return false;   
  99.         //创建场景管理器   
  100.         chooseSceneManager();   
  101.         //创建摄像机   
  102.         createCamera();   
  103.         //创建视口   
  104.         createViewports();   
  105.            
  106.         TextureManager::getSingleton().setDefaultNumMipmaps(5);   
  107.         //创建资源监听   
  108.         createResourceListener();   
  109.         //床在资源   
  110.         loadResources();   
  111.         //创建屏幕,必须重写,也就是我们OgreDemo1类中(我们现实模型需要实现的)   
  112.         createScene();   
  113.         //创建帧监听   
  114.         createFrameListener();   
  115.         return true;   
  116.     }   
  117.     /** 是否配置完成,完成则初始化系统 */  
  118.     virtual bool configure(void)   
  119.     {   
  120.         //判断是否进入(即运行过了配置窗口,进入demo窗口)   
  121.         if(mRoot->showConfigDialog())   
  122.         {   
  123.             //初始化系统,得到一个渲染窗口对象   
  124.             mWindow = mRoot->initialise(true);   
  125.             return true;   
  126.         }   
  127.         else  
  128.         {   
  129.             return false;   
  130.         }   
  131.     }   
  132.   
  133.     virtual void chooseSceneManager(void)   
  134.     {   
  135.         // 创建一个场景管理器(场景类型,窗口标题)   
  136.         mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "ExampleSMInstance");   
  137.     }   
  138.     virtual void createCamera(void)   
  139.     {   
  140.         // 创建一个摄像机   
  141.         mCamera = mSceneMgr->createCamera("PlayerCam");   
  142.   
  143.         // 设置摄像机的位置   
  144.         mCamera->setPosition(Vector3(0,0,500));   
  145.         // 设置观察点   
  146.         mCamera->lookAt(Vector3(0,0,-300));   
  147.         // 设置最近裁剪距离,如果超出则不显示   
  148.         mCamera->setNearClipDistance(5);   
  149.         //同样还有设置最远裁剪距离   
  150.         //mCamera->setFarClipDistance(1000);   
  151.     }   
  152.     //创建帧监听   
  153.     virtual void createFrameListener(void)   
  154.     {   
  155.         //实例化帧监听,(渲染窗口,摄像机)   
  156.         mFrameListener= new ExampleFrameListener(mWindow, mCamera);   
  157.         //设置是否显示调试信息(比如:fps...)   
  158.         mFrameListener->showDebugOverlay(true);   
  159.         //添加帧监听到root中   
  160.         mRoot->addFrameListener(mFrameListener);   
  161.     }   
  162.     //创建屏幕   
  163.     virtual void createScene(void) = 0;    
  164.     //清屏   
  165.     virtual void destroyScene(void){}   
  166.     /* 创建视口并初始化 */  
  167.     virtual void createViewports(void)   
  168.     {   
  169.         // 创建一个“视口”   
  170.         Viewport* vp = mWindow->addViewport(mCamera);   
  171.         //设置背景颜色   
  172.         vp->setBackgroundColour(ColourValue(0,0,0));   
  173.   
  174.         //设置屏幕的长宽比(视口的宽度和高度比,目前的宽屏电脑)   
  175.         mCamera->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));   
  176.     }   
  177.   
  178.     /// 初始化资源,比如:模型、贴图等资源   
  179.     virtual void setupResources(void)   
  180.     {   
  181.         ConfigFile cf;   
  182.         //读取配置文件   
  183.         cf.load(mResourcePath + "resources.cfg");   
  184.         ConfigFile::SectionIterator seci = cf.getSectionIterator();   
  185.         String secName, typeName, archName;   
  186.         while (seci.hasMoreElements())   
  187.         {   
  188.             secName = seci.peekNextKey();   
  189.             ConfigFile::SettingsMultiMap *settings = seci.getNext();   
  190.             ConfigFile::SettingsMultiMap::iterator i;   
  191.             for (i = settings->begin(); i != settings->end(); ++i)   
  192.             {   
  193.                 //取得并添加资源文件   
  194.                 typeName = i->first;   
  195.                 archName = i->second;   
  196. #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE   
  197.                 ResourceGroupManager::getSingleton().addResourceLocation(   
  198.                     String(macBundlePath() + "/" + archName), typeName, secName);   
  199. #else   
  200.                 ResourceGroupManager::getSingleton().addResourceLocation(   
  201.                     archName, typeName, secName);   
  202. #endif   
  203.             }   
  204.         }   
  205.     }   
  206.   
  207.     //创建资源监听,比如(正在装载资源,请稍等界面)   
  208.     virtual void createResourceListener(void)   
  209.     {   
  210.     }   
  211.   
  212.     //装载资源   
  213.     virtual void loadResources(void)   
  214.     {   
  215.         ResourceGroupManager::getSingleton().initialiseAllResourceGroups();   
  216.     }   
  217. };   
  218.   
  219.   
  220. #endif  

ExampleFrameListener.h 

Cpp代码 复制代码
  1. #ifndef __ExampleFrameListener_H__   
  2. #define __ExampleFrameListener_H__   
  3.   
  4. #include "Ogre.h"   
  5. #include "OgreStringConverter.h"   
  6. #include "OgreException.h"   
  7. #define OIS_DYNAMIC_LIB   
  8. #include <OIS/OIS.h>   
  9.   
  10. using namespace Ogre;   
  11.   
  12. class ExampleFrameListener: public FrameListener, public WindowEventListener   
  13. {   
  14. protected:   
  15.     virtual void updateStats(void)   
  16.     {   
  17.         static String currFps = "Current FPS: ";   
  18.         static String avgFps = "Average FPS: ";   
  19.         static String bestFps = "Best FPS: ";   
  20.         static String worstFps = "Worst FPS: ";   
  21.         static String tris = "Triangle Count: ";   
  22.         static String batches = "Batch Count: ";   
  23.   
  24.         // 需要更新debug信息时更新   
  25.         try {   
  26.             OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");   
  27.             OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");   
  28.             OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");   
  29.             OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");   
  30.   
  31.             const RenderTarget::FrameStats& stats = mWindow->getStatistics();   
  32.             guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));   
  33.             guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS));   
  34.             guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS)   
  35.                 +" "+StringConverter::toString(stats.bestFrameTime)+" ms");   
  36.             guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS)   
  37.                 +" "+StringConverter::toString(stats.worstFrameTime)+" ms");   
  38.   
  39.             OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");   
  40.             guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount));   
  41.   
  42.             OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches");   
  43.             guiBatches->setCaption(batches + StringConverter::toString(stats.batchCount));   
  44.   
  45.             OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");   
  46.             guiDbg->setCaption(mDebugText);   
  47.         }   
  48.         catch(...) { /* ignore */ }   
  49.     }   
  50.   
  51. public:   
  52.     // 构造函数,初始化成员变量   
  53.     ExampleFrameListener(RenderWindow* win, Camera* cam, bool bufferedKeys = falsebool bufferedMouse = false,   
  54.                  bool bufferedJoy = false ) :   
  55.         mCamera(cam), mTranslateVector(Vector3::ZERO), mCurrentSpeed(0), mWindow(win), mStatsOn(true), mNumScreenShots(0),   
  56.         mMoveScale(0.0f), mRotScale(0.0f), mTimeUntilNextToggle(0), mFiltering(TFO_BILINEAR),   
  57.         mAniso(1), mSceneDetailIndex(0), mMoveSpeed(100), mRotateSpeed(36), mDebugOverlay(0),   
  58.         mInputManager(0), mMouse(0), mKeyboard(0), mJoy(0)   
  59.     {   
  60.         //得到debug视图   
  61.         mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");   
  62.         //日志管理器   
  63.         LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");   
  64.         OIS::ParamList pl;   
  65.         size_t windowHnd = 0;   
  66.         std::ostringstream windowHndStr;   
  67.         //取得自定义的属性   
  68.         win->getCustomAttribute("WINDOW", &windowHnd);   
  69.         windowHndStr << windowHnd;   
  70.         pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));   
  71.         //创建输入管理器   
  72.         mInputManager = OIS::InputManager::createInputSystem( pl );   
  73.   
  74.         //创建输入设备、鼠标、键盘、摇杆   
  75.         mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, bufferedKeys ));   
  76.         mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, bufferedMouse ));   
  77.         try {   
  78.             mJoy = static_cast<OIS::JoyStick*>(mInputManager->createInputObject( OIS::OISJoyStick, bufferedJoy ));   
  79.         }   
  80.         catch(...) {   
  81.             mJoy = 0;   
  82.         }   
  83.   
  84.         //根据窗口的大小来设置鼠标的初始裁剪区域   
  85.         windowResized(mWindow);   
  86.         //显示debug信息   
  87.         showDebugOverlay(true);   
  88.   
  89.         //注册一个windows窗口事件监听   
  90.         WindowEventUtilities::addWindowEventListener(mWindow, this);   
  91.     }   
  92.   
  93.     //调整鼠标裁剪区域   
  94.     virtual void windowResized(RenderWindow* rw)   
  95.     {   
  96.         unsigned int width, height, depth;   
  97.         int left, top;   
  98.         //取得窗口矩阵   
  99.         rw->getMetrics(width, height, depth, left, top);   
  100.         //得到鼠标   
  101.         const OIS::MouseState &ms = mMouse->getMouseState();   
  102.         ms.width = width;   
  103.         ms.height = height;   
  104.     }   
  105.   
  106.     //关闭窗口之前进行的处理   
  107.     virtual void windowClosed(RenderWindow* rw)   
  108.     {   
  109.         //检测是否关闭了我们的渲染窗口   
  110.         if( rw == mWindow )   
  111.         {   
  112.             if( mInputManager )   
  113.             {   
  114.                 //清除输入设备   
  115.                 mInputManager->destroyInputObject( mMouse );   
  116.                 mInputManager->destroyInputObject( mKeyboard );   
  117.                 mInputManager->destroyInputObject( mJoy );   
  118.                 //销毁输入管理器   
  119.                 OIS::InputManager::destroyInputSystem(mInputManager);   
  120.                 mInputManager = 0;   
  121.             }   
  122.         }   
  123.     }   
  124.   
  125.     virtual ~ExampleFrameListener()   
  126.     {   
  127.         //移除所有的窗口事件监听   
  128.         WindowEventUtilities::removeWindowEventListener(mWindow, this);   
  129.         //关闭窗口   
  130.         windowClosed(mWindow);   
  131.     }   
  132.     //按键事件处理   
  133.     virtual bool processUnbufferedKeyInput(const FrameEvent& evt)   
  134.     {   
  135.   
  136.         if(mKeyboard->isKeyDown(OIS::KC_A))   
  137.             mTranslateVector.x = -mMoveScale;   // 向左移动摄像头矩阵   
  138.   
  139.         if(mKeyboard->isKeyDown(OIS::KC_D))   
  140.             mTranslateVector.x = mMoveScale;    // Move camera RIGHT   
  141.   
  142.         if(mKeyboard->isKeyDown(OIS::KC_UP) || mKeyboard->isKeyDown(OIS::KC_W) )   
  143.             mTranslateVector.z = -mMoveScale;   // Move camera forward   
  144.   
  145.         if(mKeyboard->isKeyDown(OIS::KC_DOWN) || mKeyboard->isKeyDown(OIS::KC_S) )   
  146.             mTranslateVector.z = mMoveScale;    // Move camera backward   
  147.   
  148.         if(mKeyboard->isKeyDown(OIS::KC_PGUP))   
  149.             mTranslateVector.y = mMoveScale;    // Move camera up   
  150.   
  151.         if(mKeyboard->isKeyDown(OIS::KC_PGDOWN))   
  152.             mTranslateVector.y = -mMoveScale;   // Move camera down   
  153.   
  154.         if(mKeyboard->isKeyDown(OIS::KC_RIGHT))   
  155.             mCamera->yaw(-mRotScale);   
  156.   
  157.         if(mKeyboard->isKeyDown(OIS::KC_LEFT))   
  158.             mCamera->yaw(mRotScale);   
  159.   
  160.         if( mKeyboard->isKeyDown(OIS::KC_ESCAPE) || mKeyboard->isKeyDown(OIS::KC_Q) )   
  161.             return false;   
  162.   
  163.         if( mKeyboard->isKeyDown(OIS::KC_F) && mTimeUntilNextToggle <= 0 )   
  164.         {   
  165.             mStatsOn = !mStatsOn;   
  166.             showDebugOverlay(mStatsOn);   
  167.             mTimeUntilNextToggle = 1;   
  168.         }   
  169.   
  170.         if( mKeyboard->isKeyDown(OIS::KC_T) && mTimeUntilNextToggle <= 0 )   
  171.         {   
  172.             switch(mFiltering)   
  173.             {   
  174.             case TFO_BILINEAR:   
  175.                 mFiltering = TFO_TRILINEAR;   
  176.                 mAniso = 1;   
  177.                 break;   
  178.             case TFO_TRILINEAR:   
  179.                 mFiltering = TFO_ANISOTROPIC;   
  180.                 mAniso = 8;   
  181.                 break;   
  182.             case TFO_ANISOTROPIC:   
  183.                 mFiltering = TFO_BILINEAR;   
  184.                 mAniso = 1;   
  185.                 break;   
  186.             defaultbreak;   
  187.             }   
  188.             MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);   
  189.             MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);   
  190.   
  191.             showDebugOverlay(mStatsOn);   
  192.             mTimeUntilNextToggle = 1;   
  193.         }   
  194.   
  195.         if(mKeyboard->isKeyDown(OIS::KC_SYSRQ) && mTimeUntilNextToggle <= 0)   
  196.         {   
  197.             std::ostringstream ss;   
  198.             ss << "screenshot_" << ++mNumScreenShots << ".png";   
  199.             mWindow->writeContentsToFile(ss.str());   
  200.             mTimeUntilNextToggle = 0.5;   
  201.             mDebugText = "Saved: " + ss.str();   
  202.         }   
  203.   
  204.         if(mKeyboard->isKeyDown(OIS::KC_R) && mTimeUntilNextToggle <=0)   
  205.         {   
  206.             mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;   
  207.             switch(mSceneDetailIndex) {   
  208.                 case 0 : mCamera->setPolygonMode(PM_SOLID); break;//设置多边形的模式   
  209.                 case 1 : mCamera->setPolygonMode(PM_WIREFRAME); break;   
  210.                 case 2 : mCamera->setPolygonMode(PM_POINTS); break;   
  211.             }   
  212.             mTimeUntilNextToggle = 0.5;   
  213.         }   
  214.   
  215.         static bool displayCameraDetails = false;   
  216.         if(mKeyboard->isKeyDown(OIS::KC_P) && mTimeUntilNextToggle <= 0)   
  217.         {   
  218.             displayCameraDetails = !displayCameraDetails;   
  219.             mTimeUntilNextToggle = 0.5;   
  220.             if (!displayCameraDetails)   
  221.                 mDebugText = "";   
  222.         }   
  223.   
  224.         if(displayCameraDetails)   
  225.             mDebugText = "P: " + StringConverter::toString(mCamera->getDerivedPosition()) +   
  226.                          " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation());   
  227.         return true;   
  228.     }   
  229.     //鼠标事件处理   
  230.     virtual bool processUnbufferedMouseInput(const FrameEvent& evt)   
  231.     {   
  232.   
  233.         // Rotation factors, may not be used if the second mouse button is pressed   
  234.         // 2nd mouse button - slide, otherwise rotate   
  235.         const OIS::MouseState &ms = mMouse->getMouseState();   
  236.         if( ms.buttonDown( OIS::MB_Right ) )   
  237.         {   
  238.             mTranslateVector.x += ms.X.rel * 0.13;   
  239.             mTranslateVector.y -= ms.Y.rel * 0.13;   
  240.         }   
  241.         else  
  242.         {   
  243.             mRotX = Degree(-ms.X.rel * 0.13);   
  244.             mRotY = Degree(-ms.Y.rel * 0.13);   
  245.         }   
  246.   
  247.         return true;   
  248.     }   
  249.   
  250.     //移动摄像头   
  251.     virtual void moveCamera()   
  252.     {   
  253.         //偏移   
  254.         mCamera->yaw(mRotX);   
  255.         //倾斜   
  256.         mCamera->pitch(mRotY);   
  257.         //移动摄像机到指定位置   
  258.         mCamera->moveRelative(mTranslateVector);   
  259.     }   
  260.     //显示debug信息   
  261.     virtual void showDebugOverlay(bool show)   
  262.     {   
  263.         if (mDebugOverlay)   
  264.         {   
  265.             if (show)   
  266.                 mDebugOverlay->show();   
  267.             else  
  268.                 mDebugOverlay->hide();   
  269.         }   
  270.     }   
  271.   
  272.     // 渲染队列   
  273.     bool frameRenderingQueued(const FrameEvent& evt)   
  274.     {   
  275.   
  276.         if(mWindow->isClosed())  return false;   
  277.   
  278.         mSpeedLimit = mMoveScale * evt.timeSinceLastFrame;   
  279.   
  280.         //捕获、更新设备   
  281.         mKeyboard->capture();   
  282.         mMouse->capture();   
  283.         if( mJoy ) mJoy->capture();   
  284.   
  285.         bool buffJ = (mJoy) ? mJoy->buffered() : true;   
  286.   
  287.         Ogre::Vector3 lastMotion = mTranslateVector;   
  288.         if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )   
  289.         {   
  290.             // one of the input modes is immediate, so setup what is needed for immediate movement   
  291.             if (mTimeUntilNextToggle >= 0)   
  292.                 mTimeUntilNextToggle -= evt.timeSinceLastFrame;   
  293.   
  294.             // Move about 100 units per second   
  295.             mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;   
  296.             // Take about 10 seconds for full rotation   
  297.             mRotScale = mRotateSpeed * evt.timeSinceLastFrame;   
  298.   
  299.             mRotX = 0;   
  300.             mRotY = 0;   
  301.             mTranslateVector = Ogre::Vector3::ZERO;   
  302.   
  303.         }   
  304.   
  305.         //Check to see which device is not buffered, and handle it   
  306.         if( !mKeyboard->buffered() )   
  307.             if( processUnbufferedKeyInput(evt) == false )   
  308.                 return false;   
  309.         if( !mMouse->buffered() )   
  310.             if( processUnbufferedMouseInput(evt) == false )   
  311.                 return false;   
  312.   
  313.         // ramp up / ramp down speed   
  314.         if (mTranslateVector == Ogre::Vector3::ZERO)   
  315.         {   
  316.             // decay (one third speed)   
  317.             mCurrentSpeed -= evt.timeSinceLastFrame * 0.3;   
  318.             mTranslateVector = lastMotion;   
  319.         }   
  320.         else  
  321.         {   
  322.             // ramp up   
  323.             mCurrentSpeed += evt.timeSinceLastFrame;   
  324.   
  325.         }   
  326.         // Limit motion speed   
  327.         if (mCurrentSpeed > 1.0)   
  328.             mCurrentSpeed = 1.0;   
  329.         if (mCurrentSpeed < 0.0)   
  330.             mCurrentSpeed = 0.0;   
  331.   
  332.         mTranslateVector *= mCurrentSpeed;   
  333.   
  334.   
  335.         if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )   
  336.             moveCamera();   
  337.   
  338.         return true;   
  339.     }   
  340.   
  341.     //帧结束,更新状态   
  342.     bool frameEnded(const FrameEvent& evt)   
  343.     {   
  344.         updateStats();   
  345.         return true;   
  346.     }   
  347.   
  348. protected:   
  349.     //指向摄像机的指针   
  350.     Camera* mCamera;   
  351.     //一个3维向量,用于摄像机的位置变换   
  352.     Vector3 mTranslateVector;   
  353.     Real mCurrentSpeed;   
  354.     //指向渲染窗口的指针   
  355.     RenderWindow* mWindow;   
  356.     //是否显示调试信息   
  357.     bool mStatsOn;   
  358.     //debug信息   
  359.     std::string mDebugText;   
  360.     //主要用于截图   
  361.     unsigned int mNumScreenShots;   
  362.     //该demo中,摄像机会旋转   
  363.     float mMoveScale;   
  364.     //速度限制   
  365.     float mSpeedLimit;   
  366.     //同样用于摄像机变换   
  367.     Degree mRotScale;   
  368.     //延时   
  369.     Real mTimeUntilNextToggle ;   
  370.     //鼠标旋转的角度,用于摄像机的更新   
  371.     Radian mRotX, mRotY;   
  372.     //纹理差值的类型,枚举类型   
  373.     TextureFilterOptions mFiltering;   
  374.     int mAniso;   
  375.     int mSceneDetailIndex ;   
  376.     //移动速度   
  377.     Real mMoveSpeed;   
  378.     //旋转速度   
  379.     Degree mRotateSpeed;   
  380.     //debug视图   
  381.     Overlay* mDebugOverlay;   
  382.   
  383.     //一些输入设备(输入设备管理器)   
  384.     OIS::InputManager* mInputManager;   
  385.     //鼠标   
  386.     OIS::Mouse*    mMouse;   
  387.     //键盘   
  388.     OIS::Keyboard* mKeyboard;   
  389.     //摇杆   
  390.     OIS::JoyStick* mJoy;   
  391. };   
  392.   
  393. #endif  

首先,我们要分析的就是Root类,使用Ogre的程序所需要作的第一件事情就是实例化一个Root对象。如果没有这个对象,你就无法调用(除了日志管理以外)的任何一个功能。Root类的构造函数接受一些符串对象的参数,这些字符代表着不同作用的文件名称。

Cpp代码 复制代码
  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实例,这里面任何的方法都能单独的正确执行。参数也是系统所默认的值(“plugins.cfg”, “ogre.cfg”, “ogre.log”——当你没有填写参数的时候,系统就认为采用了默认的这些值)。 

plugins.cfg:插件,Ogre中所谓的插件就是符合Ogre插件接口的代码模块,比如场景管理(SceneManager)插件和渲染系统(RenderSystem)插件等。在启动的Ogre时候,他会载入plugins.cfg配置文件来查看有哪些插件可以被使用。下面是一个plugins.cfg文件例子

Java代码 复制代码
  1. # Defines plugins to load   
  2.   
  3. # Define plugin folder   
  4. PluginFolder=.   
  5.   
  6. # Define plugins   
  7. Plugin=RenderSystem_Direct3D9_d   
  8. Plugin=RenderSystem_GL_d   
  9. Plugin=Plugin_ParticleFX_d   
  10. Plugin=Plugin_BSPSceneManager_d   
  11. Plugin=Plugin_CgProgramManager_d   
  12. Plugin=Plugin_PCZSceneManager_d.dll   
  13. Plugin=Plugin_OctreeZone_d.dll   
  14. Plugin=Plugin_OctreeSceneManager_d  

其中PluginFolder用于定义这些插件存在的位置(路径),  这里使用“.”,表示需要在“/”或者“/”(即根目录)。在某些平台上可以不使用“.”直接使用""(空白),ogre照样会在“/”或者“/”中去找。

而Plugin则说明了有哪些插件可以使用,但是需要注意,这些插件都没有后缀名。

这里需要注意:在“=”两边不能加入空格或者 Tab字符。

 

ogre.cfg则是一个属性配置文件,主要保存用户自定义的一些属性,即下图所示的界面的一些属性。



文件如下:

Java代码 复制代码
  1. Render System=Direct3D9 Rendering Subsystem   
  2.   
  3. [Direct3D9 Rendering Subsystem]   
  4. Allow NVPerfHUD=No   
  5. Anti aliasing=None   
  6. Floating-point mode=Fastest   
  7. Full Screen=No   
  8. Rendering Device=Mobile Intel(R) 945 Express Chipset Family   
  9. VSync=No   
  10. Video Mode=800 x 600 @ 32-bit colour   
  11. sRGB Gamma Conversion=No   
  12.   
  13. [OpenGL Rendering Subsystem]   
  14. Colour Depth=32  
  15. Display Frequency=N/A   
  16. FSAA=0  
  17. Full Screen=No   
  18. RTT Preferred Mode=FBO   
  19. VSync=No   
  20. Video Mode=1024 x 768  
  21. sRGB Gamma Conversion=No  

相信这里就不用多解释,大家都明白了。

 

Ogre.log :日志文件,用于输出一些调试信息等,比如下代码:

Cpp代码 复制代码
  1. LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***")  

就会在 Ogre.log文件中输出"*** Initializing OIS ***"信息。

 

另外需要说明得就是FrameListener接口了,当Ogre渲染每一帧的开始和结束的时候会回调FrameListener接口的方法,其中主要包括如下两个渲染方法。

Cpp代码 复制代码
  1. class ExampleFrameListener : public FrameListener{   
  2. public:   
  3.     bool frameStarted (const FrameEvent &evt);   
  4.     bool frameEnded (const FrameEvent &evt );   
  5. };   
  6.   
  7. bool ExampleFrameListener::frameStarted (const FrameEvent &evt){   
  8.     //在每一帧画面渲染前   
  9.     return true;   
  10.   
  11. }   
  12. bool ExampleFrameListener::frameEnded (const FrameEvent &evt ){   
  13.     //在每一帧画面渲染后   
  14.     return true;   
  15. }  

所以我们就可以根据需要来实现这两个方式,实现渲染。 

 

注意:在新的版本中frameRenderingQueued方法基本上取代了frameStarted,所以本例中我们就是用了frameRenderingQueued,一般在这个函数中都需要检测各种输入设备的情况,以进行相应的处理。

 

最后,当我们在程序中调用mRoot->startRendering();方法时,就告诉ogre,我们需要开始渲染了。ogre就会开始渲染。也正是ExampleApplication类中的go方法,所做的,初始化(setup)完成之后就开始渲染(mRoot->startRendering())。

 

之所以有了这两个类,上一篇中我们才可以不写任何代码就可以构建一个窗口,那么本节内容,我们要显示模型当然就很简单了。

直接在OgreDemo1类的createScene方法中来实现,

1:设置环境光,首先需要为整个场景设置环境光,这样才可以看到要显示的内容,通过调用setAmbientLight函数并指定环境光的颜色就可以做到这些。指定的颜色由红、绿、蓝三种颜色组成,且每种色数值范围在 0 到 1 之间。

Cpp代码 复制代码
  1. //设置环境光     
  2. mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) )   

2:创建一个 Entity (物体),通过调用 SceneManager 的 createEntity 方法来创建

Cpp代码 复制代码
  1. //创建一个物体   
  2. Entity *ent1 = mSceneMgr->createEntity( "Robot""robot.mesh" );  

变量 mSceneMgr 是当前场景管理器的一个对象,createEntity 方法的第一个参数是为所创建的实体指定一个唯一的标识,第二个参数 "robot.mesh" 指明要使用的网格实体,"robot.mesh" 网格实体在 ExampleApplication 类中被装载。这样,就已经创建了一个实体。

3:还需要创建一个场景节点来与它绑定在一起。既然每个场景管理器都有一个根节点,那我们就在根节点下创建一个场景节点。

Cpp代码 复制代码
  1. //创建该物体对应的场景节点   
  2. SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );  

 首先调用场景管理器的 getRootSceneNode 方法来获取根节点,再使用根节点的 createChildSceneNode 方法创建一个名为 "RobotNode" 的场景节点。与实体一样,场景节点的名字也是唯一的。

4:最后,将实体与场景节点绑定在一起,这样机器人(Robot)就会在指定的位置被渲染:

Cpp代码
  1. //将该物体和场景节点关联起来   
  2. node1->attachObject( ent1 );  

ok,现在编译运行你的程序,就可以看到我们伟大的机器人界面了。 

 

最后说一下,在创建Root对象时的文件一般会和程序最后的可执行文件在同一目录(因为有人说找不到这些文件)。祝你成功!

原创粉丝点击