当前位置: 首页 > 工具软件 > OGRE > 使用案例 >

OGRE(三)

谷梁煌
2023-12-01

1.帧监听

现在我们代替其原有的FrameListener,使用我们自己定义的实现过程.这样我们就不能使用自带的Framelistener.

class Example25FrameListener : public Ogre::FrameListener
{
};
新建一个类,继承FrameListener.

private:
Ogre::SceneNode* _node;
_node:私有变量,指向场景节点指针.

以下是成员函数

bool frameStarted(const Ogre::FrameEvent &evt)
{
 	 _node->translate(Ogre::Vector3(0.1,0,0));
 	 return true;
}

frameStarted:在帧(帧,意思是指场景中的单个图像)被渲染之前,Ogre::Root 遍历所有被添加的Framelistener并调用其frameStarted()方法.每次调用这个函数时使相应的节点移动0.1.

如果想让帧移动的速率和机器无关,把_node->translate(Ogre::Vector3(10,0,0));换成如下一行.

_node->translate(Ogre::Vector3(10,0,0) * evt.timeSinceLastFrame);
evt.timeSinceLastFrame:字面意思.

void createFrameListener()
{
 	 FrameListener = new Example25FrameListener(_SinbadNode);
 	 mRoot->addFrameListener(FrameListener);
}
FrameListener:上述类定义的一个对象,
mRoot->addFrameListener:加入帧监听到根节点.

2.添加输入支持

添加用户输入对象作为成员变量到帧监听类中:

OIS::InputManager* _man;
OIS::Keyboard* _key;
InputManager: 定义一个输入管理器.

Keyboard: 定义一个控制键盘操作的指针.

构造函数修改为:

Example25FrameListener(Ogre::SceneNode* node,RenderWindow* win)
		{
			_node = node;
			FrameListener = NULL;
			size_t windowHnd = 0;
			win->getCustomAttribute("WINDOW", &windowHnd); 	 //获取窗口的句柄
			windowHndStr << windowHnd;
			OIS::ParamList pl; 	 //创建OIS参数表
			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 )); 	 //创建一个键盘来监听用户的输入
			
		}
RenderWindow* win:传来渲染窗口对象的指针.因为我们需要渲染窗口的句柄来创建输入系统.

windowHndStr<<windowHnd:把句柄从数值类型转化成字符串类型.

接下来是析构函数:

~Example27FrameListener()
{
 	 _man->destroyInputObject(_key);
 	 OIS::InputManager::destroyInputSystem(_man);
}

之前的frameStarted改为:

bool frameStarted(const Ogre::FrameEvent &evt)
		{
			_node->translate(Ogre::Vector3(0.1,0,0));
			_key->capture(); 	 //捕获按键
			if(_key->isKeyDown(OIS::KC_ESCAPE))
			{
				return false;
			}
			return true;
		}
因为监听类发生了变化,所以在createFrameListener中的初始化实例的过程也要发生变化:

void createFrameListener()
		{
			FrameListener = new Example25FrameListener(_SinbadNode,mWindow);
			mRoot->addFrameListener(FrameListener);
		}
mWindow:这个变量是从父类继承下来的,不需要我们实例化.

3.添加漫游摄像机

#include "Ogre\ExampleApplication.h"

class Example30FrameListener : public Ogre::FrameListener  //公有继承帧监听类
{
private:
	Ogre::SceneNode* _node;  //场景节点指针
	Ogre::Camera* _Cam; 	 //摄像机指针,用来接受主类传过来的摄像机指针
	OIS::InputManager* _man; 	 //输入管理者
	OIS::Keyboard* _key; 	 //键盘控制
	OIS::Mouse* _mouse; 	 //鼠标控制
	float _movementspeed; 	 //移动速度
public:

