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

首先我们须要为项目加入一个帧监听类: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"

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

Ogre嵌入MFC傻瓜全然教程(三)的更多相关文章

  1. VS2010/MFC编程入门教程之目录和总结

    鸡啄米的这套VS2010/MFC编程入门教程到此就全部完成了,虽然有些内容还未涉及到,但帮助大家进行VS2010/MFC的入门学习业已足够.以此教程的知识为基础,学习VS2010/MFC较为深入的内容 ...

  2. webpack之傻瓜式教程

    接触webpack也有挺长一段时间了,公司的项目也是一直用着webpack在打包处理,但前几天在教新人的情况下,遇到了一个问题,那就是:尽管网上的webpack教程满天飞,但是却很难找到一个能让新人快 ...

  3. CRL快速开发框架系列教程三(更新数据)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  4. 手把手教从零开始在GitHub上使用Hexo搭建博客教程(三)-使用Travis自动部署Hexo(1)

    前言 前面两篇文章介绍了在github上使用hexo搭建博客的基本环境和hexo相关参数设置等. 基于目前,博客基本上是可以完美运行了. 但是,有一点是不太好,就是源码同步问题,如果在不同的电脑上写文 ...

  5. 无废话ExtJs 入门教程三[窗体:Window组件]

    无废话ExtJs 入门教程三[窗体:Window组件] extjs技术交流,欢迎加群(201926085) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3 ...

  6. CocoStudio教程三:认识并利用CocoStudio的果实 运行2.2.1版本

    原文:CocoStudio教程三:认识并利用CocoStudio的果实 原文用的老版,用2.21搞起来好像有些问题,然后自己摸索了下,有的都是乱找的方法,只求能运行... 1,原文的CCJsonRea ...

  7. Android Studio系列教程三--快捷键

    Android Studio系列教程三--快捷键 2014 年 12 月 09 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://stormzhang.com/ ...

  8. Laravel教程 三:视图变量传递和Blade

    Laravel教程 三:视图变量传递和Blade 此文章为原创文章,未经同意,禁止转载. Blade 上一篇我们简单地说了Router,Views和Controllers的工作流程,这一次我就按照上一 ...

  9. NGUI系列教程三

    接下来我们再来看Progress Bar和Slider,对比参数我们可以发现,Progress Bar和slider的明显区别在于slider多一个Thumb选项,这里的Thumb就是我们拖动的时候点 ...

随机推荐

  1. 简单字符串处理 hdu2532 Engine

    本来可以把这篇文章放入上一篇文章里,不过做这个题花了一点时间,也有一点收获,同时觉得网上的这个题目可供参考的文章有些少,那么就单独成篇吧. 首先分析下题目思路: 这个题目是个模拟题,步骤也很清晰. 首 ...

  2. java--join方法

    package MyTest; class TestDemo implements Runnable { public void run() { int i = 0; for (int j = 0; ...

  3. docker学习笔记3:镜像操作(查找和下载)

    一.查看本地镜像 只有下载后,镜像才会保存在本地(docker环境所在的主机),通过如下命令可以查看本地已经存在的镜像. 命令:dokcer images 上面命令列出本地所有已经存在的镜像,显示的信 ...

  4. 基于visual Studio2013解决C语言竞赛题之1007找数

         题目 解决代码及点评 /************************************************************************/ ...

  5. ImageMagick 压缩图片 方法

    Images as a percentage of page weight for the Alexa top 10 global web sites  图片在站点所占的比重越来越重.更好的优化图片能 ...

  6. 道格拉斯—普克(Douglas一Peukcer)节点抽稀算法

    Douglas一Peukcer算法由D.Douglas和T.Peueker于1973年提出,简称D一P算法,是眼下公认的线状要素化简经典算法.现有的线化简算法中,有相当一部分都是在该算法基础上进行改进 ...

  7. PHP函数详细剖析之rtrim函数 By ACReaper

    string rtrim ( string $str [, string $charlist ] ) 这个函数很好理解.r表示右边.trim表示修剪.即右边修剪.默认修剪字符str右边的字符.默认修剪 ...

  8. 11gOCP 1z0-052 :2013-09-11 MGR_ROLE role........................................................A66

    转载请注明出处:http://blog.csdn.net/guoyjoe/article/details/11584537 正确答案A 实验测试 1.创建用户:SKD gyj@OCM> crea ...

  9. [置顶] 【玩转cocos2d-x之三十】点九图和输入框的使用

    原创作品,转载请标明:http://blog.csdn.net/jackystudio/article/details/17297721 登录界面一个帐号/密码输入框或者主角命名框是少不了的.这节就来 ...

  10. Ultra Office Control 2.0

    http://www.ultrashareware.com/Ultra-Office-Control.htm