建立自己的Ogre程序

一直以来都是使用ExampleApplication.h来写程序,现在来看看它到底有什么神奇的地方。

  首先,我们新建一个win32空项目

  然后配置环境

  最后新建define.cpp、define.h、main.cpp

 具体过程如下

第一,在define.h中包含头文件,这里需要Orge.h文件,然后添加如下代码

#include "Ogre.h"

class MyApplication

{

public:

MyApplication();

~MyApplication();

void go();

protected:

bool setup();//设置环境

void setupResources();//设置资源

bool configure();//配置窗口

void chooseSceneManager();//选择场景

void createCamera();//创建摄像机

void createViewports();//创建视口

void loadResources();//加载资源

void createScene();//创建场景

void renderOneFrame();

private:

Ogre::Root*mRoot;//根节点

Ogre::RenderWindow*mWindow;//渲染窗口

Ogre::SceneManager*mSceneMgr;//场景管理器指针

Ogre::Camera*mCamera;//摄像机

bool mShutDowm;

};

第二,在define.cpp文件中定义函数,代码如下

 #include "define.h"

 MyApplication::MyApplication()//构造函数
{
mRoot = NULL;
mWindow = NULL;
mSceneMgr = NULL;
mCamera = NULL;
mWindow = NULL;
mShutDowm = false;
}
MyApplication::~MyApplication()//析构函数
{
if (mRoot)
{
delete mRoot;
}
}
bool MyApplication::setup()
{
mRoot = new Ogre::Root("plugins_d.cfg");
setupResources();
if (!configure())
{
return false;
}
chooseSceneManager();
createCamera();
createViewports();
loadResources();
createScene();
return true;
}
void MyApplication::setupResources()
{
// 加载资源,ConfigFile类是Ogre中用来读取和解析脚本使用的格式的
Ogre::ConfigFile cf;
cf.load("resources_d.cfg");
//循环遍历资源
Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();// 获取迭代器
Ogre::String secName, typeName,archName;
while (seci.hasMoreElements())//组名
{
secName = seci.peekNextKey();
Ogre::ConfigFile::SettingsMultiMap *settings =seci.getNext();
Ogre::ConfigFile::SettingsMultiMap::iterator i;
for (i =settings->begin();i != settings->end(); ++i)
{
typeName = i->first;//键名
archName = i->second;//键值
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName,typeName, secName);
}
}
}
bool MyApplication::configure()
{
if (!mRoot->showConfigDialog())//是否显示配置窗口
{
return false;
}
mWindow = mRoot->initialise(true,"IMedia Project");
return true;
}
void MyApplication::chooseSceneManager()
{
mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);
}
void MyApplication::createCamera()
{
mCamera = mSceneMgr->createCamera("MyCamera");
mCamera->setPosition(Ogre::Vector3(,,));
mCamera->lookAt(Ogre::Vector3(,,-));
mCamera->setNearClipDistance();
}
void MyApplication::createViewports()
{
Ogre::Viewport*vp = mWindow->addViewport(mCamera);
vp->setBackgroundColour(Ogre::ColourValue(,,));
mCamera->setAspectRatio(Ogre::Real(vp->getActualWidth())/Ogre::Real(vp->getActualHeight()));
}
void MyApplication::loadResources()
{
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
}
void MyApplication::createScene()
{
Ogre::Entity*ent = mSceneMgr->createEntity("Sinbad.mesh");
mSceneMgr->getRootSceneNode()->attachObject(ent);
}
void MyApplication::go()
{
if (!setup())
return;
mRoot->startRendering();
}

  在setup函数中完成了一系列的初始化操作,其中的setupResource()函数解释一下,ConfigFile类是Ogre中用来读取和解析脚本使用的格式的,我们用它来加载资源脚本,load函数定义如下:

   void load(const String& filename, const String& separators = "\t:=", bool trimWhitespace = true);//使用文件名加载文件

  接下来的while循环是循环,while循环负责组名的遍历,内部的for循环负责键名与键值的读取。

第三,我们在main.cpp文件中添加WinMain函数

 #include <windows.h>
#include "define.h" INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
{
MyApplication app;
app.go();
return ;
}

这里是我们所需要的最少的代码。如此就可以保证程序跑起来,但还需要继续改进。运行就可以看到结果。

现在我们试试把鼠标和键盘监听添加进去

第一添加新的父类,包含头文件OIS.h

class MyApplication:public Ogre::FrameListener,public OIS::KeyListener,public OIS::MouseListener

{

.......................

}

