您的位置:首页 > 其它

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

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

首先我们需要为项目添加一个帧监听类: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和方向键可移动摄像机位置。里面的代码都很简单,我就不再赘述了。

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

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

#include "MyFrameListener.h"


2、声明一个CMyFrameListener类的变量
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: