Ogre_初学指导_7_"帧监听:鼠标控制、渲染模式及计时器"

帧监听:鼠标控制、渲染模式及计时器

此节依然是讲解帧监听中的一些操作:鼠标(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;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值