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

首先我们须要为项目加入一个帧监听类: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. 更换Winform 皮肤(下)----完全GDI+绘制

    skin皮肤和DLL程序及文件:下载 链接:http://www.cnblogs.com/DebugLZQ/archive/2013/04/15/3021659.html

  2. 判断程序是否在VMWare内运行

    现在有许多用户都喜欢用虚拟机来测试他们的软件,以避免对真实机器环境造成损害.但是在虚拟机中,有些功能是受限,甚至不可能完成的,因此,需要在程序中判断虚拟机的环境,如果程序在虚拟机内运行,则就要把虚拟机 ...

  3. 使用SHA1、SHA2双证书进行微软数字签名

    微软是第一个宣布了SHA-1弃用计划,在2016年之后Windows和IE将不再信任SHA-1证书.正好我们公司的数字签名也到期了,索性就重新申请了sha256和sha1的新数字证书,用来给产品签名. ...

  4. JDBC连接SQL server与ADO.NET连接Sql Server对比

    JDBC连接SQL server与ADO.NET连接Sql Server对比 1.JDBC连接SQL server 1)java方面目前有很多驱动能够驱动连接SQL servernet.   主流的有 ...

  5. IOS系统对fixed定位支持不好的解决方法

    问题: IOS 中所有浏览器,当页面上的输入框获得焦点时,呼出键盘. 页面底部的导航栏(position:fixed)会被键盘顶到页面的中间. 而当输入框失去焦点时,导航栏停留在页面中间,造成页面错乱 ...

  6. WCF技术剖析之十九:深度剖析消息编码(Encoding)实现(下篇)

    原文:WCF技术剖析之十九:深度剖析消息编码(Encoding)实现(下篇) [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制的节目视频(苏州话 ...

  7. 【REDO】删除REDO LOG重做日志组后需要手工删除对应的日志文件(转)

    为保证重新创建的日志组成员可以成功创建,我们在删除日志组后需要手工删除对应的日志文件. 1.查看数据库当前REDO LOG日志相关信息1)查看日志组信息sys@ora10g> select * ...

  8. 基于visual Studio2013解决面试题之0901奇偶站队

     题目

  9. poj 3466 A Simple Problem with Integers

    题目链接:http://poj.org/problem?id=3468 http://poj.org/problem?id=3468 http://poj.org/problem?id=3468 思路 ...

  10. IT段子,娱乐一下

    1.我是个程序员,一天我坐在路边一边喝水一边苦苦检查bug.这时一个乞丐在我边上坐下了,开始要饭,我觉得可怜,就给了他1块钱,然后接着调试程序.他可能生意不好,就无聊的看看我在干什么,然后过了一会,他 ...