Ogre嵌入MFC傻瓜全然教程(三)
经过前两两篇博文的解说。我们已经完毕了渲染工作,但仅仅是渲染而没有交互性,本篇博文我们就来加上事件的处理方法。
首先我们须要为项目加入一个帧监听类: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傻瓜全然教程(三)的更多相关文章
- VS2010/MFC编程入门教程之目录和总结
鸡啄米的这套VS2010/MFC编程入门教程到此就全部完成了,虽然有些内容还未涉及到,但帮助大家进行VS2010/MFC的入门学习业已足够.以此教程的知识为基础,学习VS2010/MFC较为深入的内容 ...
- webpack之傻瓜式教程
接触webpack也有挺长一段时间了,公司的项目也是一直用着webpack在打包处理,但前几天在教新人的情况下,遇到了一个问题,那就是:尽管网上的webpack教程满天飞,但是却很难找到一个能让新人快 ...
- CRL快速开发框架系列教程三(更新数据)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- 手把手教从零开始在GitHub上使用Hexo搭建博客教程(三)-使用Travis自动部署Hexo(1)
前言 前面两篇文章介绍了在github上使用hexo搭建博客的基本环境和hexo相关参数设置等. 基于目前,博客基本上是可以完美运行了. 但是,有一点是不太好,就是源码同步问题,如果在不同的电脑上写文 ...
- 无废话ExtJs 入门教程三[窗体:Window组件]
无废话ExtJs 入门教程三[窗体:Window组件] extjs技术交流,欢迎加群(201926085) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3 ...
- CocoStudio教程三:认识并利用CocoStudio的果实 运行2.2.1版本
原文:CocoStudio教程三:认识并利用CocoStudio的果实 原文用的老版,用2.21搞起来好像有些问题,然后自己摸索了下,有的都是乱找的方法,只求能运行... 1,原文的CCJsonRea ...
- Android Studio系列教程三--快捷键
Android Studio系列教程三--快捷键 2014 年 12 月 09 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://stormzhang.com/ ...
- Laravel教程 三:视图变量传递和Blade
Laravel教程 三:视图变量传递和Blade 此文章为原创文章,未经同意,禁止转载. Blade 上一篇我们简单地说了Router,Views和Controllers的工作流程,这一次我就按照上一 ...
- NGUI系列教程三
接下来我们再来看Progress Bar和Slider,对比参数我们可以发现,Progress Bar和slider的明显区别在于slider多一个Thumb选项,这里的Thumb就是我们拖动的时候点 ...
随机推荐
- 简单字符串处理 hdu2532 Engine
本来可以把这篇文章放入上一篇文章里,不过做这个题花了一点时间,也有一点收获,同时觉得网上的这个题目可供参考的文章有些少,那么就单独成篇吧. 首先分析下题目思路: 这个题目是个模拟题,步骤也很清晰. 首 ...
- java--join方法
package MyTest; class TestDemo implements Runnable { public void run() { int i = 0; for (int j = 0; ...
- docker学习笔记3:镜像操作(查找和下载)
一.查看本地镜像 只有下载后,镜像才会保存在本地(docker环境所在的主机),通过如下命令可以查看本地已经存在的镜像. 命令:dokcer images 上面命令列出本地所有已经存在的镜像,显示的信 ...
- 基于visual Studio2013解决C语言竞赛题之1007找数
题目 解决代码及点评 /************************************************************************/ ...
- ImageMagick 压缩图片 方法
Images as a percentage of page weight for the Alexa top 10 global web sites 图片在站点所占的比重越来越重.更好的优化图片能 ...
- 道格拉斯—普克(Douglas一Peukcer)节点抽稀算法
Douglas一Peukcer算法由D.Douglas和T.Peueker于1973年提出,简称D一P算法,是眼下公认的线状要素化简经典算法.现有的线化简算法中,有相当一部分都是在该算法基础上进行改进 ...
- PHP函数详细剖析之rtrim函数 By ACReaper
string rtrim ( string $str [, string $charlist ] ) 这个函数很好理解.r表示右边.trim表示修剪.即右边修剪.默认修剪字符str右边的字符.默认修剪 ...
- 11gOCP 1z0-052 :2013-09-11 MGR_ROLE role........................................................A66
转载请注明出处:http://blog.csdn.net/guoyjoe/article/details/11584537 正确答案A 实验测试 1.创建用户:SKD gyj@OCM> crea ...
- [置顶] 【玩转cocos2d-x之三十】点九图和输入框的使用
原创作品,转载请标明:http://blog.csdn.net/jackystudio/article/details/17297721 登录界面一个帐号/密码输入框或者主角命名框是少不了的.这节就来 ...
- Ultra Office Control 2.0
http://www.ultrashareware.com/Ultra-Office-Control.htm