• 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





  • 相关阅读:
    APP之百度地图SDK的AK值获取(android)
    横向滚动菜单-选中标题居中显示
    函数按引用传参问题
    js验证提交
    Java servlet ajax
    数据库3种读
    mybatis插件
    mybatis 缓存
    从前端对象中获取的文本变为字符串,并替换其中一些指定的字符
    多个窗口开启后,切换到指定title的窗口
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5131398.html
Copyright © 2020-2023  润新知