Win32 或 MFC 下初始化OGRE 窗口

这个问题经常有人要问, 网上其实能够搜索得到, 为什么还有这么多人要问:

一是,原来网上的版本有些旧, 会出一些错误

二是, 可能不太清楚,

今天我也写一个吧, 尽量详细,(可能也不太清楚^-^)
(注: 今天的例子为了便于理解, 我使用Win32窗口的框架, 不用MFC, 当然,Win32窗口跟MFC其实是一样的, 稍微转化一下即可)

新建一个Win32窗口的程序,本例子中名称为:Win32Ogre,

所有代码在Win32Ogre.cpp中, 代码如下, 解释全部看注释吧,:

  1. // Win32Ogre.cpp : Defines the entry point for the application.
  2. //
  3. #include "stdafx.h"
  4. #include "Win32Ogre.h"
  5. #include "ogre.h"
  6. #include "MyExampleFrameListener.h"
  7. #define MAX_LOADSTRING 100
  8. // Global Variables:
  9. HINSTANCE hInst;                                // current instance
  10. TCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
  11. TCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name
  12. HWND hWnd;
  13. //OGRE -------------------//
  14. Root* mRoot;
  15. RenderWindow* mWindow;
  16. SceneManager* mSceneMgr;
  17. Camera* mCamera;
  18. Viewport* vp ;
  19.  
  20. void setupResources();
  21. void SetRoot()
  22. {
  23.     //----创建根实例
  24.     mRoot = new Root();//无参数即默认参数Root("plugin.cfg","ogre.cfg","ogre.log")
  25.     //----设置资源目录(声明资源:此时资源未初始化,不可使用)
  26.     setupResources();//目录设置根据"resource.cfg"
  27.     if(!mRoot->showConfigDialog())//你不想弹出那个配置对话框就注释掉此句, 下面的程序是手动来配置,手动配置自动使用D3D
  28.     {
  29.     //-----初始化渲染器
  30.         RenderSystemList* rl = Root::getSingleton().getAvailableRenderers();//获得所有可用渲染器
  31.         RenderSystem* rsys = NULL;
  32.         RenderSystemList::iterator it = rl->begin();//循环列表,得到GL渲染器
  33.         while( it != rl->end() )
  34.         { 
  35.             if( -1 != ( *it )->getName().find( "3D9" )  )
  36.             {
  37.                 rsys = (RenderSystem*)( *it );
  38.                 break;
  39.             }
  40.             it++;
  41.         }
  42.     
  43.         //设置渲染器属性
  44.      
  45.         rsys->setConfigOption( "Full Screen""No" );
  46.         rsys->setConfigOption( "VSync""No" );
  47.     
  48.         rsys->setConfigOption( "Video Mode""800 x 600" );
  49.      
  50.         mRoot->setRenderSystem( rsys ); // 起用该渲染器
  51.     
  52.     
  53.         
  54.     }
  55.     mRoot->initialise(0);
  56.     
  57.     //-------初始化渲染窗口(自建)
  58.     NameValuePairList parms;
  59.     parms["externalWindowHandle"] = StringConverter::toString((long)hWnd);
  60.     RECT   rect;
  61.     ::GetWindowRect(hWnd,&rect);
  62.     mWindow = mRoot->createRenderWindow("MFC Window", rect.right-rect.left, rect.bottom-rect.top, false, &parms);
  63.     //渲染窗口事实上是由渲染器所创建RenderSystem::CreateRenderWindow
  64. }
  65. void CreateCamVP()
  66.     mCamera = mSceneMgr->createCamera("PlayerCam");
  67.     mCamera->setPosition(Vector3(0,0,500));
  68.     mCamera->lookAt(Vector3(0,0,-300));
  69.     mCamera->setNearClipDistance(1);
  70.     mCamera->setFarClipDistance(100000);
  71.     mCamera->setQueryFlags(8);//临时定一个掩码值,暂时与现在的所有掩码不冲突,保证检测不到相机
  72.     // -------创建视口
  73.     vp = mWindow->addViewport(mCamera);
  74.  
  75.     // 视口创建好后调整相机的比例
  76.     mCamera->setAspectRatio(
  77.         Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
  78. }
  79. //设置阴影
  80. void AddShadowEffect()
  81. {
  82.     mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE);
  83.     LiSPSMShadowCameraSetup* lispsm = new LiSPSMShadowCameraSetup();
  84.     lispsm->setOptimalAdjustFactor(0.5);
  85.     mSceneMgr->setShadowFarDistance(1000);
  86.     mSceneMgr->setShadowCameraSetup(ShadowCameraSetupPtr(lispsm));
  87.     mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5));
  88. }
  89. //设置场景相关的效果,如灯光,雾,天空,视口背景色等
  90. void SetAmbientRef()
  91. {
  92.     //--------创建灯光
  93.     Light* l = mSceneMgr->createLight("MainLight");
  94.     l->setPosition(20,2000,50);
  95.     //mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 800, 2000);
  96.     mSceneMgr->setAmbientLight(ColourValue(0.5,0.5,0.5));
  97.     ColourValue fadeColour(0.93, 0.86, 0.76);
  98.     mWindow->getViewport(0)->setBackgroundColour(fadeColour);
  99.  
  100.     mSceneMgr->setSkyBox(true"Examples/CloudyNoonSkyBox");
  101. }
  102. void setupResources()
  103. {
  104.     ConfigFile cf;
  105.     cf.load("resources.cfg");
  106.     // Go through all sections & settings in the file
  107.     ConfigFile::SectionIterator seci = cf.getSectionIterator();
  108.     String secName, typeName, archName;
  109.     while (seci.hasMoreElements())
  110.     {
  111.         secName = seci.peekNextKey();
  112.         ConfigFile::SettingsMultiMap *settings = seci.getNext();
  113.         ConfigFile::SettingsMultiMap::iterator i;
  114.         for (i = settings->begin(); i != settings->end(); ++i)
  115.         {
  116.             typeName = i->first;
  117.             archName = i->second;
  118.             ResourceGroupManager::getSingleton().addResourceLocation(
  119.                 archName, typeName, secName);
  120.         }
  121.     }
  122. }
  123. void CreateScene()
  124. {
  125.     //----------初始化OGRE(自动加载插件)----------------//
  126.     SetRoot();
  127.  
  128.     Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
  129.  
  130.     //-------创建场景管理器-------------------------------//
  131.     mSceneMgr = mRoot->createSceneManager(ST_GENERIC);//在新版本中,getSceneManager全部更新为createSceneManager
  132.      
  133.     //-----------打开阴影-------------------------------//
  134.     AddShadowEffect();
  135.     //=======================================================//
  136.     //--------创建相机并设置,创建视口----//
  137.     CreateCamVP();
  138.     //===================================//
  139.   
  140.     //-------设置环境相关,如灯光,雾,天空等------------//
  141.     SetAmbientRef();
  142.     //===================================================//
  143.      
  144.     //-------设置FramListener---------------------------//
  145.     MyExampleFrameListener *m_FramListenler=new MyExampleFrameListener(mWindow,mCamera,hWnd);
  146.     mRoot->addFrameListener(m_FramListenler);
  147.     //==================================================//.
  148.  
  149.     mWindow->update();
  150.      
  151. }
  152. //========================//
  153. // Forward declarations of functions included in this code module:
  154. ATOM                MyRegisterClass(HINSTANCE hInstance);
  155. BOOL                InitInstance(HINSTANCEint);
  156. LRESULT CALLBACK    WndProc(HWNDUINTWPARAMLPARAM);
  157. INT_PTR CALLBACK    About(HWNDUINTWPARAMLPARAM);
  158. int APIENTRY _tWinMain(HINSTANCE hInstance,
  159.                      HINSTANCE hPrevInstance,
  160.                      LPTSTR    lpCmdLine,
  161.                      int       nCmdShow)
  162. {
  163.     UNREFERENCED_PARAMETER(hPrevInstance);
  164.     UNREFERENCED_PARAMETER(lpCmdLine);
  165.     // TODO: Place code here.
  166.     MSG msg;
  167.     HACCEL hAccelTable;
  168.     // Initialize global strings
  169.     LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  170.     LoadString(hInstance, IDC_WIN32OGRE, szWindowClass, MAX_LOADSTRING);
  171.     MyRegisterClass(hInstance);
  172.     // Perform application initialization:
  173.     if (!InitInstance (hInstance, nCmdShow))
  174.     {
  175.         return FALSE;
  176.     }
  177.     hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32OGRE));
  178.     // Main message loop:
  179.     while (GetMessage(&msg, NULL, 0, 0))
  180.     {
  181.         if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  182.         {
  183.             TranslateMessage(&msg);
  184.             DispatchMessage(&msg);
  185.         }
  186.     }
  187.     return (int) msg.wParam;
  188. }
  189.  
  190. ATOM MyRegisterClass(HINSTANCE hInstance)
  191. {
  192.     WNDCLASSEX wcex;
  193.     wcex.cbSize = sizeof(WNDCLASSEX);
  194.     wcex.style          = CS_HREDRAW | CS_VREDRAW;
  195.     wcex.lpfnWndProc    = WndProc;
  196.     wcex.cbClsExtra     = 0;
  197.     wcex.cbWndExtra     = 0;
  198.     wcex.hInstance      = hInstance;
  199.     wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32OGRE));
  200.     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
  201.     wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
  202.     wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_WIN32OGRE);
  203.     wcex.lpszClassName  = szWindowClass;
  204.     wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
  205.     return RegisterClassEx(&wcex);
  206. }
  207.  
  208. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  209. {
  210.    
  211.    hInst = hInstance; // Store instance handle in our global variable
  212.    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
  213.       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
  214.    if (!hWnd)
  215.    {
  216.       return FALSE;
  217.    }
  218.    ShowWindow(hWnd, nCmdShow);
  219.    UpdateWindow(hWnd);
  220.    SetTimer(hWnd,1,1,0);
  221.    return TRUE;
  222. }
  223.  
  224. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  225. {
  226.     int wmId, wmEvent;
  227.     PAINTSTRUCT ps;
  228.     HDC hdc;
  229.     switch (message)
  230.     {
  231.     case WM_COMMAND:
  232.         wmId    = LOWORD(wParam);
  233.         wmEvent = HIWORD(wParam);
  234.         // Parse the menu selections:
  235.         switch (wmId)
  236.         {
  237.         case IDM_ABOUT:
  238.             DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
  239.             break;
  240.         case IDM_EXIT:
  241.             DestroyWindow(hWnd);
  242.             break;
  243.         default:
  244.             return DefWindowProc(hWnd, message, wParam, lParam);
  245.         }
  246.         break;
  247.     case WM_TIMER:  //这里的处理,如果在MFC中,即是响应OnTimer
  248.         {
  249.             static int once=1;
  250.             if(once==1)
  251.             {
  252.                 once=2;
  253.                 CreateScene();    //这里即全部的初始化操作, 放在这里是为了不影响窗口初始化,能够先弹出来
  254.                 
  255.             }
  256.             if(once==2)
  257.                 mRoot->renderOneFrame();   //每帧渲染, 当然前提是先初始化好OGRE
  258.         }
  259.         break;
  260.     case WM_PAINT:
  261.         hdc = BeginPaint(hWnd, &ps);
  262.         // TODO: Add any drawing code here...
  263.         EndPaint(hWnd, &ps);
  264.         break;
  265.     case WM_DESTROY:
  266.         PostQuitMessage(0);
  267.         break;
  268.     default:
  269.         return DefWindowProc(hWnd, message, wParam, lParam);
  270.     }
  271.     return 0;
  272. }
  273. // Message handler for about box.
  274. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  275. {
  276.     UNREFERENCED_PARAMETER(lParam);
  277.     switch (message)
  278.     {
  279.     case WM_INITDIALOG:
  280.         return (INT_PTR)TRUE;
  281.     case WM_COMMAND:
  282.         if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
  283.         {
  284.             EndDialog(hDlg, LOWORD(wParam));
  285.             return (INT_PTR)TRUE;
  286.         }
  287.         break;
  288.     }
  289.     return (INT_PTR)FALSE;
  290. }



