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和方向键可移动摄像机位置。里面的代码都很简单,我就不再赘述了。

下面修改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傻瓜完全教程(三)

时间: 2024-08-07 18:36:53

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

cv::namedWindow, GLFWwindow以及其他程序嵌入到MFC中的教程

cv::namedWindow, GLFWwindow以及其他程序嵌入到MFC中的教程 MFC虽然很老, 不美观, 不跨平台, 但是在Windows系统中, 利用MFC做功能验证的界面, 还是很快很方便的. 因为它老, 所以有很多解决方案可以利用, 因为它是MS提供的界面库, 所以在Windows上很容易实现, 并且和Windows系统结合很紧密. 比如说, 窗口消息等, 在MFC中是很方便实现的. 基于上面的种种原因, 利用MFC作为功能验证的一个"壳" 是很好的工具. 当然, 难免

[MFC] MFC音乐播放器 傻瓜级教程 网络 搜索歌曲 下载

>目录< >----------------------< 1.建立工程  1.建立一个MFC工程,命名为Tao_Music 2.选择为基本对话框 3.包含Windows Sockts 4.使用静态链接库 [方便一会直接生成的exe文件单独可以发布] 2. 搭建界面  1. 拖入控件: 2. 控件拖入并摆好 3. 控件属性设置: 3. 写代码实现功能  1.变量绑定: 2.加入图片资源 3.新建mp3类: 4.修改Tao_MusicDlg.h 5.修改Tao_Music.cpp 6

手把手教学MFC吃豆子教程

手把手教学MFC吃豆子教程 本教程适用于零基础学员制作C++课程设计 编程工具:VC++6.0. 本次教学主要知识点: 1.控件消息响应. 2.CDC类函数的使用. 下面开始教学: 吃豆子的基本思想: 1.定义脸和食物类. 2.不断将脸的上一个坐标重绘为白色,将新的脸绘制出来,从而在宏观上实现脸的移动. 3.运用OnTimer()函数制作时钟更新画面,运用OnKeyDown()接收键盘消息. 首先创建工程:我们选择的是MFC AppW的单文档工程. xxxxxxxxxxxxxxxxxxxxxxx

Q?t ?Creator? 傻瓜安装教程

首先需要的软件: 1.MinGW-gcc440_1.zip 2.qt-win-opensource-4.8.5-mingw.exe 3.qt-creator-win-opensource-2.8.1.exe  步骤: 1. 解压缩MinGW-gcc440_1到目录D:\Qt\MinGW-gcc440_1 2.安装qt-win-opensource-4.8.5-mingw.exe,在find installed mingw选择MinGW的目录为D:\Qt\MinGW-gcc440_1, 安装到目录

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

      目前该教程可以到鸡啄米编程课堂去学习,阅读体验更好,更适合在线学习. 鸡啄米的这套VS2010/MFC编程入门教程到此就全部完成了,虽然有些内容还未涉及到,但帮助大家进行VS2010/MFC的入门学习业已足够.以此教程的知识为基础,学习VS2010/MFC较为深入的内容已非难事.作为本教程的最后一课,鸡啄米将对前面所讲内容进行目录归纳,并对这八个月加班加点的努力进行总结. 一.VS2010/MFC编程入门教程之目录 第一部分:VS2010/MFC开发环境 VS2010/MFC编程入门

微信开放平台 公众号第三方平台开发 教程三 一键登录授权给第三方平台

原文:微信开放平台 公众号第三方平台开发 教程三 一键登录授权给第三方平台 教程导航: 微信开放平台 公众号第三方平台开发 教程一 平台介绍 微信开放平台 公众号第三方平台开发 教程二 创建公众号第三方平台 微信开放平台 公众号第三方平台开发 教程三 一键登录授权给第三方平台 微信开放平台 公众号第三方平台开发 教程四 代公众号调用接口的SDK和demo 公众号第三方平台的开放,是为了让公众号运营者,在面向垂直行业需求时,可以一键登录授权给第三方的公众号运营平台,通过第三方开发者提供的公众号第三

struts2 官方系列教程三:使用struts2 标签 tag

避免被爬,先贴上本帖地址:struts2 官方系列教程一:使用struts2 标签 tag http://www.cnblogs.com/linghaoxinpian/p/6901316.html 本教材假定你已完成了HelloWorld项目,你可以在 struts2 官方系列教程三:使用struts2 标签 tag 下载本章节的代码 在上一节教程中,我们在index.jsp中使用 url tag 创建了一个超链接hello.action 这节我们将探索struts2中其它tags Web应用程

Junit 4 Tutorials(Junit 4 教程) 三、Junit4 断言方法

Junit 4 断言方法允许检查测试方法的期望结果值和真实返回值.Junit的org.junit.Assert类提供了各种断言方法来写junit测试.这些方法被用来检查方法的真实结果值和期望值.下列一些有用的断言方法列表: Junit 4 Assert Methods Method Description assertNull(java.lang.Object object) 检查对象是否为空 assertNotNull(java.lang.Object object) 检查对象是否不为空 as

Swift中文教程(三)--流程控制

原文:Swift中文教程(三)--流程控制 Swift用if和switch编写条件控制语句,用for-in,for,while和do-while编写循环.条件控制语句和循环语句中,小括号是可选的,但花括号包住这个循环体是必须的: 1 let individualScores = [75, 43, 103, 87, 12] 2 var teamScore = 0 3 for score in individualScores { 4 if score > 50 { 5 teamScore += 3