您现在的位置是:首页 >技术交流 >Ogre与OIS实现键盘响应网站首页技术交流

Ogre与OIS实现键盘响应

轩雨轩寻hy 2024-10-14 00:01:03
简介Ogre与OIS实现键盘响应

Ogre与OIS实现键盘响应

环境:

  • ubuntu 18.04
  • Ogre 1.12.13
  • OIS 1.3.0

ubuntu下安装OIS

sudo apt-get install libois-dev -y

帧监听是基于一个观察者的模式。
在OGRE中其工作流程是:
在帧被渲染前,Ogre::Root 遍历所有被添加的FrameListener并调用其frameStarted()方法。直到frameStarted返回false时,帧监听终止,程序结束。

CMakeLists.txt

find_package(OGRE REQUIRED COMPONENTS Bites RTShaderSystem CONFIG)
#...
target_link_libraries(test OgreBites OgreRTShaderSstem -lOIS)

using OIS

InputManager函数说明

Public Member Functions
virtual Object* createInputObject(Type iType, bool bufferMode)=0;产生一个输入设备!
virtual void destroyInputObject (Object *obj)=0;销毁一个输入设备
Static Public Member Functions
InputManager* createInputSystem(std::size_t winHandle);产生输入控制管理系统
InputManager* createInputSystem(ParamList ¶mList);创建控制管理系统
void destroyInputSystem(InputManager *manager);销毁控制管理系统

鼠标键盘函数说明

鼠标的2个重要类是Mouse,MouseListener,相应的键盘的2个重要类是Keyboard,KeyListener 。

Mouse的重要函数:

Public Member Functions
virtual void setEventCallback (MouseListener *mouseListener);
const MouseState& getMouseState () const;
virtual void capture();

MouseListener的重要函数

Public Member Functions
virtual void mouseMoved( const MouseEvent &arg ) = 0;
virtual void mousePressed( const MouseEvent &arg, MouseButtonID id ) = 0;
virtual void mouseReleased( const MouseEvent &arg, MouseButtonID id ) = 0;

Keyboard的重要函数

Public Member Functions
virtual bool isKeyDown (KeyCode key)=0;
virtual void setEventCallback (KeyListener *keyListener);
virtual void capture();//继承自Object类

KeyListener的重要函数

Public Member Functions
virtual bool keyPressed( const KeyEvent &arg ) = 0;
virtual void keyReleased( const KeyEvent &arg ) = 0;

初始化

OIS::ParamList pl;
size_t windowHnd = 0;
std::ostringstream windowHndStr;
m_win->getCustomAttribute("WINDOW", &windowHnd);
windowHndStr << windowHnd;
pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
m_InputManager = OIS::InputManager::createInputSystem( pl );

或者

size_t hWnd = 0;
m_win->getCustomAttribute("WINDOW", &hWnd);
m_InputManager = OIS::InputManager::createInputSystem(hWnd);

自定义监听器

#include "OgreFrameListener.h"
#include "OgreRenderWindow.h"
#include <ois/OISEvents.h>
#include <ois/OISInputManager.h>
#include <ois/OISKeyboard.h>

class MyFrameListener :public FrameListener
{
public:
	MyFrameListener(RenderWindow* win){
		size_t windowHnd = 0;
		std::stringstream windowHndStr;
		win->getCustomAttribute("WINDOW", &windowHnd);//创建窗口句柄,以获取输入事件
		windowHndStr << windowHnd;//类型转换
		
		//创建输入系统,使用参数表创建输入系统
		OIS::ParamList pl;
		pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
		//产生输入控制管理系统
		mMan= OIS::InputManager::createInputSystem(pl);
		//创建键盘接口,用于查询用户按下了哪个键
		mKey= static_cast<OIS::Keyboard*>(mMan->createInputObject(OIS::OISKeyboard, false));
	}
	~MyFrameListener(){
		//销毁一个输入设备
		mMan->destroyInputObject(mKey);//销毁键盘
		//销毁控制管理系统
		OIS::InputManager::destroyInputSystem(mMan);
	}
	bool frameStarted(const Ogre::FrameEvent &evt){
		mKey->capture();//在started类中添加键盘状态获取函数capture
		if (mKey->isKeyDown(OIS::KC_ESCAPE))
		{
			return false;
		}
		else if (mKey->isKeyDown(OIS::KC_F1))
		{
			//按键需要实现的功能,如移动camera等
			
			return true;
		}
		return true;
	}
private:
	OIS::InputManager* mMan;
	OIS::Keyboard*mKey; //创建键盘对象:OIS::Keyboard* _key;如果是鼠标:OIS::Mouse*_mouse;
};
#include "OgreApplicationContext.h"
//省
class OgreFrame: public OgreBites::ApplicationContext
{
public:
	OgreFrame()
	{
		mFrameListener = NULL;
	}
	~OgreFrame()
	{
		if (mFrameListener)
		{
			delete mFrameListener;
		}
	}
	protected:
	void createScene()
	{
		// add a plane
		Plane plane(Vector3::UNIT_Y, -10);
		Ogre::MeshManager::getSingleton().createPlane("plane", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 1500, 1500, 200,200, true, 1, 5,5,Vector3::UNIT_Z);
		Entity *ent = mSceneMgr->createEntity("LightPlaneEntity","plane");
		mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);
		ent->setMaterialName("Examples/BeachStones");
		//add a light
		Light *light = mSceneMgr->createLight("Light1");
		light->setType(Ogre::Light::LT_DIRECTIONAL);
		light->setDirection(Vector3(1,-1,0));
		//add Model
		SceneNode *node = mSceneMgr->createSceneNode("Node1");
		mSceneMgr->getRootSceneNode()->addChild(node);
		Entity *Sinbad = mSceneMgr->createEntity("Sinbad", "Sinbad.mesh");
		mSinbadNode = node->createChildSceneNode("SinbadNode");
		mSinbadNode->setScale(3.0f,3.0f,3.0f);
		mSinbadNode->setPosition(Vector3(0,4.0f,0));
		mSinbadNode->attachObject(Sinbad);
		//add Shadow
		mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);
	}
	void createCamera()
	{
		mCamera = mSceneMgr->createCamera("MyCamera1");
		mCamera->setPosition(0,100,200);
		mCamera->lookAt(0,0,0);
		mCamera->setNearClipDistance(5);
	}
	void createFrameListener()
	{
		mFrameListener = new MyFrameListener(mSinbadNode, mWindow);
		mRoot->addFrameListener(mFrameListener);
	}