最后添加我改写的文件: MyExampleFrameListener.h

当然, 你直接用Ogre的 例子中的ExampleFrameListener.h 也行, 近我这个修改就行了.

  1. #ifndef __MyExampleFrameListener_H__
  2. #define __MyExampleFrameListener_H__
  3. #include "Ogre.h"
  4. #include "OgreStringConverter.h"
  5. #include "OgreException.h"
  6. //Use this define to signify OIS will be used as a DLL
  7. //(so that dll import/export macros are in effect)
  8. #define OIS_DYNAMIC_LIB
  9. #include <OIS/OIS.h>  //使用OIS
  10.  

  11.  
  12. using namespace Ogre;
  13. using namespace std;
  14. using Ogre::uint;
  15. class MyExampleFrameListener: public FrameListener, public WindowEventListener
  16. {
  17.  
  18. protected:
  19.     void updateStats(void)
  20.     {
  21.         
  22.         static String currFps = "Current FPS: ";
  23.         static String avgFps = "Average FPS: ";
  24.         static String bestFps = "Best FPS: ";
  25.         static String worstFps = "Worst FPS: ";
  26.         static String tris = "Triangle Count: ";
  27.         static String batches = "Batch Count: ";
  28.         // update stats when necessary
  29.         try {
  30.             OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
  31.             OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
  32.             OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
  33.             OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");
  34.  
  35.             const RenderTarget::FrameStats& stats = mWindow->getStatistics();
  36.             guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
  37.             guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS));
  38.             guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS)
  39.                 +" "+StringConverter::toString(stats.bestFrameTime)+" ms");
  40.             guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS)
  41.                 +" "+StringConverter::toString(stats.worstFrameTime)+" ms");
  42.             
  43.             OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
  44.             guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount));
  45.             OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches");
  46.             guiBatches->setCaption(batches + StringConverter::toString(stats.batchCount));
  47.             OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
  48.             guiDbg->setCaption(mDebugText);
  49.             guiDbg->setColour(ColourValue(1,1,1));
  50.         }
  51.         catch(...) { /* ignore */ }
  52.     }
  53. public:
  54.     // Constructor takes a RenderWindow because it uses that to determine input context
  55.     MyExampleFrameListener(RenderWindow* win, Camera* cam, HWND h,bool bufferedKeys = falsebool bufferedMouse = false,
  56.                  bool bufferedJoy = false ) :
  57.         mCamera(cam), m_hwnd(h),mTranslateVector(Vector3::ZERO), mWindow(win), mStatsOn(true), mNumScreenShots(0),
  58.         mMoveScale(0.0f), mRotScale(0.0f), mTimeUntilNextToggle(0), mFiltering(TFO_BILINEAR),
  59.         mAniso(1), mSceneDetailIndex(0), mMoveSpeed(100), mRotateSpeed(36), mDebugOverlay(0),
  60.         mInputManager(0), mMouse(0), mKeyboard(0), mJoy(0)
  61.     {
  62.         using namespace OIS;
  63.         mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
  64.          
  65.  
  66.         LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
  67.         ParamList pl;
  68.         
  69.  
  70.          //下面这段是重点, 使用Win32的窗口
  71.         unsigned long h1 = (unsigned long)m_hwnd;
  72.         pl.insert(std::make_pair(std::string("WINDOW"), StringConverter::toString(h1)));
  73.         pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));
  74.         pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND")));
  75.         pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));
  76.         pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));
  77.         mInputManager = InputManager::createInputSystem( pl );
  78.          
  79.         //Create all devices (We only catch joystick exceptions here, as, most people have Key/Mouse)
  80.         mKeyboard = static_cast<Keyboard*>(mInputManager->createInputObject( OISKeyboard, bufferedKeys ));
  81.         mMouse = static_cast<Mouse*>(mInputManager->createInputObject( OISMouse, bufferedMouse ));
  82.         try {
  83.             mJoy = static_cast<JoyStick*>(mInputManager->createInputObject( OISJoyStick, bufferedJoy ));
  84.         }
  85.         catch(...) {
  86.             mJoy = 0;
  87.         }
  88.         //Set initial mouse clipping size
  89.         windowResized(mWindow);
  90.         showDebugOverlay(true);
  91.         //Register as a Window listener
  92.         WindowEventUtilities::addWindowEventListener(mWindow, this);
  93.     }
  94.     //Adjust mouse clipping area
  95.     virtual void windowResized(RenderWindow* rw)
  96.     {
  97.         unsigned int width, height, depth;
  98.         int left, top;
  99.         rw->getMetrics(width, height, depth, left, top);
  100.         const OIS::MouseState &ms = mMouse->getMouseState();
  101.         ms.width = width;
  102.         ms.height = height;
  103.     }
  104.     //Unattach OIS before window shutdown (very important under Linux)
  105.     virtual void windowClosed(RenderWindow* rw)
  106.     {
  107.         //Only close for window that created OIS (the main window in these demos)
  108.         if( rw == mWindow )
  109.         {
  110.             if( mInputManager )
  111.             {
  112.                 mInputManager->destroyInputObject( mMouse );
  113.                 mInputManager->destroyInputObject( mKeyboard );
  114.                 mInputManager->destroyInputObject( mJoy );
  115.                 OIS::InputManager::destroyInputSystem(mInputManager);
  116.                 mInputManager = 0;
  117.             }
  118.         }
  119.     }
  120.     virtual ~MyExampleFrameListener()
  121.     {
  122.         //Remove ourself as a Window listener
  123.         WindowEventUtilities::removeWindowEventListener(mWindow, this);
  124.         windowClosed(mWindow);
  125.     }
  126.     virtual bool processUnbufferedKeyInput(const FrameEvent& evt)
  127.     {
  128.         using namespace OIS;
  129.         int vel=1;//速度增加1倍
  130.         if(mKeyboard->isKeyDown(KC_A))
  131.             mTranslateVector.x = -mMoveScale*vel;   // Move camera left
  132.         if(mKeyboard->isKeyDown(KC_D))
  133.             mTranslateVector.x = mMoveScale*vel;    // Move camera RIGHT
  134.         if(mKeyboard->isKeyDown(KC_UP) || mKeyboard->isKeyDown(KC_W) )
  135.             mTranslateVector.z = -mMoveScale*vel;   // Move camera forward
  136.         if(mKeyboard->isKeyDown(KC_DOWN) || mKeyboard->isKeyDown(KC_S) )
  137.             mTranslateVector.z = mMoveScale*vel;    // Move camera backward
  138.         if(mKeyboard->isKeyDown(KC_PGUP))
  139.             mTranslateVector.y = mMoveScale;    // Move camera up
  140.         if(mKeyboard->isKeyDown(KC_PGDOWN))
  141.             mTranslateVector.y = -mMoveScale;   // Move camera down
  142.         if(mKeyboard->isKeyDown(KC_RIGHT))
  143.             mCamera->yaw(-mRotScale);
  144.         if(mKeyboard->isKeyDown(KC_LEFT))
  145.             mCamera->yaw(mRotScale);
  146.          
  147.         if( mKeyboard->isKeyDown(KC_ESCAPE) || mKeyboard->isKeyDown(KC_Q) )
  148.             return false;
  149.         if( mKeyboard->isKeyDown(KC_F) && mTimeUntilNextToggle <= 0 )
  150.         {
  151.             mStatsOn = !mStatsOn;
  152.             showDebugOverlay(mStatsOn);
  153.             mTimeUntilNextToggle = 1;
  154.         }
  155.  
  156.         if( mKeyboard->isKeyDown(KC_T) && mTimeUntilNextToggle <= 0 )
  157.         {
  158.             switch(mFiltering)
  159.             {
  160.             case TFO_BILINEAR:
  161.                 mFiltering = TFO_TRILINEAR;
  162.                 mAniso = 1;
  163.                 break;
  164.             case TFO_TRILINEAR:
  165.                 mFiltering = TFO_ANISOTROPIC;
  166.                 mAniso = 8;
  167.                 break;
  168.             case TFO_ANISOTROPIC:
  169.                 mFiltering = TFO_BILINEAR;
  170.                 mAniso = 1;
  171.                 break;
  172.             defaultbreak;
  173.             }
  174.             MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
  175.             MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);
  176.             showDebugOverlay(mStatsOn);
  177.             mTimeUntilNextToggle = 1;
  178.         }
  179.         if(mKeyboard->isKeyDown(KC_SYSRQ) && mTimeUntilNextToggle <= 0)
  180.         {
  181.             std::ostringstream ss;
  182.             ss << "screenshot_" << ++mNumScreenShots << ".png";
  183.             mWindow->writeContentsToFile(ss.str());
  184.             mTimeUntilNextToggle = 0.5;
  185.             mDebugText = "Saved: " + ss.str();
  186.         }
  187.         if(mKeyboard->isKeyDown(KC_R) && mTimeUntilNextToggle <=0)
  188.         {
  189.             mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;
  190.             switch(mSceneDetailIndex) {
  191.                 case 0 : mCamera->setPolygonMode(PM_SOLID); break;
  192.                 case 1 : mCamera->setPolygonMode(PM_WIREFRAME); break;
  193.                 case 2 : mCamera->setPolygonMode(PM_POINTS); break;
  194.             }
  195.             mTimeUntilNextToggle = 0.5;
  196.         }
  197.         static bool displayCameraDetails = false;
  198.         if(mKeyboard->isKeyDown(KC_P) && mTimeUntilNextToggle <= 0)
  199.         {
  200.             displayCameraDetails = !displayCameraDetails;
  201.             mTimeUntilNextToggle = 0.5;
  202.             if (!displayCameraDetails)
  203.                 mDebugText = "";
  204.         }
  205.         // Print camera details
  206.         if(displayCameraDetails)
  207.             mDebugText = "P: " + StringConverter::toString(mCamera->getDerivedPosition()) +
  208.                          " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation());
  209.         // Return true to continue rendering
  210.         return true;
  211.     }
  212.     bool processUnbufferedMouseInput(const FrameEvent& evt)
  213.     {
  214.         using namespace OIS;
  215.         // Rotation factors, may not be used if the second mouse button is pressed
  216.         // 2nd mouse button - slide, otherwise rotate
  217.         const MouseState &ms = mMouse->getMouseState();
  218.         if( ms.buttonDown( MB_Middle ) )
  219.         {
  220.             mTranslateVector.x -= ms.X.rel * 0.13;
  221.             mTranslateVector.y += ms.Y.rel * 0.13;
  222.         }
  223.         if(ms.buttonDown(MB_Left))//此处改为左键按下旋转镜头
  224.         {
  225.             mRotX = Degree(-ms.X.rel * 0.13);
  226.             mRotY = Degree(-ms.Y.rel * 0.13);
  227.         }
  228.         if(ms.Z.rel)
  229.             mTranslateVector.z = -ms.Z.rel;//使用滚轮来ZoomIn/ZoomOut
  230.         return true;
  231.     }
  232.     void moveCamera()
  233.     {
  234.         // Make all the changes to the camera
  235.         // Note that YAW direction is around a fixed axis (freelook style) rather than a natural YAW
  236.         //(e.g. airplane)
  237.         mCamera->yaw(mRotX);
  238.         mCamera->pitch(mRotY);
  239.         mCamera->moveRelative(mTranslateVector);
  240.          
  241.     }
  242.     void showDebugOverlay(bool show)
  243.     {
  244.         if (mDebugOverlay)
  245.         {
  246.             if (show)
  247.                 mDebugOverlay->show();
  248.             else
  249.                 mDebugOverlay->hide();
  250.          
  251.         }
  252.     }
  253.     // Override frameStarted event to process that (don't care about frameEnded)
  254.     bool frameStarted(const FrameEvent& evt)
  255.     {
  256.         using namespace OIS;
  257.         if(mWindow->isClosed()) return false;
  258.         //Need to capture/update each device
  259.         mKeyboard->capture();
  260.         mMouse->capture();
  261.         if( mJoy ) mJoy->capture();
  262.         bool buffJ = (mJoy) ? mJoy->buffered() : true;
  263.         //Check if one of the devices is not buffered
  264.         if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
  265.         {
  266.             // one of the input modes is immediate, so setup what is needed for immediate movement
  267.             if (mTimeUntilNextToggle >= 0)
  268.                 mTimeUntilNextToggle -= evt.timeSinceLastFrame;
  269.             // If this is the first frame, pick a speed
  270.             if (evt.timeSinceLastFrame == 0)
  271.             {
  272.                 mMoveScale = 1;
  273.                 mRotScale = 0.1;
  274.             }
  275.             // Otherwise scale movement units by time passed since last frame
  276.             else
  277.             {
  278.                 // Move about 100 units per second,
  279.                 mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
  280.                 // Take about 10 seconds for full rotation
  281.                 mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
  282.             }
  283.             mRotX = 0;
  284.             mRotY = 0;
  285.             mTranslateVector = Ogre::Vector3::ZERO;
  286.         }
  287.         //Check to see which device is not buffered, and handle it
  288.         if( !mKeyboard->buffered() )
  289.             if( processUnbufferedKeyInput(evt) == false )
  290.                 return false;
  291.         if( !mMouse->buffered() )
  292.             if( processUnbufferedMouseInput(evt) == false )
  293.                 return false;
  294.         if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
  295.             moveCamera();
  296.         return true;
  297.     }
  298.     bool frameEnded(const FrameEvent& evt)
  299.     {
  300.         updateStats();
  301.         return true;
  302.     }
  303. protected:
  304.     Camera* mCamera;
  305.     HWND m_hwnd;
  306.     Vector3 mTranslateVector;
  307.     RenderWindow* mWindow;
  308.     bool mStatsOn;
  309.     std::string mDebugText;
  310.     unsigned int mNumScreenShots;
  311.     float mMoveScale;
  312.     Degree mRotScale;
  313.     // just to stop toggles flipping too fast
  314.     Real mTimeUntilNextToggle ;
  315.     Radian mRotX, mRotY;
  316.     TextureFilterOptions mFiltering;
  317.     int mAniso;
  318.     int mSceneDetailIndex ;
  319.     Real mMoveSpeed;
  320.     Degree mRotateSpeed;
  321.     Overlay* mDebugOverlay;
  322.     //OIS Input devices
  323.     OIS::InputManager* mInputManager;
  324.     OIS::Mouse*    mMouse;
  325.     OIS::Keyboard* mKeyboard;
  326.     OIS::JoyStick* mJoy;
  327. };
  328. #endif

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值