第四章 OGRE中的帧监听、鼠标键盘控制、绘画模式、计时器

本文介绍了一个基于Ogre3D的游戏开发实例,详细展示了如何创建场景、设置光照及摄像机,并通过键盘和鼠标输入控制角色移动及视角变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include "ExampleApplication.h"

//2 begin
class Example25FrameListener:public Ogre::FrameListener
{
public:
	//2.2 begin
/*
	Example25FrameListener(Ogre::SceneNode* node)
	{
		_node=node;
	}*/

	//2.2 end
	//4_3|2.2 begin
	//4.1 begin
	//Example25FrameListener(Ogre::SceneNode* node,RenderWindow* win):_node(node)
	//4.1 end
	//6_5|4.1 begin
	Example25FrameListener(Ogre::SceneNode* node,RenderWindow* win,Ogre::Camera* cam):_node(node),_Cam(cam)
	//6_5|4.1 end
	{
		size_t windowHnd=0;
		std::stringstream windowHndStr;
		win->getCustomAttribute("WINDOW",&windowHnd);
		windowHndStr<<windowHnd;
		OIS::ParamList pl;
		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));//InputManage->InputSystem->InputObject 
		//6_5 begin
		_mouse=static_cast<OIS::Mouse*>(_man->createInputObject(OIS::OISMouse,false));
		//6_5 end
		//7_6 begin
		_PolyMode=Ogre::PolygonMode::PM_SOLID;
		//7_6 end
		//8_7 begin
		_timer.reset();
		//8_7 end

	}
	~Example25FrameListener()
	{
		//6_5 begin
		_man->destroyInputObject(_mouse);
		//6_5 end
		_man->destroyInputObject(_key);
		OIS::InputManager::destroyInputSystem(_man);

	}
	//4_3|2.2 end

	bool frameStarted(const Ogre::FrameEvent &evt)//Before a frame is rendered,Ogre::Root iterates over all added FrameListeners and calls the frameStarted() method of each one.
	{
		//2.1 begin
		//_node->translate(Ogre::Vector3(0.1,0,0));
		//2.1 end
		//3_2|2.1 begin
		//_node->translate(Ogre::Vector3(10,0,0)*evt.timeSinceLastFrame);
		
		//以下两行是OgreRoot.h
		//bool renderOneFrame(void);//里面会触发渲染前和渲染后事件
		//bool renderOneFrame(Real timeSinceLastFrame);//如果需要锁定30fps,需要传入1/30
		
		//3_2|2.1 end


		

		//4_3|2.2 begin
		_key->capture();
		if(_key->isKeyDown(OIS::KC_ESCAPE))
			return false;
		//4_3|2.2 end
		//5_4|3_2 begin
		Ogre::Vector3 translate=Ogre::Vector3(0,0,0);
		if(_key->isKeyDown(OIS::KC_W))
		{
			translate+=Ogre::Vector3(0,0,-10);
		}
		if(_key->isKeyDown(OIS::KC_S))
		{
			translate+=Ogre::Vector3(0,0,10);
		}
		if(_key->isKeyDown(OIS::KC_A))
		{
			translate+=Ogre::Vector3(-10,0,0);
		}
		if(_key->isKeyDown(OIS::KC_D))
		{
			translate+=Ogre::Vector3(10,0,0);
		}
		//7_6 begin
		//7.1 begin
		//if(_key->isKeyDown(OIS::KC_R))
		//7.1 end
		//8_7|7.1 begin
		if(_key->isKeyDown(OIS::KC_R) && _timer.getMilliseconds() > 250)
		//8_7|7.1 end
		{
			if(_PolyMode == PM_SOLID)
			{
				_PolyMode=Ogre::PolygonMode::PM_WIREFRAME;		
			}
			else if(_PolyMode == PM_WIREFRAME)
			{
				_PolyMode = Ogre::PolygonMode::PM_POINTS;
			}
			else if(_PolyMode == PM_POINTS)
			{
				_PolyMode = Ogre::PolygonMode::PM_SOLID;
			}
			//8_7 begin
			_timer.reset();
			//8_7 end
		}
		
		//A solution for the problem of changing the render mode too fast is the use of a timer.

		_Cam->setPolygonMode(_PolyMode);
		//7_6 end
		_node->translate(translate*evt.timeSinceLastFrame);
		//5_4|3_2 end
		//6_5 begin
		_mouse->capture();
		float rotX=_mouse->getMouseState().X.rel*evt.timeSinceLastFrame*-1;
		float rotY=_mouse->getMouseState().Y.rel*evt.timeSinceLastFrame*-1;
		_Cam->yaw(Ogre::Radian(rotX));
		_Cam->pitch(Ogre::Radian(rotY));
		_Cam->moveRelative(translate*evt.timeSinceLastFrame);
		//6_5 end
		return true;//If it return false,Ogre 3D would interpret this as a signal to drop out of the render loop,and with this,the application would be closed.
	}
