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类中添加键盘状态获取函数captureif (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 planePlane 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 lightLight *light = mSceneMgr->createLight("Light1");light->setType(Ogre::Light::LT_DIRECTIONAL);light->setDirection(Vector3(1,-1,0));//add ModelSceneNode *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 ShadowmSceneMgr->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;
}
问题:
- 通过自定义帧监听器的方式监听键盘响应之后,自带的鼠标响应失效了???
- 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类中添加键盘状态获取函数capturemMouse->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;
};