OGRE自定义渲染循环实现

#include "Ogre/Ogre.h"
#include "OIS/OIS.h"//引入OIS头文件来使用OIS

//创建一个新的称为MyFrameListener,并列出三个公有的事件响应函数
class MyFrameListener:public Ogre::FrameListener
{
	//私有成员来存储InputManager和Keyboard
private:
	OIS::InputManager *_InputManager;
	OIS::Keyboard *_Keyboard;
public:
	//FrameListener需要一个指向RenderWindow类的指针来初始化OIS,
	//所以需要一个以窗口指针作为参数的构造函数
	MyFrameListener(Ogre::RenderWindow *win)
	{
		//OIS使用参数列表来初始化,同样需要一个字符串形式的窗口句柄来构建参数列表;
		//创建三个必要的变量来保存数据
		OIS::ParamList parameters;
		unsigned int windowHandle = 0;
		std::ostringstream windowHandleString;
		//获得RenderWindow的句柄并转换它为一个字符串
		win->getCustomAttribute("WINDOW",&windowHandle);//得到当前渲染窗口在系统中的句柄
		windowHandleString<<windowHandle;
		//使用键值"WINDOW"来添加字符串类型的句柄到参数表
		parameters.insert(std::make_pair("WINDOW",windowHandleString.str()));
		//使用参数表来创建InputManager
		_InputManager = OIS::InputManager::createInputSystem(parameters);
		//用InputManager来创建keyboard
		_Keyboard = static_cast<OIS::Keyboard *>(_InputManager->createInputObject(OIS::OISKeyboard,false));
	}
	~MyFrameListener()
	{
		_InputManager->destroyInputObject(_Keyboard);
		OIS::InputManager::destroyInputSystem(_InputManager);
	}
	//创建一个新的frameStarted函数,来获取当前键盘状态,如果按下了Escape,返回false,反之,返回true
	bool frameStarted(const Ogre::FrameEvent &evt)
	{
		_Keyboard->capture();
		if(_Keyboard->isKeyDown(OIS::KC_ESCAPE))
		{
			return false;
		}
		return true;
	}
};

//创建有两个私有的指针的MyApplication类,一个指向Ogre 3D SceneManager,另一个指向Root类
class MyApplication
{
private:
	Ogre::SceneManager *_sceneManager;
	Ogre::Root *_root;
	//类的主体需要一个指针来存储FrameListener
	MyFrameListener *_listener;
	//程序需要知道是否要一直循环下去,所以添加一个bool类型的私有成员变量以记录成员的状态
	bool _keepRunning;
public:
	//创建一个loadResources()函数,这个函数加载resources_d.cfg配置文件
	void loadResources()
	{
		Ogre::ConfigFile cf;
		cf.load("resources_d.cfg");
		//遍历配置文件的所有区段
		Ogre::ConfigFile::SectionIterator sectionIter = cf.getSectionIterator();
		Ogre::String sectionName,typeName,dataname;
		while(sectionIter.hasMoreElements())
		{
			//获取区段名称和设置迭代器
			sectionName = sectionIter.peekNextKey();
			Ogre::ConfigFile::SettingsMultiMap *settings = sectionIter.getNext();
			Ogre::ConfigFile::SettingsMultiMap::iterator i;
			//迭代所有的设置并添加每个资源
			for(i = settings->begin(); i != settings->end(); ++i)
			{
				typeName = i->first;
				dataname = i->second;
				Ogre::ResourceGroupManager::getSingleton().addResourceLocation(dataname,typeName,sectionName);
			}
			Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
		}
	}
	void createScene()
	{
		Ogre::Entity *ent = _sceneManager->createEntity("Sinbad.mesh");
		_sceneManager->getRootSceneNode()->attachObject(ent);
	}
	//创建一个startup()函数,使用plugins.cfg创建一个Ogre 3D Root类的实现
	int startup()
	{
		_root = new Ogre::Root("plugins_d.cfg");
		//显示配置窗口当用户退出时,返回-1并关闭程序
		if(!_root->showConfigDialog())
		{
			return -1;
		}
		//创建RenderWindow和SceneManager
		Ogre::RenderWindow *window = _root->initialise(true,"Ogre 3D Beginners Guide");
		_sceneManager = _root->createSceneManager(Ogre::ST_GENERIC);
		//创建一个摄像机和视口
		Ogre::Camera *camera = _sceneManager->createCamera("Camera");
		camera->setPosition(Ogre::Vector3(0.0f,0.0f,50.0f));
		camera->lookAt(Ogre::Vector3(0.0f,0.0f,0.0f));
		camera->setNearClipDistance(5);
		Ogre::Viewport *viewport = window->addViewport(camera);
		camera->setAspectRatio(Ogre::Real(viewport->getActualWidth())/Ogre::Real(viewport->getActualHeight()));
		//调用函数来加载资源并创建一个场景,最后,Ogre3D可以开始渲染了
		loadResources();
		createScene();
		_listener = new MyFrameListener(window);
		_root->addFrameListener(_listener);
		//_root->startRendering();
		return 0;
	}
	MyApplication()
	{
		_sceneManager = NULL;
		_root = NULL;
		_listener = NULL;
	}
	~MyApplication()
	{
		delete _root;
		delete _listener;
	}
	//添加一个新的称为renderOneFrame的函数,这个函数调用了root实例的renderOneFrame函数,
	//并且可以把返回值保存在_keepRunning成员变量中。在调用这个之前,添加一个函数在处理
	//所有的窗口事件
	void renderOneFrame()
	{
		Ogre::WindowEventUtilities::messagePump();//外部事件的响应,用来接收系统事件,
		//比如激活当前窗口,关闭,窗口变化等等,处理程序之间的消息事件
		_keepRunning = _root->renderOneFrame();
	}
	//添加一个获取_keepRunning成员变量的函数
	bool keepRunning()
	{
		return _keepRunning;
	}
};

int main(void)
{
	MyApplication app;
	app.startup();
	//添加一个while循环到主函数中,只要keepRunning函数返回true,循环将一直进行下去。再循环体里,
	//调用程序的renderOneFrame函数
	while(app.keepRunning())
	{
		app.renderOneFrame();
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值