private:
	Ogre::SceneNode* _node;
	//4_3|2.2 begin
	OIS::InputManager* _man;
	OIS::Keyboard* _key;
	//4_3|2.2 end
	//6_5 begin
	Ogre::Camera* _Cam;
	OIS::Mouse* _mouse;
	//6_5 end
	//7_6 begin
	Ogre::PolygonMode _PolyMode;
	//7_6 end
	//8_7 begin
	Ogre::Timer _timer;
	
	//8_7 end
};
//2 end

class Example1:public ExampleApplication
{
public:
	//2 begin
	Example1()
	{
		FrameListener=NULL;
	}
	~Example1()
	{
		if(FrameListener)
		{
			delete FrameListener;
		}
	}
	//2 end
	void createScene()
	{
		//1 begin
		Ogre::Plane plane(Vector3::UNIT_Y,-10);
		Ogre::MeshManager::getSingleton().createPlane("planemesh",ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,plane,1500,1500,200,200,true,1,5,5,Vector3::UNIT_Z);
		Ogre::Entity* LightPlane=mSceneMgr->createEntity("LightPlane","planemesh");
		mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(LightPlane);
		LightPlane->setMaterialName("Examples/BeachStones");

		Ogre::Light* DirectionalLight=mSceneMgr->createLight("MyDirectionalLight");
		DirectionalLight->setType(Ogre::Light::LT_DIRECTIONAL);
		DirectionalLight->setDirection(Ogre::Vector3(1,-1,0));
		
		Ogre::SceneNode* SubNodeRoot=mSceneMgr->getRootSceneNode()->createChildSceneNode("SubNodeRoot");
		Ogre::Entity* Sinbad=mSceneMgr->createEntity("Sinbad","Sinbad.mesh");
		_SinbadNode=SubNodeRoot->createChildSceneNode("SinbadNode");
		_SinbadNode->setPosition(Ogre::Vector3(0.0f,4.0f,0.0f));
		_SinbadNode->setScale(3.0f,3.0f,3.0f);
		_SinbadNode->attachObject(Sinbad);

		mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
		//1 end
	}
	//1 begin
	void createCamera()
	{
		mCamera=mSceneMgr->createCamera("MyCamera1");
		mCamera->setPosition(Ogre::Vector3(0,100,200));
		mCamera->lookAt(0,0,0);
		mCamera->setNearClipDistance(5);
	}
	//1 end
//1 begin
//2 begin
	void createFrameListener()
	{
		//2.1 begin
		//FrameListener=new Example25FrameListener(_SinbadNode)
		//2.1 end
		//4.2_3|2.1 begin
		//FrameListener=new Example25FrameListener(_SinbadNode,mWindow);//Because we need the window handle for the creation of the input system.
		//4.2_3|2.1 end
		//6_5|4.2 begin
		FrameListener=new Example25FrameListener(_SinbadNode,mWindow,mCamera);
		//6_5|4.2 end
		mRoot->addFrameListener(FrameListener);
	}
//2 end
private:
	Ogre::SceneNode* _SinbadNode;
//1 end
//2 begin
	Ogre::FrameListener* FrameListener;
//2 end
};


int main()
{
	Example1 app;
	app.go();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值