经过前两两篇博文的解说。我们已经完毕了渲染工作,但仅仅是渲染而没有交互性,本篇博文我们就来加上事件的处理方法。
首先我们须要为项目加入一个帧监听类:CMyFrameListener,为了直观,在这直接贴上代码
头文件
#pragma once #include "ogre.h" #include "OgreConfigFile.h" #include "OgreFrameListener.h" #include "OgreStringConverter.h" #include "OIS.h" #include "MyOgreApp.h" #include <OISEvents.h> #include <OISInputManager.h> #include <OISKeyboard.h> #include <OISMouse.h> #include <SdkTrays.h> #include <SdkCameraMan.h> using namespace Ogre; class CMyFrameListener: public FrameListener, public OIS::MouseListener,public Ogre::WindowEventListener, public OIS::KeyListener { public: CMyFrameListener(RenderWindow* win, Camera* cam, SceneManager *sceneMgr, Light* light); ~CMyFrameListener(void); bool frameRenderingQueued(const Ogre::FrameEvent& evt); bool mouseMoved(const OIS::MouseEvent &e); bool mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id); bool mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id); bool keyPressed(const OIS::KeyEvent &e); bool keyReleased(const OIS::KeyEvent &e); protected: Ogre::SceneManager *mSceneMgr;//场景管理器 Ogre::SceneNode* mCamNode;//摄像机节点 Ogre::Camera* mCamera;//摄像机 Ogre::RenderWindow* mWindow;//渲染窗体 Ogre::Light* light;//灯光 OIS::Keyboard* mKeyboard;//键盘 OIS::Mouse* mMouse; //鼠标 OIS::InputManager* mInputManager;//输入管理器 // OgreBites::SdkTrayManager* mTrayMgr; OgreBites::SdkCameraMan* mCameraMan; // basic camera controller bool mRBtdown; };源文件
#include "StdAfx.h" #include "MyFrameListener.h" CMyFrameListener::CMyFrameListener(RenderWindow* win, Camera* cam, SceneManager *sceneMgr, Light *l): mMouse(0), mKeyboard(0), mInputManager(0), mWindow(win), mCamera(cam), light(l) { mRBtdown = false; mCamNode=cam->getParentSceneNode(); mSceneMgr = sceneMgr; size_t windowHnd = 0; std::ostringstream windowHndStr; OIS::ParamList pl; mCameraMan = new OgreBites::SdkCameraMan(mCamera); windowHnd = (size_t )AfxGetMainWnd()->GetSafeHwnd(); // 这里这个窗体句柄就是传入的MFC主窗体 windowHndStr << windowHnd; // OIS的窗体必需要顶层窗体,所以仅仅有传MFC的主窗体给他,传view就不行 pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); // 设置鼠标显示和非游戏独占,这样鼠标能够显示在屏幕上并能够移动到窗体外 pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_FOREGROUND" ))); pl.insert(std::make_pair(std::string("w32_mouse"), std::string("DISCL_NONEXCLUSIVE"))); // 键盘非游戏独占 pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_FOREGROUND"))); pl.insert(std::make_pair(std::string("w32_keyboard"), std::string("DISCL_NONEXCLUSIVE"))); mInputManager = OIS::InputManager::createInputSystem(pl); mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, true )); mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, true )); mMouse->setEventCallback(this); mKeyboard->setEventCallback(this); } CMyFrameListener::~CMyFrameListener(void) { mInputManager->destroyInputObject(mMouse); mInputManager->destroyInputObject(mKeyboard); OIS::InputManager::destroyInputSystem(mInputManager); mInputManager = 0; } bool CMyFrameListener::frameRenderingQueued(const Ogre::FrameEvent& e){ mMouse->capture(); mKeyboard->capture(); mCameraMan->frameRenderingQueued(e); return true; } bool CMyFrameListener::mouseMoved(const OIS::MouseEvent &e) { if (mRBtdown) { mCameraMan->injectMouseMove(e); } return true; } bool CMyFrameListener::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id) { // mCameraMan->injectMouseDown(e, id); if (id == OIS::MB_Right) { mRBtdown = true; } return true; } bool CMyFrameListener::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id) { // mCameraMan->injectMouseUp(e, id); if (id == OIS::MB_Right) { mRBtdown = false; } return true; } //键盘响应 bool CMyFrameListener::keyPressed(const OIS::KeyEvent &e) { mCameraMan->injectKeyDown(e); return true; } bool CMyFrameListener::keyReleased(const OIS::KeyEvent &e) { mCameraMan->injectKeyUp(e); return true; }
此类实现了对于鼠标和键盘事件的监听与响应。按住鼠标右键拖动可旋转摄像机角度,WASD和方向键可移动摄像机位置。里面的代码都非常easy,我就不再赘述了。
以下改动CMyOgreApp类其可以响应鼠标和键盘的事件。
1、首先在MyOgreApp.h中加入监听类的引用
#include "MyFrameListener.h"
class CMyFrameListener* mListener;
3、声明一个函数
void createFrameListener(void);
4、在MyOgreApp.cpp文件里定义createFrameListener()
void CMyOgreApp::createFrameListener(void) { mListener= new CMyFrameListener(mWindow, mCamera, mSceneMgr, light); mRoot->addFrameListener(mListener); }5、在go() 函数中调用createFrameListener()
bool CMyOgreApp::go(CRect rt, HWND hWnd) { createRoot(); setupResources(); setupRenderSystem(); createRenderWindow(hWnd, rt.Width(), rt.Height()); chooseSceneManager(); createCamera(); createViewport(); initializeResourceGroups(); createScene(); createFrameListener();//创建侦听 return true; }生成并执行。使用鼠标和键盘就能够控制摄像机运动了。
至此,整个工作就完毕了,希望这几篇文章能帮到还在受这个问题困扰的朋友。
PS:整个项目都在我上传的资源中,配置好环境变量,再依照里面的说明简单配置下就能编译执行
Demo地址:http://download.csdn.net/detail/guoyk1990/7360731