分享

Ogre嵌入MFC傻瓜完全教程(三)

 蓝色飘零 2015-05-05

经过前两两篇博文的讲解,我们已经完成了渲染工作,但只是渲染而没有交互性,本篇博文我们就来加上事件的处理方法。

首先我们需要为项目添加一个帧监听类:CMyFrameListener,为了直观,在这直接贴上代码

头文件

  1. #pragma once  
  2. #include "ogre.h"  
  3. #include "OgreConfigFile.h"  
  4. #include "OgreFrameListener.h"  
  5. #include "OgreStringConverter.h"  
  6. #include "OIS.h"  
  7.   
  8. #include "MyOgreApp.h"  
  9. #include <OISEvents.h>  
  10. #include <OISInputManager.h>  
  11. #include <OISKeyboard.h>  
  12. #include <OISMouse.h>  
  13.   
  14. #include <SdkTrays.h>  
  15. #include <SdkCameraMan.h>  
  16. using namespace Ogre;  
  17. class CMyFrameListener: public FrameListener, public OIS::MouseListener,public Ogre::WindowEventListener, public OIS::KeyListener  
  18. {  
  19. public:  
  20.     CMyFrameListener(RenderWindow* win, Camera* cam, SceneManager *sceneMgr, Light* light);  
  21.     ~CMyFrameListener(void);  
  22.     bool frameRenderingQueued(const Ogre::FrameEvent& evt);  
  23.     bool mouseMoved(const OIS::MouseEvent &e);  
  24.     bool mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id);   
  25.     bool mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id);  
  26.     bool keyPressed(const OIS::KeyEvent &e);  
  27.     bool keyReleased(const OIS::KeyEvent &e);  
  28.   
  29. protected:  
  30.   
  31.     Ogre::SceneManager *mSceneMgr;//场景管理器  
  32.     Ogre::SceneNode* mCamNode;//摄像机节点  
  33.     Ogre::Camera* mCamera;//摄像机  
  34.     Ogre::RenderWindow* mWindow;//渲染窗口  
  35.     Ogre::Light* light;//灯光  
  36.   
  37.     OIS::Keyboard* mKeyboard;//键盘           
  38.     OIS::Mouse* mMouse;      //鼠标      
  39.     OIS::InputManager* mInputManager;//输入管理器   
  40.   
  41. //  OgreBites::SdkTrayManager* mTrayMgr;  
  42.     OgreBites::SdkCameraMan* mCameraMan;     // basic camera controller  
  43.     bool mRBtdown;  
  44. };  