	Example30FrameListener(Ogre::SceneNode* node,RenderWindow* win,Ogre::Camera* cam) 	 //需要三个参数:场景节点指针,渲染窗口指针,摄像机指针
	{
		_node = node; 	 //你懂得
		_Cam = cam; 	 //你懂得

		_movementspeed = 200.0f; 	 //设置速度

		size_t windowHnd = 0; 	 //用来接收句柄的
		std::stringstream windowHndStr; 	 //定义句柄字符串

		win->getCustomAttribute("WINDOW", &windowHnd); 	 //用传进来的渲染窗口指针获取句柄
		windowHndStr << windowHnd; 	 //转str
		
		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 )); 		 //初始化键盘控制
		_mouse = static_cast<OIS::Mouse*>(_man->createInputObject( OIS::OISMouse, false )); 		 //初始化鼠标控制
	}
	
	bool frameStarted(const Ogre::FrameEvent  &evt) 		 //每渲染一帧前都会调用一次这个函数
	{
		Ogre::Vector3 translate(0,0,0); 		 //每次都使它归0,避免速度一直叠加
		
		_key->capture(); 	 //捕获键盘和鼠标
		_mouse->capture();
		if(_key->isKeyDown(OIS::KC_ESCAPE))
		{
			return false;
		}
		if(_key->isKeyDown(OIS::KC_W))
		{
			translate += Ogre::Vector3(0,0,-1);
		}
		if(_key->isKeyDown(OIS::KC_S))
		{
			translate += Ogre::Vector3(0,0,1);
		}
		if(_key->isKeyDown(OIS::KC_A))
		{
			translate += Ogre::Vector3(-1,0,0);
		}
		if(_key->isKeyDown(OIS::KC_D))
		{
			translate += Ogre::Vector3(1,0,0);
		}
		
		float rotX = _mouse->getMouseState().X.rel * evt.timeSinceLastFrame* -1; 	 //捕获鼠标绕X,Y旋转了多少,返回的是弧度
		float rotY = _mouse->getMouseState().Y.rel * evt.timeSinceLastFrame * -1;
		

		_Cam->yaw(Ogre::Radian(rotX)); 	 //绕Y轴旋转摄像机
		_Cam->pitch(Ogre::Radian(rotY)); 	 //绕X轴旋转摄像机
		_Cam->moveRelative(translate*evt.timeSinceLastFrame * _movementspeed); 	 //让摄像机平移

		return true;
	}
};


class Example30 : public ExampleApplication
{
private:
	Ogre::SceneNode* _SinbadNode; 		 //Sinbad节点
public:

	void createScene() 	 
	{
		Ogre::Plane plane(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);


		Ogre::Entity* ent = mSceneMgr->createEntity("LightPlaneEntity", "plane");
		mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);
		ent->setMaterialName("Examples/BeachStones");


		Ogre::SceneNode* node = mSceneMgr->createSceneNode("Node1");
		mSceneMgr->getRootSceneNode()->addChild(node);



		Ogre::Light* light = mSceneMgr->createLight("Light1");
		light->setType(Ogre::Light::LT_DIRECTIONAL);
		light->setDirection(Ogre::Vector3(1,-1,0));


		Ogre::Entity* Sinbad = mSceneMgr->createEntity("Sinbad", "Sinbad.mesh");
		_SinbadNode = node->createChildSceneNode("SinbadNode");
		_SinbadNode->setScale(3.0f,3.0f,3.0f);
		_SinbadNode->setPosition(Ogre::Vector3(0.0f,4.0f,0.0f));
		_SinbadNode->attachObject(Sinbad);

		mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);	
	}

	void createCamera() 	 //如果把这里的摄像机信息加入到createScene中去的话,则不能控制摄像头了
	{
	
		mCamera = mSceneMgr->createCamera("MyCamera1");
		mCamera->setNearClipDistance(5);
		mCamera->setPosition(0,100,200);
		


	}

	void createFrameListener() 	 //顾名思义,创建帧监听
	{
		Ogre::FrameListener* FrameListener = new Example30FrameListener(_SinbadNode,mWindow,mCamera);
		mRoot->addFrameListener(FrameListener);
	}
};

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














 类似资料: