Code Knight

Programming is so cool
随笔 - 52, 文章 - 0, 评论 - 14, 引用 - 0
数据加载中……

OGRE之输入系统笔记

     一个基本的例子:
    
#include "ExampleApplication.h"

class TutorialFrameListener : public ExampleFrameListener, public OIS::MouseListener, public OIS::KeyListener
{
public:
TutorialFrameListener(RenderWindow* win, Camera* cam, SceneManager *sceneMgr)
 : ExampleFrameListener(win, cam, true, true)
{
// Populate the camera and scene manager containers
mCamNode = cam->getParentSceneNode();
mSceneMgr = sceneMgr;

// set the rotation and move speed
mRotate = 0.13;
mMove = 250;

// continue rendering
mContinue = true;

mMouse->setEventCallback(this);
mKeyboard->setEventCallback(this);

mDirection = Vector3::ZERO;
}

bool frameStarted(const FrameEvent &evt)
{
if(mMouse)
mMouse->capture();
if(mKeyboard)
mKeyboard->capture();

mCamNode->translate(mDirection * evt.timeSinceLastFrame, Node::TS_LOCAL);
return mContinue;
}

// MouseListener
bool mouseMoved(const OIS::MouseEvent &e)
{
if (e.state.buttonDown(OIS::MB_Right))
{
mCamNode->yaw(Degree(-mRotate * e.state.X.rel), Node::TS_WORLD);
mCamNode->pitch(Degree(-mRotate * e.state.Y.rel), Node::TS_LOCAL);
}
return true;
}

bool mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id)
{
Light *light = mSceneMgr->getLight("Light1");
switch (id)
{
case OIS::MB_Left:
light->setVisible(! light->isVisible());
break;
}
return true;
}

bool mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id) { return true; }

// KeyListener
bool keyPressed(const OIS::KeyEvent &e)
{
switch (e.key)
{
case OIS::KC_ESCAPE:
mContinue = false;
break;

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;

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;
}
return true;
}

bool keyReleased(const OIS::KeyEvent &e)
{
switch (e.key)
{
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;
} // switch
return true;
}
protected:
Real mRotate; // The rotate constant
Real mMove; // The movement constant

SceneManager *mSceneMgr; // The current SceneManager
SceneNode *mCamNode; // The SceneNode the camera is currently attached to

bool mContinue; // Whether to continue rendering or not
Vector3 mDirection; // Value to move in the correct direction
};

class TutorialApplication : public ExampleApplication
{
public:
void createCamera(void)
{
// create camera, but leave at default position
mCamera = mSceneMgr->createCamera("PlayerCam");
mCamera->setNearClipDistance(5);
}

void createScene(void)
{
mSceneMgr->setAmbientLight(ColourValue(0.25, 0.25, 0.25));

// add the ninja
Entity *ent = mSceneMgr->createEntity("Ninja", "ninja.mesh");
SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode("NinjaNode");
node->attachObject(ent);

// create the light
Light *light = mSceneMgr->createLight("Light1");
light->setType(Light::LT_POINT);
light->setPosition(Vector3(250, 150, 250));
light->setDiffuseColour(ColourValue::White);
light->setSpecularColour(ColourValue::White);

// Create the scene node
node = mSceneMgr->getRootSceneNode()->createChildSceneNode("CamNode1", Vector3(-400, 200, 400));
node->yaw(Degree(-45));
node->attachObject(mCamera);

// create the second camera node/pitch node
node = mSceneMgr->getRootSceneNode()->createChildSceneNode("CamNode2", Vector3(0, 200, 400));
}

void createFrameListener(void)
{
// Create the FrameListener
mFrameListener = new TutorialFrameListener(mWindow, mCamera, mSceneMgr);
mRoot->addFrameListener(mFrameListener);

// Show the frame stats overlay
mFrameListener->showDebugOverlay(true);
}
};

#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"

INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)
#else
int main(int argc, char **argv)
#endif
{
// Create application object
TutorialApplication app;

try {
app.go();
} catch(Exception& e) {
#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
MessageBox(NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
fprintf(stderr, "An exception has occurred: %s\n",
e.getFullDescription().c_str());
#endif
}

return 0;
}

按照理论来说
unbuffered:不断的响应按键信息,直到按键放开。例如,按下上下左右,使得角色持续移动。
               一般来讲适合于3D场景漫游过程,当在每帧渲染之前,系统捕获输入设备状态,并根据这些状态对场景中的物体和摄象机进行控制。
buffered:在一个按键放开之前,只处理一次输入信息。
             例如呼出主菜单。适合于GUI界面的情况(如设置菜单),输入设备状态可以被发送到各GUI元素进行处理(如按钮被按下)。

这个例子试图说明缓冲输入和非缓冲输入的区别,但是让我困惑的是为什么采用了缓冲输入系统还能响应持续按键呢?编译后运行按住WSAD照样移动摄像机。

posted on 2009-12-06 19:44 Code Knight 阅读(763) 评论(1)  编辑 收藏 引用 所属分类: OGRE

评论

# re: OGRE之输入系统笔记  回复  更多评论   

unbuffered:快照catch
buffered:输入消息队列
我的理解
2009-12-07 09:14 | LOGOS

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理