第二,添加成员函数以及成员变量

 Public:

 void createFrameListener(void);//创建帧监听器

 virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);//OGRE

 virtual bool keyPressed(const OIS::KeyEvent &arg);//ois key

 virtual bool keyReleased(const OIS::KeyEvent &arg);//key

 virtual bool mouseMoved( const OIS::MouseEvent &arg );//mouse

 virtual bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id );

 virtual bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id );

 Private:

 OIS::InputManager *minputManager;//输入管理器

 OIS::Mouse *mMouse;//鼠标

 OIS::Keyboard *mKeyboard;//键盘

第三,函数定义,虚函数并没有添加其他代码,你可以直接添加需要的动作

 void MyApplication::createFrameListener()
{
OIS::ParamList pl;
size_t windowHnd = ;
std::ostringstream windowHndStr;
mWindow->getCustomAttribute("WINDOW", &windowHnd);//获取自己定义的属性
windowHndStr << windowHnd;
pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
minputManager = OIS::InputManager::createInputSystem( pl );//依照系统环境创建一个合适的输入系统
mKeyboard=static_cast<OIS::Keyboard*>(minputManager->createInputObject( OIS::OISKeyboard, true ));//创建输入对象
mMouse = static_cast<OIS::Mouse*>(minputManager->createInputObject( OIS::OISMouse, true )); mMouse->setEventCallback(this);
mKeyboard->setEventCallback(this);
mRoot->addFrameListener(this); }
bool MyApplication::frameRenderingQueued(const Ogre::FrameEvent& evt)
{
if (mWindow->isClosed())
{
return false;
}
if (mShutDowm)
{
return false;
}
mKeyboard->capture();
mMouse->capture();
return true;
}
bool MyApplication::keyPressed(const OIS::KeyEvent &arg)
{
if (arg.key == OIS::KC_ESCAPE)
{
mShutDowm = true;
}
return true;
}
bool MyApplication::keyReleased(const OIS::KeyEvent &arg)
{
return true;
}
bool MyApplication::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
return true;
}
bool MyApplication::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
{
return true;
}
bool MyApplication::mouseMoved( const OIS::MouseEvent &arg )
{ return true;
}

代码解释:

这里看一下createFrameListener()函数,其中 ParamList是一个map类型,定义如下:

  typedef std::multimap<std::string, std::string> ParamList;

然后是创建输入对象,第一个参数指出了对象的类型

  Object* createInputObject( Type iType, bool bufferMode, const std::string &vendor = "");

 第四,记得在析构函数中清空对象

     if (minputManager)
{
minputManager->destroyInputObject(mKeyboard);
minputManager->destroyInputObject(mMouse);
OIS::InputManager::destroyInputSystem(minputManager);
minputManager = ;
}

  并在setup()函数中调用createFrameListener()函数

bool MyApplication::setup()
{
  .........
createFrameListener();//
return true;
}

 现在可以实现我们以前用ExampleApplication.h才能实现的功能了,ogre程序的运行过程就是这样。

 

最新文章

  1. 10、TV UI
  2. easyloader [easyui_1.4.2] 分析源码,妙手偶得之
  3. 【转】STL中mem_fun和mem_fun_ref的用法及区别
  4. UITableview 中获取非选中的cell
  5. nyoj 915 +-字符串
  6. python 语句,条件,循环
  7. 如何重写EF DBContext 获取链接字符串的方法
  8. 【python】运算优先级
  9. 强引用,弱引用,4种Java引用浅解(涉及jvm垃圾回收)
  10. JNA入门实例
  11. C++的发展,特点和源程序构成
  12. django学习之Model(四)MakingQuery
  13. 万众瞩目之下,ANGULAR 2终于正式发布啦!
  14. 衡量android开发者水平的面试问题-android学习之旅(91)
  15. Entity Framework Core系列之DbContext
  16. 用同一台PC的两个网口实现Iperf的server端和client端
  17. RT-thread-------------------信号量
  18. C#编程の模板
  19. vue 数组push元素 视图没更新
  20. href=&#39;#&#39; 和 href=&#39;###&#39;

热门文章

  1. linux设置history历史记录
  2. Spring IoC和AOP的介绍
  3. 卸载gitlab
  4. cms-帖子管理
  5. byte[] 中需要除去的特定 byte
  6. HDU3954 线段树(区间更新 + 点更新)
  7. C/C++语言补缺 宏- extern &quot;C&quot;-C/C++互调
  8. 2017.12.4 JavaWeb中EL表达式的运用
  9. Servlet 学习小结
  10. webpack4.x ,1基本项目构建 详解