帧监听:鼠标控制、渲染模式及计时器
此节依然是讲解帧监听中的一些操作:鼠标(Mouse)、渲染模式(Render Mode)及计时器(timer)
一、鼠标控制
1、首先创建Mouse对象,并用输入系统实例化输入对象(Mouse)。
如:OIS::Mouse*_Mouse;
_Mouse =static_case<OIS::Mouse*>(_man->createInputObject(OIS::OISMouse,false));//_man为上一节创建的输入系统(InputManager)
2、侦听函数中,获得鼠标操作(Capture)以获取鼠标状态
如:_Mouse->capture();
Float rotX =_Mouse->getMouseState().X.rel;//
3、实现鼠标控制摄像机
根据当前鼠标的位置进行旋转:
如:鼠标左右晃动(X轴方向变动),镜头也跟着变化,即设置摄像机绕Y轴转动。(要了解Ogre中的 坐标系统,参见第四小节)
Float rotX =_Mouse->getMouseState().X.rel * evt.timeSinceLastFrame * (-1);
_Camera->yaw(Ogre::Radian(rotX));
二、渲染模式
实体模式(Solid)、线框模式(Wireframe)、点模式(Points)。
1、 创建渲染模式:PolygonMode
Ogre::PolygonMode _PolyMode;
2、 初始化:_PolyMode= Ogre::PolygonMode::PM_SOLID;//实体模型
3、 PolygonMode是个枚举类型,只含有三个量:PM_SOLID、PM_WIREFRAME、PM_POINTS。
4、 设置模式切换:假设按键keynum= “R”
Keynum= OIS::KC_R;
if(_key->isKeyDown(keynum))
{
switch(_PolyMode)
{
casePM_SOLID: _PolyMode = Ogre::PolygonMode::PM_WIREFRAME;
break;
casePM_WIREFRAME: _PolyMode = Ogre::PolygonMode::PM_POINTS;
break;
casePM_POINTS: _PolyMode = Ogre::PolygonMode::PM_SOLID;
break;
default:
break;
}
}
5、 完成设置:_Camera->setPolygonMode(_PolyMode);
三、计时器(timer)
根据“二”中的代码,如果进行调试会发现,当我们按下R键时,渲染模式会切换很多次,这是因为我们人手的反应速度小于每一帧的更新时间,这就导致了虽然我们按下了一次键但相应N次的结果!
为了解决这一问题,我们使用计时器。每一次当我们按下R键,一个计时器就启动了,并且只有当足够的时间过去我们才能处理另一个R键的按下。
1、 定义:Ogre::Timer_timer;
2、 复位(置零):_timer.reset();
每当我们响应完一个按键后,要记得重新复位,否则,此按键只能相应一次
3、 设置相应时间:_timer.getMilliseconds()> 250;//大于0.25秒
代码:
#include"ExampleApplication.h"
usingnamespaceOgre;
classMyFrameListener:publicOgre::FrameListener
{
private:
SceneNode*mNode;
OIS::InputManager*_man;
OIS::Keyboard*_key;
OIS::Mouse*_mouse;
Camera*_Camera;
PolygonMode_PolyMode;
Timer_timer;
public:
MyFrameListener(SceneNode*node,RenderWindow*win,Camera*cam)
{
mNode=node;
_Camera=cam;
size_twindowHnd=0;
std::stringstreamwindowHndStr;
win->getCustomAttribute("WINDOW",&windowHnd);
windowHndStr<<windowHnd;//类型转换
//创建输入系统
OIS::ParamListpl;
pl.insert(std::make_pair(std::string("WINDOW"),windowHndStr.str()));
_man=OIS::InputManager::createInputSystem(pl);
_key=static_cast<OIS::Keyboard*>(_man->createInputObject(OIS::OISKeyboard,false));
_mouse=static_cast<OIS::Mouse*>(_man->createInputObject(OIS::OISMouse,false));
//设置渲染模式
_PolyMode=Ogre::PolygonMode::PM_SOLID;
//计时器
_timer.reset();
}
~MyFrameListener()
{
_man->destroyInputObject(_key);//销毁键盘
_man->destroyInputObject(_mouse);//销毁鼠标
OIS::InputManager::destroyInputSystem(_man);
}
voidchangePolygonMode(OIS::KeyCodekeynum=OIS::KC_R)
{
if(_key->isKeyDown(keynum)&&_timer.getMilliseconds()>250)//大于0.25秒
{
_timer.reset();
switch(_PolyMode)
{
casePM_SOLID:_PolyMode=Ogre::PolygonMode::PM_WIREFRAME;
break;
casePM_WIREFRAME:_PolyMode=Ogre::PolygonMode::PM_POINTS;
break;
casePM_POINTS:_PolyMode=Ogre::PolygonMode::PM_SOLID;
break;
default:
break;
}
}
_Camera->setPolygonMode(_PolyMode);
}
boolframeStarted(constOgre::FrameEvent&evt)
{
_key->capture();
_mouse->capture();
//Mouse state
floatrotX=_mouse->getMouseState().X.rel*evt.timeSinceLastFrame*-1;
floatrotY=_mouse->getMouseState().Y.rel*evt.timeSinceLastFrame*-1;
//change the Camera position
_Camera->yaw(Ogre::Radian(rotX));
_Camera->pitch(Ogre::Radian(rotY));
//_Camera->moveRelative(Vector3(10,0,0) *evt.timeSinceLastFrame * 10);
if(_key->isKeyDown(OIS::KC_ESCAPE))
{
returnfalse;
}
//改变渲染模式
changePolygonMode();
//模型节点更新位置
//mNode->translate(Vector3(10,0,0) *evt.timeSinceLastFrame);
returntrue;
}
};
classexample1:publicExampleApplication
{
public:
example1()
{
mFrameListener=NULL;
}
~example1()
{
if(mFrameListener)
{
deletemFrameListener;
}
}
protected:
voidcreateScene()
{
// add a plane
Planeplane(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);
}
voidcreateCamera()
{
mCamera=mSceneMgr->createCamera("MyCamera1");
mCamera->setPosition(0,100,200);
mCamera->lookAt(0,0,0);
mCamera->setNearClipDistance(5);
}
voidcreateFrameListener()
{
mFrameListener=newMyFrameListener(mSinbadNode,mWindow,mCamera);
mRoot->addFrameListener(mFrameListener);
}
private:
SceneNode*mSinbadNode;
FrameListener*mFrameListener;
};
intmain()
{
example1ex1;
ex1.go();
return0;
}