OGRE+CEGUI游戏教程(1)----GUI框架

转载 2012年03月26日 14:03:58

 转载文章请注明出处:http://blog.csdn.net/pizzazhang 

  源码和可执行程序链接http://code.google.com/p/pizzaprojects/downloads/list

  今天起我会陆续更新一些原创的Ogre结合CEGUI的游戏教程。想到什么就做什么,没有固定的内容,不过基本是游戏里可以用到的。 

  请先确保学习完了Ogre Wiki上的基础和中级教程后再来讨论这里的教程。因为一些基础的Ogre知识这里不会多做解释。

  今天先建立一个用来演示的框架。其中我们已经有了BaseFramework框架,这个框架里已经帮你弄好了一些资源、场景管理器等设置,当然还有一个Overlay,但我们的GUI不打算使用Overlay,所以我们需要一个GUI框架。所以赶紧来做一个GUI框架使用吧!

 

MyGUISystem.h

  1. class MyGUISystem  
  2. {  
  3. public:  
  4.     virtual ~MyGUISystem();  
  5.     //把OIS的鼠标ID转换成CEGUI的鼠标ID  
  6.     static CEGUI::MouseButton convertButton(OIS::MouseButtonID buttonId);  
  7.     //销毁资源  
  8.     bool destroy();  
  9.     //初始化CEGUI, 必须在RenderWindow创始后初始, 只在第一次调用有效  
  10.     bool init();  
  11.     //GUI更新  
  12.     void update(float timeSinceLastFrame);  
  13.     /** 
  14.     根据图片构造Imageset 
  15.     params: 
  16.     @name       创建的Imageset名称, 全局唯一 
  17.     @filename   创建Imageset的图片名称 
  18.     */  
  19.     static void createImageset(const std::string& name, const std::string& filename);  
  20.     //加载layout  
  21.     bool loadLayout(const std::string& layoutName);  
  22.     //得到指定名称的窗口  
  23.     inline CEGUI::Window* getWindow(const std::string& windowName)   
  24.     {  
  25.         return getGUIWindowManager()->getWindow(windowName);   
  26.     }  
  27.     //销毁指定名称的窗口  
  28.     bool destroyWindow(const std::string& windowName);  
  29.     /* 
  30.     *   给指定名称的窗口设定属性 
  31.     params: 
  32.     @windowName 窗口名称 
  33.     @key            XML标签  key值 
  34.     @value          XML标签  value值 
  35.     */  
  36.     static void setProperty(const std::string& windowName, const std::string& key,   
  37.         const std::string& value);  
  38.     /** 
  39.     注册CEGUI控件事件 
  40.     params: 
  41.     @windowName     要注册事件的控件名称 
  42.     @eventName      注册的控件事件 
  43.     @subscriber     事件触发时的回调函数 
  44.     */  
  45.     static void subscribeEvent(const CEGUI::String& windowName,   
  46.         const CEGUI::String &eventName,   
  47.         const CEGUI::Event::Subscriber &subscriber);  
  48.     //得到窗口管理器,用来获取管理GUI的窗口对象的管理器  
  49.     inline CEGUI::WindowManager* getGUIWindowManager()  
  50.     {  
  51.         return CEGUI::WindowManager::getSingletonPtr();  
  52.     }  
  53.     // 注入CEGUI鼠标点击事件  
  54.     bool injectMouseButtonDown(CEGUI::MouseButton id)   
  55.     {  
  56.         return mGUISystem->injectMouseButtonDown(id);  
  57.     }  
  58.     bool injectMouseButtonUp(CEGUI::MouseButton id)   
  59.     {  
  60.         return mGUISystem->injectMouseButtonUp(id);   
  61.     }  
  62.     // 注入CEGUI鼠标移动事件  
  63.     bool injectMouseMove(float xRel, float yRel)  
  64.     {  
  65.         return mGUISystem->injectMouseMove(xRel, yRel);  
  66.     }  
  67.     //显示/隐藏GUI鼠标  
  68.     inline void showGUICursor(bool showCursor)  
  69.     {  
  70.         if(showCursor)  
  71.         {  
  72.             CEGUI::MouseCursor::getSingleton().show();  
  73.         }  
  74.         else  
  75.         {  
  76.             CEGUI::MouseCursor::getSingleton().hide();  
  77.         }  
  78.         //隐藏系统鼠标  
  79.         ShowCursor(false);  
  80.     }  
  81.     /* 
  82.     *   设置默认鼠标样式 
  83.     params: 
  84.     @schemeName 样式名称 
  85.     @mouseName      样式中的鼠标名称 
  86.     */  
  87.     inline void setDefaultMouseCursor(const std::string& schemeName, const std::string& mouseName)   
  88.     {  
  89.         CEGUI::System::getSingleton().setDefaultMouseCursor(schemeName, mouseName);  
  90.         CEGUI::MouseCursor::getSingleton().setImage(mGUISystem->getDefaultMouseCursor());  
  91.     }  
  92. public:  
  93.     /* 
  94.     *   单件实例方法 
  95.     */  
  96.     static MyGUISystem* getSingletonPtr()  
  97.     {  
  98.         if(ms_singleton == NULL)  
  99.         {  
  100.             ms_singleton = new MyGUISystem;  
  101.         }  
  102.         return ms_singleton;  
  103.     }  
  104. private:  
  105.     //单件实例指针  
  106.     static MyGUISystem* ms_singleton;  
  107. private:  
  108.     CEGUI::OgreRenderer* mGUIRender;  
  109.     CEGUI::System*       mGUISystem;  
  110. private:  
  111.     /* 
  112.     *   私有化实例函数,实现单件 
  113.     */  
  114.     MyGUISystem()  
  115.         :mGUIRender(0), mGUISystem(0)  
  116.     {}  
  117.     MyGUISystem(const MyGUISystem&);  
  118.     MyGUISystem& operator=(const MyGUISystem&);  
  119. };  