private:
SceneNode *mSinbadNode;
MyFrameListener*mFrameListener;
};

int main()
{
	OgreFrame app;
	app.go();
	return 0;
}

问题:

  1. 通过自定义帧监听器的方式监听键盘响应之后,自带的鼠标响应失效了???
  2. ubuntu虚拟桌面通过OgreBites::InputListener实现的键盘和鼠标监听器无响应????

OIS使用参考

以下程序解决鼠标无响应的问题:

#include "OgreFrameListener.h"
#include "OgreRenderWindow.h"
#include <ois/OISEvents.h>
#include <ois/OISInputManager.h>
#include <ois/OISKeyboard.h>

class MyFrameListener :public FrameListener,public OIS::MouseListener,public OIS::KeyListener
{
public:
	MyFrameListener(RenderWindow* win){
		size_t windowHnd = 0;
		std::stringstream windowHndStr;
		win->getCustomAttribute("WINDOW", &windowHnd);//创建窗口句柄,以获取输入事件
		windowHndStr << windowHnd;//类型转换
		
		//创建输入系统,使用参数表创建输入系统
		OIS::ParamList pl;
		pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
#if defined(OIS_LINUX_PALATFORM)
		pl.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("false")));
		pl.insert(std::make_pair(std::string("x11_mouse_hide"), std::string("false")));
		pl.insert(std::make_pair(std::string("x11_keyboard_grab"), std::string("false")));
		pl.insert(std::make_pair(std::string("XAutoRepeatOn"), std::string("true")));
#endif
		//产生输入控制管理系统
		mMan = OIS::InputManager::createInputSystem(pl);
		//创建键盘接口,用于查询用户按下了哪个键
		mKey = static_cast<OIS::Keyboard*>(mMan->createInputObject(OIS::OISKeyboard, true));
		mMouse = static_cast<OIS::Mouse*>(mMan->createInputObject(OIS::OISMouse, true));
		mKey->setEventCallBack(this);
		mMouse->setEventCallBack(this);
	}
	~MyFrameListener(){
		//销毁一个输入设备
		mMan->destroyInputObject(mKey);//销毁键盘
		mMan->destroyInputObject(mMouse);//销毁键盘
		//销毁控制管理系统
		OIS::InputManager::destroyInputSystem(mMan);
	}
	bool frameStarted(const Ogre::FrameEvent &evt){
		mKey->capture();//在started类中添加键盘状态获取函数capture
		mMouse->capture();
		return true;
	}
	bool mouseMoved(const OIS::MouseEvent &e){
		return true;
	}
	bool mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id){
		return true;
	}
	bool mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id){
		return true;
	}
	bool keyPressed(const OIS::KeyEvent &e){
		if (e.key == OIS::KC_ESCAPE)
		{
			//getRoot()->queueEndRendering();//退出
			return false;
		}
		else if (e.key == OIS::KC_F1)
		{
			//按键需要实现的功能,如移动camera等
			
		}
		return true;
	}
	bool keyReleased(const OIS::KeyEvent &e){
		return true;
	}
private:
	OIS::InputManager* mMan;
	OIS::Keyboard*mKey; //创建键盘对象:OIS::Keyboard* _key;如果是鼠标:OIS::Mouse*_mouse;
	OIS::Mouese* mMouse;
};
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。