OGRE基础教程五 Buffered Input
来源:互联网 发布:灌篮高手 爱知学院 编辑:程序博客网 时间:2024/05/21 05:40
英语水平有限,欢迎大家批评指正
本文并没有将原文全部翻译,只是将其中的一些知识点翻译总结了一下,想要查看详细讲解的话,可以到原文处看一下,附上英文原文地址:http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Basic+Tutorial+5&structure=Tutorials
Buffered Input in a Nutshell
Introduction
前面的教程中我们使用了非缓存输入,即每一帧我们都查询OIS::Keyboard和OIS::Mouse实例的状态来查看什么键或鼠标按钮被按下。缓存输入使用监听器接口来通知你的程序有事件发生。例如,当一个键被按下,KeyListener::keyPressed事件被执行,当按钮被松开,KeyListener::keyReleased事件被执行,在所有已注册的KeyListener类中。他关心的是记录触发次数或前一帧键是否是未被按下的。
OIS也支持非缓存Joystick事件通过OIS::JoystickListener接口。
对应OIS监听器系统有一件重要的事情需要注意,那就是每个Keyboard、Mouse、Joystick对象只能有一个监听器。这样是为了简单(也为了速度)。调用setEventCallback函数乘以次数,最后注册的侦听器得到事件。如果你要多个对象得到Key、Mouse、Joystick事件,你就必须写一条消息自己分配。还有注意我们仍要在frameRenderingQueued方法中调用Keyboard::capture和Mouse::capture。OIS不使用线程来确定键盘和鼠标的状态,所以你就必须说明应该什么时候捕获输入。
The KeyListener Interface
OIS KeyListener接口提供两个纯虚函数,keyPressed函数(每次一个键被按下时调用),keyReleased函数(每次一个键被松开时调用)。传给这些函数的参数是一个KeyEvent,它包含了被按下或松开的按键代码。
The MouseListener Interface
MouseListener接口只是比KeyListener接口稍微复杂一点。它包含两个函数来查看鼠标按钮被按下或松开:MouseListener::mousePressed和MouseListener::mouseReleased。它还有一个mouseMoved函数,当鼠标移动时就会被调用。这些函数都接收一个MouseEvent对象,它将鼠标的当前状态放在了“state”变量中。对应MouseState对象需要注意的最重要的事情就是它不仅包含了鼠标上一个动作的XY相对坐标(即,自上一次MouseListener::mouseMoved函数被调用它所移动的距离),还包含了XY决定坐标(即,他们在屏幕上的真正位置)。
The Code
Variables
Real mRotate; // 旋转常量
Real mMove; // 移动常量
SceneNode *mCamNode; // camera当前绑定的场景节点
Vector3 mDirection; // 移动的正确方向,包含了每一帧中我们应该如何 //移动camera的信息
createFrameListener method
添加如下代码到createFrameListener方法中:
// Populate the camera container
mCamNode = mCamera->getParentSceneNode();
// set the rotation and move speed
mRotate = 0.13;
mMove = 250;
OIS mMouse和mKeyboard对象以及从BaseApplication的createFrameListener方法中得到。那里我们调用这些对象的setEventCallback方法来注册侦听器:
// Do not add this code to the project!
mMouse->setEventCallback(this);
mKeyboard->setEventCallback(this);
最后,我们需要初始化mDirection为零向量(因为我们初始时不移动):
mDirection = Ogre::Vector3::ZERO;
Key Bindings
继续之前,我们应绑定ESC键用来退出程序。keyPressed方法改下为:
bool keyPressed(const OIS::KeyEvent& evt)
{
switch (evt.key)
{
case OIS::KC_ESCAPE:
mShutDown = true;
break;
default:
break;
}
return true;
}
把如下代码添加到frameRenderingQueued方法中,以使程序响应键盘输入:
if (mWindow->isClosed()) return false;
if (mShutDown) return false;
mKeyboard->capture();
mMouse->capture();
mTrayMgr->frameRenderingQueued(evt);
现在在前面的switch语句中添加其他的键绑定代码。第一通过按1和2允许用户在视点间转换:
case OIS::KC_1:
mCamera->getParentSceneNode()->detachObject(mCamera);
mCamNode = mSceneMgr->getSceneNode("CamNode1");
mCamNode->attachObject(mCamera);
break;
case OIS::KC_2:
mCamera->getParentSceneNode()->detachObject(mCamera);
mCamNode = mSceneMgr->getSceneNode("CamNode2");
mCamNode->attachObject(mCamera);
break;
下面添加键盘动作,每当用户按下绑定有动作的按键,我们都将增加或减少(根据方向)mMove:
case OIS::KC_UP:
case OIS::KC_W:
mDirection.z = -mMove;
break;
case OIS::KC_DOWN:
case OIS::KC_S:
mDirection.z = mMove;
break;
case OIS::KC_LEFT:
case OIS::KC_A:
mDirection.x = -mMove;
break;
case OIS::KC_RIGHT:
case OIS::KC_D:
mDirection.x = mMove;
break;
case OIS::KC_PGDOWN:
case OIS::KC_E:
mDirection.y = -mMove;
break;
case OIS::KC_PGUP:
case OIS::KC_Q:
mDirection.y = mMove;
break;
现在我们要撤销mDirection向量的改变,无论何时按键被按下来停止动作。在keyReleased方法中添加如下代码:
switch (evt.key)
{
case OIS::KC_UP:
case OIS::KC_W:
mDirection.z = 0;
break;
case OIS::KC_DOWN:
case OIS::KC_S:
mDirection.z = 0;
break;
case OIS::KC_LEFT:
case OIS::KC_A:
mDirection.x = 0;
break;
case OIS::KC_RIGHT:
case OIS::KC_D:
mDirection.x = 0;
break;
case OIS::KC_PGDOWN:
case OIS::KC_E:
mDirection.y = 0;
break;
case OIS::KC_PGUP:
case OIS::KC_Q:
mDirection.y = 0;
break;
default:
break;
}
return true;
现在mDirection根据输入更新,我们需要使变化发生。在frameRenderingQueued函数中添加代码:
mCamNode->translate(mDirection*evt.timeSinceLastFrame, Ogre::Node::TS_LOCAL);
Mouse Bindings
我们将通过鼠标左键来开关光源,mousePressed函数有MouseEvent和MouseButtonID两个参数。我们通过MouseButtonID来确定哪个按钮被按下,将mousePressed函数修改为:
Ogre::Light *light = mSceneMgr->getLight("Light1");
switch (id)
{
case OIS::MB_Left:
light->setVisible(! light->isVisible());
break;
default:
break;
}
return true;
每当鼠标移动时,我们就查看鼠标右键是否按下。如果是,我们就旋转camera根据相对移动。我们可以通过传个这个函数的MouseEvent对象来得到鼠标的相对动作。它包含了一个叫做state包含了MouseState(主要是关于鼠标的详细信息)的变量。MouseState::buttonDown会告诉我们某一特定的鼠标按钮是否被按下,X和Y变量会告诉我们鼠标的相对动作。将mouseMoved函数改为:
if (evt.state.buttonDown(OIS::MB_Right))
{
mCamNode->yaw(Ogre::Degree(-mRotate * evt.state.X.rel), Ogre::Node::TS_WORLD);
mCamNode->pitch(Ogre::Degree(-mRotate * evt.state.Y.rel), Ogre::Node::TS_LOCAL);
}
return true;
编译运行程序,鼠标右键按下时camera就可以自由观察场景。
- OGRE基础教程五 Buffered Input
- 第五章 Buffered input
- OGRE基础教程四 Frame Listeners and Unbuffered Input
- Ogre笔记八:基础教程五—缓冲输入
- OGRE(五)
- Ogre笔记五:基础教程二—摄像机、阴影和光照处理
- OGRE基础教程六 The Ogre Startup Sequence
- OGRE基础教程七 CEGUI and Ogre
- OGRE基础教程1(上)
- OGRE基础教程1(下)
- 基础教程六(CEGUI和OGRE)
- OGRE基础教程1(上)
- OGRE基础教程1(下)
- ogre学习笔记-基础教程345
- ogre中缓冲(buffered)输入方式和非缓冲(unbuffered)输入有什么区别?
- Ogre笔记九:基础教程六—CEGUI和Ogre
- OGRE 引擎官方基础教程 (七) OGRE 和 CEGUI
- Ogre基础教程7:CEGUI 与 Ogre(未完成)
- 在linux下如何较好的生成随机数
- uva_10465Homer Simpson
- 0-1背包的动态规划解法
- struts2从一个action我想跳转到另一个action,并且带上值
- Word公式编辑器常见问题的解决办法
- OGRE基础教程五 Buffered Input
- 从程序员到项目经理(一)
- 探索推荐引擎内部的秘密
- Javascript 面向对象编程(一):封装
- 人生这七年(航向)
- Javascript面向对象编程(二):构造函数的继承
- OGRE基础教程六 The Ogre Startup Sequence
- Javascript面向对象编程(三):非构造函数的继承
- 【php】获取当前url