这里采用一个简单的单价模式来实现GUI系统。 其中最重要的方法是 loadLayout,createImageset , setProperty和subscribeEvent。

 loadLayout方法主要是载入layout,但是传入的参数是指定layout的根窗口,把它作为GUISheet进行显示。

createImageset是载入图片资源让CEGUI转化为纹理供有StaticImage的地方使用。

setProperty主要用来设置窗口的属性,尤其是StaticImage的设置。

subscribeEvent用来注册GUI事件。

 

下面是实现文件:

MyGUISystem.cpp

  1. #include "MyGUISystem.h"  
  2. #include <cassert>  
  3. //-----------------------------------------------------------------------------  
  4. MyGUISystem* MyGUISystem::ms_singleton = NULL;  
  5. //-----------------------------------------------------------------------------  
  6. MyGUISystem::~MyGUISystem()  
  7. {  
  8.     destroy();  
  9. }  
  10. //-----------------------------------------------------------------------------  
  11. bool MyGUISystem::destroy()  
  12. {  
  13.     CEGUI::OgreRenderer::destroySystem();  
  14.     delete ms_singleton;  
  15.     ms_singleton = 0;  
  16.     return true;  
  17. }  
  18. //-----------------------------------------------------------------------------  
  19. CEGUI::MouseButton MyGUISystem::convertButton(OIS::MouseButtonID buttonId)  
  20. {  
  21.     switch(buttonId)  
  22.     {  
  23.     case OIS::MB_Left:  
  24.         return CEGUI::LeftButton;  
  25.     case OIS::MB_Right:  
  26.         return CEGUI::RightButton;  
  27.     case OIS::MB_Middle:  
  28.         return CEGUI::MiddleButton;  
  29.     default:  
  30.         return CEGUI::LeftButton;  
  31.     }  
  32. }  
  33. //-----------------------------------------------------------------------------  
  34. bool MyGUISystem::init()  
  35. {  
  36.     if(!mGUIRender)  
  37.     {  
  38.         mGUIRender = &CEGUI::OgreRenderer::bootstrapSystem();  
  39.         mGUISystem = CEGUI::System::getSingletonPtr();  
  40.         //加载GUI主题, 设置默认参数  
  41.         CEGUI::Imageset::setDefaultResourceGroup("Imagesets");  
  42.         CEGUI::Font::setDefaultResourceGroup("Fonts");  
  43.         CEGUI::Scheme::setDefaultResourceGroup("Schemes");  
  44.         CEGUI::WidgetLookManager::setDefaultResourceGroup("LookNFeel");  
  45.         CEGUI::WindowManager::setDefaultResourceGroup("Layouts");  
  46.         CEGUI::SchemeManager::getSingleton().create("TaharezLook.scheme");  
  47.         CEGUI::FontManager::getSingleton().create("SimHei-14.font");  
  48.         mGUISystem->setDefaultFont("SimHei-14");  
  49.         /* 
  50.          *  此处设置图片资源(Imageset) 
  51.          */  
  52.         //设置默认鼠标样式  
  53.         setDefaultMouseCursor("TaharezLook""MouseArrow");  
  54.         //设置GUI鼠标是否可见  
  55.         showGUICursor(true);  
  56.         return true;  
  57.     }  
  58.     return false;  
  59. }  
  60. //-----------------------------------------------------------------------------  
  61. void MyGUISystem::update(float timeSinceLastFrame)  
  62. {  
  63.     mGUISystem->injectTimePulse(timeSinceLastFrame);  
  64. }  
  65. //-----------------------------------------------------------------------------  
  66. void MyGUISystem::createImageset(const std::string& name, const std::string& filename)  
  67. {  
  68.     CEGUI::ImagesetManager::getSingleton().createFromImageFile(name, filename);  
  69. }  
  70. //-----------------------------------------------------------------------------  
  71. bool MyGUISystem::loadLayout(const std::string& layoutName)  
  72. {  
  73.     CEGUI::Window *guiSheet;  
  74.     // 检测给定layout的文件是否加载,没有加载则加载  
  75.     if(!getGUIWindowManager()->isWindowPresent(layoutName))  
  76.     {  
  77.         // 从 .layout脚本文件读取一个UI布局设计,并将其放置到GUI资源组中。  
  78.         guiSheet = getGUIWindowManager()->loadWindowLayout(layoutName + ".layout");  
  79.     }  
  80.     else  
  81.     {     
  82.         // 如果已经加载则直接显示  
  83.         guiSheet = getGUIWindowManager()->getWindow(layoutName);  
  84.     }  
  85.     // 接下来我们告诉CEGUI显示哪份UI布局。当然我们可以随时更换显示的UI布局。  
  86.     mGUISystem->setGUISheet(guiSheet);  
  87.     //显示UI布局  
  88.     guiSheet->show();  
  89.     return true;  
  90. }  
  91. //-----------------------------------------------------------------------------  
  92. bool MyGUISystem::destroyWindow(const std::string& windowName)  
  93. {  
  94.     getGUIWindowManager()->destroyWindow(windowName);  
  95.     return true;  
  96. }  
  97. //-----------------------------------------------------------------------------  
  98. void MyGUISystem::subscribeEvent(const CEGUI::String& windowName,  
  99.     const CEGUI::String &eventName, const CEGUI::Event::Subscriber &subscriber)  
  100. {  
  101.     CEGUI::WindowManager::getSingleton().getWindow(CEGUI::String(windowName))  
  102.         ->subscribeEvent(eventName,subscriber);  
  103. }  
  104. //-----------------------------------------------------------------------------  
  105. void MyGUISystem::setProperty(const std::string& windowName,   
  106.     const std::string& key, const std::string& value)  
  107. {  
  108.     MyGUISystem::getSingletonPtr()->getWindow(windowName)->setProperty(key, value);  
  109. }  
  110. //-----------------------------------------------------------------------------  

