这篇文章是对于Ogre3D中文网——基础教程六的补充,阅读前假定你已经对于Ogre和CEGUI有一定了解,并且阅读了《基础教程六》
如果你还不了解他们,你应该知道:
Ogre是一个3D图形渲染引擎;CEGUI是灵活的,可自由定义样式的GUI框架,他可以很好的支持Ogre,来绘制界面。
如果你对于Ogre和CEGUI感兴趣,以下将是很好的学习资源:
Ogre:http://www.ogre3d.org/
Ogre3D中文网:http://wiki.ogre3d.cn/wiki/
CEGUI:http://www.cegui.org.uk/
如果你和我一样也是从Ogre1.7开始接触这个食人魔,你也一定在学习的过程中遇到了很多麻烦,官方的入门教程还多数停留在Ogre 1.4的时代,面对这个更新如此频繁的怪物,很多守旧的东西早已不适用,如果你还在挖空心思想要了解这些经历了版本变迁过时的东西,如何能够应用到新的Ogre1.7+CEGUI0.7中,这篇文章或许对你会有帮助:D。另外,Ogre于4月28号刚刚更新到1.7.1,修正了1.7.0的诸多问题,继续学习前建议你更新到此版本。
结合使用Ogre1.7+CEGUI0.7,需要注意的问题:
1、你可能还在学习官方的Ogre1.4版本的教程,你会发现MouseMotionListener、MouseListener这些由Ogre自己实现的输入设备功能类早已被取消掉,原1.4版本的InputReader已由InputManager替代,键/鼠/手柄设备的输入功能可以由OIS来实现(这并非唯一途径,但,是官方极力推荐的),创建设备对象可以通过
mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject(OIS::OISKeyboard, true)); mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject(OIS::OISMouse, true)); mJoy = static_cast<OIS::JoyStick*>(mInputManager->createInputObject(OIS::OISJoyStick, true));
使用CEGUI时,还需通过System向CEGUI注入OIS事件对象,如:
CEGUI::System::getSingleton().injectMouseButtonDown(convertOgreButtonToCegui(id));
2、CEGUI0.7版本之前的Ogre渲染器CEGUI::OgreCEGUIRenderer已由CEGUI::OgreRender替代,并且创建Renderer和System的步骤已经被简化,原来的
mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000,mSceneMgr); mGUISystem = new CEGUI::System(mGUIRenderer);
现在可以简化为:
mGUIRenderer=&CEGUI::OgreRenderer::bootstrapSystem();
下面对于基础教程六的代码进行新版改造:
下面的场景中创建了一个简单的天空穹,用CEGUI绘制了一个按钮,点击按钮OK后退出应用程序
注意:为了能让Ogre找到CEGUI的相关素材资源,你需要将Ogre的resource.cfg资源文件中的CEGUI资源文件路径做相关添加
全部代码如下:
#include <CEGUIImageset.h> #include <CEGUISystem.h> #include <CEGUILogger.h> #include <CEGUISchemeManager.h> #include <CEGUIWindowManager.h> #include <CEGUIWindow.h> #include <elements/CEGUIPushButton.h> #include <RendererModules/Ogre/CEGUIOgreRenderer.h> #include <RendererModules/Ogre/CEGUIOgreResourceProvider.h> #include <RendererModules/Ogre/CEGUIOgreGeometryBuffer.h> //regular mem handler #include "ExampleApplication.h" CEGUI::MouseButton convertOgreButtonToCegui(int buttonID) { switch (buttonID) { case OIS::MB_Left: return CEGUI::LeftButton; case OIS::MB_Right: return CEGUI::RightButton; case OIS::MB_Middle: return CEGUI::MiddleButton; default: return CEGUI::LeftButton; } } class GuiFrameListener:public ExampleFrameListener,public OIS::MouseListener,public OIS::KeyListener { private: CEGUI::Renderer *mGUIRenderer; bool mShoutdownRequested; public: GuiFrameListener(RenderWindow* win,Camera* cam,CEGUI::Renderer* renderer) :ExampleFrameListener(win,cam,true,true),mGUIRenderer(renderer),mShoutdownRequested(false) { mMouse->setEventCallback(this); mKeyboard->setEventCallback(this); CEGUI::WindowManager* wmgr=CEGUI::WindowManager::getSingletonPtr(); CEGUI::Window* quitBtn=wmgr->getWindow((CEGUI::utf8*)"Quit"); quitBtn->subscribeEvent(CEGUI::PushButton::EventClicked,CEGUI::Event::Subscriber(&GuiFrameListener::quit,this)); } void requestShoutdown() { mShoutdownRequested=true; } bool quit(const CEGUI::EventArgs &evt) { mShoutdownRequested=true; return true; } bool frameStarted(const FrameEvent& evt) { if(mMouse) mMouse->capture(); if(mKeyboard) mKeyboard->capture(); return ExampleFrameListener::frameStarted(evt); } bool frameEnded(const FrameEvent& evt) { if(mShoutdownRequested) return false; else return ExampleFrameListener::frameEnded(evt); } bool mouseMoved(const OIS::MouseEvent &evt) { CEGUI::System::getSingleton().injectMouseMove(evt.state.X.rel,evt.state.Y.rel); return true; } bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id) { CEGUI::System::getSingleton().injectMouseButtonDown(convertOgreButtonToCegui(id)); return true; } bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id ) { CEGUI::System::getSingleton().injectMouseButtonUp(convertOgreButtonToCegui(id)); return true; } bool keyPressed(const OIS::KeyEvent &evt ) { if(evt.key==OIS::KC_ESCAPE) { mShoutdownRequested=true; return true; } CEGUI::System::getSingleton().injectKeyDown(evt.key); CEGUI::System::getSingleton().injectChar(evt.text); return true; } bool keyReleased(const OIS::KeyEvent &evt ) { CEGUI::System::getSingleton().injectKeyUp(evt.key); return true; } };class TutorialApplication:public ExampleApplication { public: CEGUI::OgreRenderer* mGUIRenderer; CEGUI::Window* mEditorGuiSheet; public: TutorialApplication() :mGUIRenderer(NULL),mEditorGuiSheet(NULL) { } ~TutorialApplication() { /**//*if(mEditorGuiSheet) { CEGUI::WindowManager::getSingleton().destroyWindow(mEditorGuiSheet); }*/ } protected: void createScene(void) { mGUIRenderer=&CEGUI::OgreRenderer::bootstrapSystem(); //设置日志 //Ogre::Log::setLogDetail(Ogre::LoggingLevel::LL_NORMAL); CEGUI::Logger::getSingleton().setLoggingLevel(CEGUI::LoggingLevel::Informative); CEGUI::SchemeManager::getSingleton().create("TaharezLook.scheme"); CEGUI::System::getSingleton().setDefaultMouseCursor("TaharezLook", "MouseArrow"); CEGUI::MouseCursor::getSingleton().setImage("TaharezLook","MouseMoveCursor"); CEGUI::System::getSingleton().setDefaultFont("DejaVuSans-10"); mEditorGuiSheet=(CEGUI::Window*)CEGUI::WindowManager::getSingleton().createWindow("DefaultWindow","Sheet"); CEGUI::System::getSingleton().setGUISheet(mEditorGuiSheet); CEGUI::PushButton* quitBtn=(CEGUI::PushButton*)CEGUI::WindowManager::getSingleton().createWindow("TaharezLook/Button",(CEGUI::utf8*)"Quit"); quitBtn->setPosition(CEGUI::UVector2(cegui_reldim(.35f), cegui_reldim(.45f))); quitBtn->setSize(CEGUI::UVector2(cegui_reldim(.15f), cegui_reldim(.05f))); quitBtn->setText((CEGUI::utf8*)"OK"); mEditorGuiSheet->addChildWindow(quitBtn); /**//* mEditorGuiSheet = CEGUI::WindowManager::getSingleton().loadWindowLayout((CEGUI::utf8*)"Tutorial Gui.xml"); CEGUI::System::getSingleton().setGUISheet(mEditorGuiSheet); CEGUI::PushButton* quitButton=(CEGUI::PushButton*)CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"Quit"); */ mSceneMgr->setAmbientLight(ColourValue(1, 1, 1)); mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8); } void createFrameListener(void) { mFrameListener = new GuiFrameListener(mWindow, mCamera, mGUIRenderer); mRoot->addFrameListener(mFrameListener); } }; #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #define WIN32_LEAN_AND_MEAN #include "windows.h" INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) #else int main(int argc, char **argv) #endif { // Create application object TutorialApplication app; try { app.go(); } catch( Exception& e ) { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL); #else fprintf(stderr, "An exception has occured: %s\n",e.getFullDescription().c_str()); #endif } return 0; }