CEGUI是一个2D的UI渲染库。它支持大部分渲染引擎,不仅支持Ogre,也同样的支持OpenGL和Irrlicht引擎。它同时又是基于XML脚本文件格式应用的一个重量级库。当然,你可以在你的代码中定义所有的UI信息,但如果你在使用XML文件进行UI文件的定义也会非常简单,CEGUI也能够在运行时对这些XML文件进行读取和分析。CEGUI本身有一些例子和支持这些例子的资源。你可以看一看这些例子中是如何使用XML脚本文件,如何进行UI单元的定义的。也可以去看看例子中的 .layout 文件和 .xsd文件,这些会对你学习CEGUI有所帮助。当然,你可能需要在自己的程序中自定义一些UI组件。
UI的渲染
CEGUI在一些四方形网格上渲染它的UI单元,并将它们渲染到一个“屏幕空间”中。那么,将意味着这些承载着UI单元的四方形网格的整个绘制过程是完全不接受任何视角变换和投影变换影响的。这一条是任何2D UI系统运行的基准方法。CEGUI通过“OgreGUIRenderer”类与Ogre进行结合。这个类所在文件存放在Ogre的“Samples”文件夹下,然而却定义在“CEGUI”命名空间内。OgreGUIRenderer简单的取得了CEGUI中的一些绘制命令,并将这些命令转译成Ogre中的网格和材质数据,并将其放置到’层渲染队列(Overlay render queue)’中,通过这种手段Ogre就可以对其进行绘制了,同时,这样可以使UI在我们的渲染场景中永远处于近屏顶端。在我们的程序代码中,我们除了提供一个OgreGUIRenderer类的实体对象给CEGUI,其他的渲染相关部分我们不用操心。
输入系统和CEGUI
CEGUI本身没有任何的输入处理,如果我们程序中需要对不同的输入数据进行处理,那么我们必须为它提供整套的输入事件处理系统。这样做有一些好处。其中之一就是你不需要担心UI库会和你的应用程序争夺输入数据的处理权。此外,你可以自由的完全的把CEGUI从“输入循环”中移除出来,并不给它任何输入数据信息。你同样也不需要依赖于任何的第三方IO库和API,你可以自由的选择输入设备:OIS,SDL,DirectInput,Win32, XWindows作为输入库都可以,完全的取决于你。在本文中我们将使用OIS做为CEGUI的输入处理系统。
CEGUI数据文件
说起来,你可能能够在代码中完美的进行你的UI层的定义。但是用以下几种XML文件做为CEGUI的配置方法将会更加简单和高效。这些文件包括”scheme”, ”looknfeel”, ”layout”, ”imagesets”和CEGUI显示使用的文字”font”。 ?Scheme 定义着在同一个配置下不同的有效UI元件。例如. 我们程序中需要使用的一些按钮Buttons,下拉选菜单ListBoxes等等UI元件都能够在 .scheme 格式的文件中找到。 ?Look-And-Feel 定义着每个需要显示的UI元件的各种属性,包括了它的纹理,颜色,状态属性等。我们可以查看 .looknfeel文件。 ?Layout 定义了UI元件的父层级关系,位置,大小等与其他UI元件可能联系到的属性。我们可以查看 .layout 文件。 ?Imageset 定义了一种配置下的纹理,UV值等信息,我们可以查看 .imageset 文件。 ?font 显而易见。CEGUI需要知道我们POST http://blog.hfut.edu.cn/spacecp.php?action=spacefut.edu.cn/spacecp.php?action=spacegui.zip文件,你能够在里面找到上述所有文件的一些例子。认真查看每个类型的文件,虽然它们都是XML格式的文件,注意它们各自的格式以及包含了UI的什么信息。如果你依旧看不明白,可以去CEGUI的官方站点看看对它们功能的描述。本文将使用” TcharazLookSkin”这套配置。(Tcharaz是创建这个配置的一个人名,他创建了这个配置的.scheme, .look-and-feel, .texture和.imageset)
编码
好了,介绍的足够多了,现在我们看看实际编码。如果你坚持看了Ogre的这系列教程例子,你应该很熟悉如何创建一个按下Esc就退出的Ogre渲染窗口的框架了。在这个例子中,我们用一种主菜单的面版来替代以前的空窗口框架。这个主菜单包含三个按钮,但是我只打算让Quit这个按钮进行事件响应处理。我们除了使用ESC键之外,我们还可以通过Quit按钮退出本程序。不知道通过之前的讲解你是否能明白,CEGUI通过别的输入系统获得用户输入事件后能够将其事件都反映出来,就如本例,我们可以在自己的代码中对鼠标点击事件做出响应。一会你从代码中就能轻易的明白如何在自己的代码中Hook到 CEGUI的事件行为。注意:我们下面的代码操作都是基于C++的,如果你对希望在脚本(例如Lua或其他脚本引擎)中Hook到CEGUI的事件行为,希望你能到CEGUI官方去看看如何做到。
数据
首先,我们来看一下CEGUI中至关重要的数据文件---Layout文件。你可以通过CEGUI的Layout编辑器来生成和编辑该文件,但是在本例中下面这个XML格式的 .layout 文件完全是我手动编写出来的,实际上很简单。在Ogre的Debug文件夹下resource目录下有个压缩包是gui.zip,你在里面会发现一个文件叫”Katana.layout”,下面是该文件的全部内容:
<?xml version="1.0" ?> <GUILayout> <Window Type="TaharezLook/FrameWindow" Name="Main">
<Property Name="UnifiedAreaRect" Value="{{0.0,0},{0.0,0},{1.0,0},{1.0,0}}" />
<Property Name="FrameEnabled" Value="false" />
<Property Name="TitlebarEnabled" Value="false" />
<Property Name="CloseButtonEnabled" Value="False" />
<Window Type="TaharezLook/Button" Name="cmdQuit"> <Property Name="Text" Value="Quit" />
<Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.7,0},{0.6,0},{0.77,0}}" />
</Window> <Window Type="TaharezLook/Button" Name="cmdOptions">
<Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.6,0},{0.6,0},{0.67,0}}" />
<Property Name="Text" Value="Options" /> </Window> <Window Type="TaharezLook/Button" Name="cmdInstantAction">
<Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.5,0},{0.6,0},{0.57,0}}" />
<Property Name="Text" Value="Instant Action" /> </Window> </Window> </GUILayout>
你在浏览这些代码的时候,首先可能发现里面那些神秘的数字。在CEGUI 0.5.x版本中,UI元件需要定义的是UI元件的绝对尺寸大小。而在这个layout文件中,我们使用的是统一的相对尺寸范围。Value =”” 中定义了元件的左,右,上,下点的位置。但这个位置我们既可以定义这些点的绝对位置,也可以是定义这些点针对其父容器UI元件的相对位置。例如,下面这个UI元件的区域定义:
{{0.4,0},{0.5,0},{0.6,0},{0.57,0}}
这些数值告诉了CEGUI,这个UI元件在其上一层元件容器中的相对位置和大小。如本例,这个元件左上角将距离其上一层元件容器的左上角的右偏移距离为 (0.4 * 上一层元件容器宽度),这个元件左上角将距离其上一层元件容器的左上角的下偏移距离为 (0.5 * 上一层元件容器高度)。该UI元件宽度将为((0.6 ? 0.4)* 上一层元件宽度 )大小,高度将为( (0.57 ? 0.5) * 上一层元件告诉 )大小。那么,那些参数中的”0”是什么意义呢?如果你想同时指定UI元件的绝对象素位置的话,可以把这些”0”替换为该元件的象素位置。所以这就意味着,你能够根据自己喜好,为UI元件设置相对坐标或者象素的绝对坐标。我想不起来指定象素绝对坐标时这些数值的意义,如果谁看到本例并且知道这些绝对坐标数值意义的话,请帮助补充到本文中。:)不过,如果谁是曾经做过网页的话,将会非常熟悉这些绝对坐标的意义和顺序,因为这俩完全是一个东西。 (补充:译者推荐在游戏制作中使用相对坐标,这样的话在对窗口缩放或对单一UI窗口缩放时会容易的避免一些问题。) 在这个Layout文件中,第一行告诉CEGUI,我们想创建一个顶层的窗口”Main”,而且这个窗口大小是占满整个程序显示区-----它的相对宽高是(1.0 - 0.0 )。我们不希望看到它的标题栏,也不希望看到这个顶层窗口右上边的关闭按钮和其边框。于是,下面我们设置他们的Value为false。(这三项是 FrameWindow框架窗口默认存在的捆绑控件)。接下来,我们在屏幕中放置三个按钮----这样的话,在我们运行程序的时候将会从上到下见到 “Instant Action”“Options”“Quit”三个按钮。按钮控件的名称属性是非常重要的,这是我们在代码中获取该控件行为的唯一标识,这点我们一会就会见到。
接下来,看编码
我将要重点说明在代码中整合CEGUI时有什么更变。首先,在main.cpp中,需要额外加一些头文件。
// 需要能够创建CEGUI渲染接口
1. include "OgreCEGUIRenderer.h"
// CEGUI 的头文件
1. include "CEGUISystem.h"
2. include "CEGUIInputEvent.h"
3. include "CEGUIWindow.h"
4. include "CEGUIWindowManager.h"
5. include "CEGUISchemeManager.h"
6. include "CEGUIFontManager.h"
7. include "elements/CEGUIFrameWindow.h"
我们将创建GUI渲染器的一个实例,所以我们需要包含OgreCEGUIRenderer.h这个头文件。你可以在OgreSDK或Ogre源代码的Samples/include文件夹下找到该文件。CEGUI的头文件能够在OgreSDK的include/CEGUI文件夹下找到这些文件。(在安装OgreSDK时这些通常被自动设置为默认包含头文件目录了)。如果你在编译时候这里出错,请保证同时添加了包含了这两个目录” include/CEGUI”和”include”。你也可以不包含” elements/CEGUIFrameWindow.h”,它仅仅是老版本的CEGUI中残留的一个习惯,新版本的CEGUI中已经可以不包含它了。不过包含的话也是没什么坏处的。
初始化CEGUI
Main.cpp
// 在有一个有效的场景管理器和Windows窗口后,我们可以创建一个GUI渲染器
CEGUI::OgreCEGUIRenderer* pGUIRenderer = new CEGUI::OgreCEGUIRenderer {
Window, // 这个渲染目标窗口应该在之前创建好,CEGUI将会在这个窗口上进行渲染。
Ogre::RENDER_QUEUE_OVERLAY, // CEGUI将会在这个渲�
评论0