ogre3D学习基础17 --- 如何手动创建ogre程序

建立自己的Ogre程序

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

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

  然后配置环境

  最后新建define.cppdefine.hmain.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文件中定义函数,代码如下

 1 #include "define.h"
 2 
 3 
 4 MyApplication::MyApplication()//构造函数
 5 {
 6     mRoot = NULL;
 7     mWindow = NULL;
 8     mSceneMgr = NULL;
 9     mCamera = NULL;
10     mWindow = NULL;
11     mShutDowm = false;
12 }
13 MyApplication::~MyApplication()//析构函数
14 {
15     if (mRoot)
16     {
17         delete mRoot;
18     }
19 }
20 bool MyApplication::setup()
21 {
22     mRoot = new Ogre::Root("plugins_d.cfg");
23     setupResources();
24     if (!configure())
25     {
26         return false;
27     }
28     chooseSceneManager();
29     createCamera();
30     createViewports();
31     loadResources();
32     createScene();
33     return true;
34 }
35 void MyApplication::setupResources()
36 {
37     // 加载资源,ConfigFile类是Ogre中用来读取和解析脚本使用的格式的
38     Ogre::ConfigFile cf;
39     cf.load("resources_d.cfg");
40     //循环遍历资源
41     Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();//  获取迭代器
42     Ogre::String secName, typeName,archName;
43     while (seci.hasMoreElements())//组名
44     {
45         secName = seci.peekNextKey();
46         Ogre::ConfigFile::SettingsMultiMap *settings =seci.getNext();
47         Ogre::ConfigFile::SettingsMultiMap::iterator i;
48         for (i =settings->begin();i != settings->end(); ++i)
49         {
50             typeName = i->first;//键名
51             archName = i->second;//键值
52             Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName,typeName, secName);
53         }
54     }
55 }
56 bool MyApplication::configure()
57 {
58     if (!mRoot->showConfigDialog())//是否显示配置窗口
59     {
60         return false;
61     }
62     mWindow = mRoot->initialise(true,"IMedia Project");
63     return true;
64 }
65 void MyApplication::chooseSceneManager()
66 {
67     mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);
68 }
69 void MyApplication::createCamera()
70 {
71     mCamera = mSceneMgr->createCamera("MyCamera");
72     mCamera->setPosition(Ogre::Vector3(0,0,80));
73     mCamera->lookAt(Ogre::Vector3(0,0,-300));
74     mCamera->setNearClipDistance(5);
75 }
76 void MyApplication::createViewports()
77 {
78     Ogre::Viewport*vp = mWindow->addViewport(mCamera);
79     vp->setBackgroundColour(Ogre::ColourValue(0,0,0));
80     mCamera->setAspectRatio(Ogre::Real(vp->getActualWidth())/Ogre::Real(vp->getActualHeight()));
81 }
82 void MyApplication::loadResources()
83 {
84     Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
85 }
86 void MyApplication::createScene()
87 {
88      Ogre::Entity*ent = mSceneMgr->createEntity("Sinbad.mesh");
89      mSceneMgr->getRootSceneNode()->attachObject(ent);    
90 }
91 void MyApplication::go()
92 {
93     if (!setup())
94         return;
95     mRoot->startRendering();
96 }

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

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

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

 

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

1 #include <windows.h>
2 #include "define.h"
3 
4 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
5 {
6     MyApplication app;
7     app.go();
8     return 0;
9 }

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

 

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

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

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

{

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

}

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

 1 Public:
 2 
 3 void createFrameListener(void);//创建帧监听器
 4 
 5 virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);//OGRE
 6 
 7 virtual bool keyPressed(const OIS::KeyEvent &arg);//ois key
 8 
 9 virtual bool keyReleased(const OIS::KeyEvent &arg);//key
10 
11 virtual bool mouseMoved( const OIS::MouseEvent &arg );//mouse
12 
13 virtual bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id );
14 
15 virtual bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id );
16 
17 Private:
18 
19 OIS::InputManager *minputManager;//输入管理器
20 
21 OIS::Mouse *mMouse;//鼠标
22 
23 OIS::Keyboard *mKeyboard;//键盘

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

 1 void MyApplication::createFrameListener()
 2 {
 3     OIS::ParamList pl;
 4     size_t windowHnd = 0;
 5     std::ostringstream windowHndStr;
 6     mWindow->getCustomAttribute("WINDOW", &windowHnd);//获取自己定义的属性
 7     windowHndStr << windowHnd;
 8     pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
 9     minputManager = OIS::InputManager::createInputSystem( pl );//依照系统环境创建一个合适的输入系统
10     mKeyboard=static_cast<OIS::Keyboard*>(minputManager->createInputObject( OIS::OISKeyboard, true ));//创建输入对象
11     mMouse = static_cast<OIS::Mouse*>(minputManager->createInputObject( OIS::OISMouse, true ));
12 
13     mMouse->setEventCallback(this);
14     mKeyboard->setEventCallback(this);
15     mRoot->addFrameListener(this);
16 
17 }
18 bool MyApplication::frameRenderingQueued(const Ogre::FrameEvent& evt)
19 {
20     if (mWindow->isClosed())
21     {
22         return false;
23     }
24     if (mShutDowm)
25     {
26         return false;
27     }
28     mKeyboard->capture();
29     mMouse->capture();
30     return true;
31 }
32 bool MyApplication::keyPressed(const OIS::KeyEvent &arg)
33 {
34     if (arg.key == OIS::KC_ESCAPE)
35     {
36         mShutDowm = true;
37     }
38     return true;
39 }
40 bool MyApplication::keyReleased(const OIS::KeyEvent &arg)
41 {
42     return true;
43 }
44 bool MyApplication::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
45 {
46     return true;
47 }
48 bool MyApplication::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
49 {
50     return true;
51 }
52 bool MyApplication::mouseMoved( const OIS::MouseEvent &arg )
53 {
54     
55     return true;
56 }

代码解释:

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

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

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

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

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

1     if (minputManager)
2     {
3         minputManager->destroyInputObject(mKeyboard);
4         minputManager->destroyInputObject(mMouse);
5         OIS::InputManager::destroyInputSystem(minputManager);
6         minputManager = 0;
7     }

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

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

 

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

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/songliquan/p/3335230.html