Ogre笔记七:基础教程四—帧监听器和非缓冲输入

非缓冲输入,个人觉得不怎么好用,但是在某些特殊场景下可能会有大用。

首先,我们了解一下这一节教程想实现个什么东西:

我们将把一个忍者放到屏幕中,并在场景中加上点光源。

当你点击鼠标左键,灯光会打开或关闭。按住鼠标右键,则开启“鼠标观察”模式(也就是你用摄像机四处观望,想想一下你玩3D游戏的场景)。

按下1、2键,以选择从哪一个视口来观看场景。


#include "ExampleApplication.h"
class TutorialFrameListener : public ExampleFrameListener
{
public:
	TutorialFrameListener(RenderWindow* win, Camera* cam, SceneManager *sceneMgr)
		: ExampleFrameListener(win, cam, false, false)
	{
		// 键盘和鼠标状态追踪
		mMouseDown = false;
		mToggle = 0.0;
		// Populate the camera and scene manager containers
		mCamNode = cam->getParentSceneNode();
		mSceneMgr = sceneMgr;
		// 设置旋转和移动速度
		mRotate = 0.13;
		mMove = 250;
	}
	bool frameStarted(const FrameEvent &evt)
	{
		mMouse->capture();
		mKeyboard->capture();

		//Escape键被按下时程序退出
		if(mKeyboard->isKeyDown(OIS::KC_ESCAPE))
			return false;

		//左击鼠标控制灯的开关
		bool currMouse = mMouse->getMouseState().buttonDown(OIS::MB_Left);
		if (currMouse && ! mMouseDown)
		{
			Light *light = mSceneMgr->getLight("Light1");
			light->setVisible(! light->isVisible());
		}
		mMouseDown = currMouse;

		//事件之间的休息时间
		mToggle -= evt.timeSinceLastFrame;

		//按1、2键,能够转换摄像机的视口
		if ((mToggle < 0.0f ) && mKeyboard->isKeyDown(OIS::KC_1))
		{
			mToggle = 0.5f;
			mCamera->getParentSceneNode()->detachObject(mCamera);
			mCamNode = mSceneMgr->getSceneNode("CamNode1");
			mCamNode->attachObject(mCamera);
		}
		else if ((mToggle < 0.0f) && mKeyboard->isKeyDown(OIS::KC_2))
		{
			mToggle = 0.5f;
			mCamera->getParentSceneNode()->detachObject(mCamera);
			mCamNode = mSceneMgr->getSceneNode("CamNode2");
			mCamNode->attachObject(mCamera);
		}

		//按下方向键或W、A、S、D键时,进行mCamNode的平移
		Vector3 transVector = Vector3::ZERO;
		if (mKeyboard->isKeyDown(OIS::KC_UP) || mKeyboard->isKeyDown(OIS::KC_W))
			transVector.z -= mMove;
		if (mKeyboard->isKeyDown(OIS::KC_DOWN) || mKeyboard->isKeyDown(OIS::KC_S))
			transVector.z += mMove;
		if (mKeyboard->isKeyDown(OIS::KC_LEFT) || mKeyboard->isKeyDown(OIS::KC_A))
			transVector.x -= mMove;
		if (mKeyboard->isKeyDown(OIS::KC_RIGHT) || mKeyboard->isKeyDown(OIS::KC_D))
			transVector.x += mMove;

		//E键或者PageDown键进行向下移动,用Q键或者PageUp键进行向上移动
		if (mKeyboard->isKeyDown(OIS::KC_PGUP) || mKeyboard->isKeyDown(OIS::KC_Q))
			transVector.y += mMove;
		if (mKeyboard->isKeyDown(OIS::KC_PGDOWN) || mKeyboard->isKeyDown(OIS::KC_E))
			transVector.y -= mMove;

		//摄像机旋转
		mCamNode->translate(transVector*evt.timeSinceLastFrame,Node::TS_LOCAL);

		if (mMouse->getMouseState().buttonDown(OIS::MB_Right))
		{
			mCamNode->yaw(Degree(-mRotate * mMouse->getMouseState().X.rel), Node::TS_WORLD);
			mCamNode->pitch(Degree(-mRotate * mMouse->getMouseState().Y.rel), Node::TS_LOCAL);
		}

		return true;
		//return ExampleFrameListener::frameStarted(evt);
	}
protected:
	bool mMouseDown; // 鼠标左键是否在上一帧被按下
	Real mToggle; // 直到下一次触发的时间
	Real mRotate; // 滚动常量
	Real mMove; // 移动常量
	SceneManager *mSceneMgr; // 当前场景管理器
	SceneNode *mCamNode; // 当前摄像机所附在的场景节点
};
class TutorialApplication : public ExampleApplication
{
public:
	TutorialApplication()
	{
	}
	~TutorialApplication()
	{
	}
protected:
	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));

		//添加一个忍者
		Entity *ent = mSceneMgr->createEntity("Ninja", "ninja.mesh");
		SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode("NinjaNode");
		node->attachObject(ent);

		//添加一个光源
		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
		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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值