建立自己的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文件中定义函数,代码如下
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程序的运行过程就是这样。