源文件

  1. #include "StdAfx.h"  
  2. #include "MyFrameListener.h"  
  3.   
  4. CMyFrameListener::CMyFrameListener(RenderWindow* win, Camera* cam, SceneManager *sceneMgr, Light *l): mMouse(0),   
  5.     mKeyboard(0), mInputManager(0), mWindow(win), mCamera(cam), light(l)  
  6. {  
  7.     mRBtdown = false;  
  8.     mCamNode=cam->getParentSceneNode();  
  9.     mSceneMgr = sceneMgr;  
  10.   
  11.   
  12.     size_t windowHnd = 0;  
  13.     std::ostringstream windowHndStr;  
  14.     OIS::ParamList pl;  
  15.   
  16.   
  17.     mCameraMan = new OgreBites::SdkCameraMan(mCamera);    
  18.   
  19.   
  20.     windowHnd = (size_t )AfxGetMainWnd()->GetSafeHwnd(); // 这里这个窗口句柄就是传入的MFC主窗口  
  21.     windowHndStr << windowHnd;  
  22.     // OIS的窗口必须要顶层窗口,所以只有传MFC的主窗口给他,传view就不行  
  23.     pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));  
  24.   
  25.   
  26.     // 设置鼠标显示和非游戏独占,这样鼠标可以显示在屏幕上并可以移动到窗口外  
  27.     pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" )));  
  28.     pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE")));  
  29.     // 键盘非游戏独占  
  30.     pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND")));  
  31.     pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE")));  
  32.     mInputManager = OIS::InputManager::createInputSystem(pl);  
  33.   
  34.   
  35.     mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, true ));  
  36.     mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, true ));  
  37.   
  38.   
  39.     mMouse->setEventCallback(this);  
  40.     mKeyboard->setEventCallback(this);  
  41. }  
  42.   
  43.   
  44.   
  45.   
  46. CMyFrameListener::~CMyFrameListener(void)  
  47. {  
  48.     mInputManager->destroyInputObject(mMouse);  
  49.     mInputManager->destroyInputObject(mKeyboard);  
  50.     OIS::InputManager::destroyInputSystem(mInputManager);  
  51.     mInputManager = 0;  
  52. }  
  53.   
  54.   
  55.   
  56.   
  57. bool CMyFrameListener::frameRenderingQueued(const Ogre::FrameEvent& e){  
  58.   
  59.   
  60.     mMouse->capture();  
  61.     mKeyboard->capture();  
  62.     mCameraMan->frameRenderingQueued(e);   
  63.     return true;  
  64. }  
  65.   
  66.   
  67. bool CMyFrameListener::mouseMoved(const OIS::MouseEvent &e)  
  68. {  
  69.     if (mRBtdown)  
  70.     {  
  71.         mCameraMan->injectMouseMove(e);  
  72.     }  
  73.       
  74.     return true;  
  75. }  
  76.   
  77.   
  78. bool CMyFrameListener::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id)  
  79. {  
  80. //  mCameraMan->injectMouseDown(e, id);  
  81.     if (id == OIS::MB_Right)  
  82.     {  
  83.         mRBtdown = true;  
  84.     }  
  85.       
  86.     return true;  
  87. }  
  88.   
  89.   
  90. bool CMyFrameListener::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id)  
  91. {  
  92.   
  93.   
  94. //  mCameraMan->injectMouseUp(e, id);  
  95.     if (id == OIS::MB_Right)  
  96.     {  
  97.         mRBtdown = false;  
  98.     }  
  99.     return true;  
  100. }  
  101. //键盘响应  
  102. bool CMyFrameListener::keyPressed(const OIS::KeyEvent &e)  
  103. {  
  104.       
  105.     mCameraMan->injectKeyDown(e);  
  106.   
  107.   
  108.     return true;  
  109. }  
  110.   
  111.   
  112. bool CMyFrameListener::keyReleased(const OIS::KeyEvent &e)  
  113. {  
  114.      mCameraMan->injectKeyUp(e);  
  115.     return true;  
  116. }  

此类实现了对于鼠标和键盘事件的监听与响应。按住鼠标右键拖动可旋转摄像机角度,WASD和方向键可移动摄像机位置。里面的代码都很简单,我就不再赘述了。

下面修改CMyOgreApp类其能够响应鼠标和键盘的事件。

1、首先在MyOgreApp.h中添加监听类的引用

  1. #include "MyFrameListener.h"  


2、声明一个CMyFrameListener类的变量

  1. class CMyFrameListener* mListener;  

3、声明一个函数 

  1. void createFrameListener(void);  

4、在MyOgreApp.cpp文件中定义createFrameListener()

  1. void CMyOgreApp::createFrameListener(void)  
  2. {  
  3.     mListener= new CMyFrameListener(mWindow, mCamera, mSceneMgr, light);  
  4.     mRoot->addFrameListener(mListener);  
  5. }  
5、在go() 函数中调用createFrameListener()

  1. bool CMyOgreApp::go(CRect rt, HWND hWnd)  
  2. {  
  3.     createRoot();  
  4.     setupResources();  
  5.     setupRenderSystem();  
  6.     createRenderWindow(hWnd, rt.Width(), rt.Height());  
  7.     chooseSceneManager();  
  8.     createCamera();  
  9.     createViewport();  
  10.     initializeResourceGroups();  
  11.     createScene();  
  12.     createFrameListener();//创建侦听  
  13.     return true;  
  14. }  
生成并运行,使用鼠标和键盘就可以控制摄像机运动了。

至此,整个工作就完成了,希望这几篇文章能帮到还在受这个问题困扰的朋友。
 PS:整个项目都在我上传的资源中,配置好环境变量,再按照里面的说明简单配置下就能编译运行

Demo地址:http://download.csdn.net/detail/guoyk1990/7360731

原文:http://blog.csdn.net/guoyk1990/article/details/26060353

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约