update中我们让GUI系统更新时间,如果你需要实现GUI的动画效果,那么这个方法必须在Ogre的每帧进行调用。

在init中我们设置了GUI的一些默认资源,其中的字体我使用的是黑体14号。这是一个中文字体,CEGUI本身是使用UTF-8编码的,那么理论上是可以显示中文的。但是还需要一些小小的步骤才行。

 

CEGUI中显示中文的步骤:

1. 将编辑好的layout文件使用VC Studio打开(不要使用记事本),然后在文件->高级保存选项中把文件保存为UTF-8。

2.从WINDOW/Fonts文件夹中找一个中文字体的文件, 比如我使用的simhei.ttf

3.新建一个xml字体文件, 比如SimHei-14.Font,然后写上:

[html] view plaincopy
  1. <?xml version="1.0" ?>  
  2. <Font Name="SimHei-14" Filename="simhei.ttf" Type="FreeType" Size="14" NativeHorzRes="1024" NativeVertRes="768" AutoScaled="true"/>  

Name就是我们需要在程序中使用的字体名。

4.之后可以直接在layout文件中 有Text属性的地方使用中文, 如果要在代码中设置Text的中文,需要这么使用:

CEGUI::String str = (CEGUI::utf8*)Ogre::UTFString(L"你需要的中文").asUTF8_c_str()

 

这个GUI框架的使用很简单, 在Ogre窗口配置好后,使用MyGUISystem::getSingletonPtr()->init()对GUI系统初始化, 在Ogre渲染循环里对GUI系统update, 然后就可以使用了。

 

下篇文章会使用这个框架做一个游戏里要找NPC对话, 点击NPC后镜头与NPC拉近,然后弹出GUI对话框, 如果要退出游戏按ESC弹出退出的GUI菜单,并且带有GUI的动画效果。

CEGUI教程---教你如何使用CEGUI库

  • 2010年05月14日 15:06
  • 318KB
  • 下载

CEGUI-专用游戏界面开发库

转载请注明原帖地址:http://www.unpack.cn/thread-62011-1-1.html本文来自:UPK软件安全社区 作者:铁打英雄 下载:http://www.cegui.org.u...
  • kenkao
  • kenkao
  • 2011年03月18日 09:11
  • 7268

【CEGUI】CEGUI入门篇之初始化(一)

以下内容翻译自http://static.cegui.org.uk/docs/0.8.7/rendering_tutorial.html1、简介初始化CEGUI时,不管其渲染API或渲染引擎是什么,都...
  • iEearth
  • iEearth
  • 2017年04月13日 07:06
  • 1096

CEGUI详细深入完整教程

  • 2016年10月02日 22:29
  • 14KB
  • 下载

OGRE+CEGUI游戏教程(3)----角色创建

转载请注明出处:http://blog.csdn.net/pizzazhang   源码和可执行程序链接http://code.google.com/p/pizzaprojects/downlo...
  • aiversonwk
  • aiversonwk
  • 2012年03月26日 14:06
  • 2136

CEGUI 输入法窗口实现

大部分网络游戏,都会有聊天框。当我们使用输入法输入文字时,会发现我们原本输入法窗口(如搜狗输入法窗口,或者微软,QQ拼音输入法窗口)不在游戏窗口内,而在游戏窗口窗口外头。另外,当我们游戏真全屏(非窗口...
  • xujiezhige
  • xujiezhige
  • 2013年09月03日 11:33
  • 7047

网游UI解决方案的选择(CEGUI/MYGUI/Hikari/Scaleform/...)

网游UI解决方案的选择 作者 鸣·铭 转载请注明出自http://www.mobilegamebase.com     由于新项目动工,UI方面需要确定方向,所以最近纠结于各种解决方案的选...
  • pizi0475
  • pizi0475
  • 2011年04月14日 10:34
  • 2729

OGRE 引擎官方基础教程 (七) OGRE 和 CEGUI

版本要求 OGRE: >= 1.7.0CEGUI: >= 0.7.0 修改Basic Tutorial 7类定义如下所示 BasicTutorial7 header #includ...
  • cfzjxz
  • cfzjxz
  • 2013年05月28日 10:58
  • 2710

OGRE+CEGUI游戏教程(2)----NPC对话演示

转载请注明出处:http://blog.csdn.net/pizzazhang   源码和可执行程序链接http://code.google.com/p/pizzaprojects/download...
  • xionghaoaizhangruyun
  • xionghaoaizhangruyun
  • 2011年10月30日 02:37
  • 1670

CEGUI入门

cegui渲染入门: 至少需要3步,才可以使cegui运行起来1 创建CEGUI::Renderer对象2 创建CEGUI::System对象3 调用渲染函数of course,实现真正的游戏GUI,...
  • J_hui
  • J_hui
  • 2010年05月10日 14:15
  • 1844
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OGRE+CEGUI游戏教程(1)----GUI框架
举报原因:
原因补充:

(最多只允许输入30个字)