CEGUI 实践1
欢迎来到如何使用CEGUI 系列教程的第一篇。教程主要是通过代码进行讲解,我也会尝试使用少量的.layout 布局。你一旦清楚了如何在代码中使用各种部件(Widget),通过脚本来控制它们也就变得非常容易。
【请注意,我是一名Ogre3d 使用者,所以初始化设置是从如何引导并启动Ogre3d 开始。】
介绍CEGUI
首先请注意,CEGUI 使用了许多单件类。单件类,如果你没有使用过,可以理解为在代码中允许全局访问,且保证只创建一个类实例。下面是本例中将会用到的一些单件:
CEGUI::System - 大魔法师(译注:教父、大师,指统治级别)。有很多设置和获取缺省值的函数。
CEGUI::WindowManager - 管理CEGUI 所有窗口,用于创建或删除。
CEGUI::SchemeManager - 管理所有配色方案(Scheme)。
CEGUI::FontManager - 管理应用程序中用到的不同字体。
开始
我们从一些设置工作开始,第一件要做的事情就是建立系统并使其跑起来。因为我是一名Ogre 使用者,所以用Ogre 来构建可运行的系统。还有多种以其它渲染系统来启动的方法,参见这里:The Beginner Guide to Getting CEGUI Rendering 。
Ogre3d 方式演示如下:
包含必要的头文件
include "CEGUI.h"#include "RendererModules/Ogre/CEGUIOgreRenderer.h"
启动CEGUI
CEGUI::OgreRenderer* renderer = &CEGUI::OgreRenderer::bootstrapSystem();
【注意:bootstrapSystem 是一个比较新的方法,在CEGUI 0.7.1 中才引入。Wiki 上的一些例子还在使用旧版本的CEGUI ,你需要确认自己正在使用的版本。】
上面的代码创建一个Ogre3d 渲染实例用于Ogre3d和CEGUI,如果运行没问题的话,后面就不用再怎么管它了。它建立起用Ogre 渲染CEGUI 的关联。请注意:如果Ogre 是自动创建渲染窗口(大多如此)的话,你需要这么调用一下。假如你想手动创建一个Ogre3d 窗口,可以调用CEGUI::OgreRenderer::bootstrapSystem(Ogre::RenderWindow *) 重载版本。
还有一点值得一提的是bootstrapSystem() 会创建一个CEGUI::System 实例。这一点很重要,因为如果你已经创建过CEGUI::System ,这里就会抛出一个异常。
呃,来点脚本文件
上面我们就只调用了那一个函数,在进行更多CEGUI 处理之前,我们需要了解一些基础知识。
CEGUI 是一个高度脚本化的库,大量的内容素材定义在各种类型的.xml 文件中。首先提到的是配色方案(*.scheme),GUI 中用到的每个部件都定义在.scheme 文件中。它还可以包含后面提到的子脚本文件,后面的教程会对这些文件进行详细讲解。下面是一个你可能会碰到的示例:
<?xml version="1.0" ?><GUIScheme Name="TaharezLook">
<Imageset Filename="TaharezLook.imageset" />
<Font Filename="DejaVuSans-10.font" />
<LookNFeel Filename="TaharezLook.looknfeel" />
<WindowRendererSet Filename="CEGUIFalagardWRBase" />
<FalagardMapping WindowType="TaharezLook/Button" TargetType="CEGUI/PushButton" Renderer="Falagard/Button" LookNFeel="TaharezLook/Button" />
<FalagardMapping WindowType="TaharezLook/Checkbox" TargetType="CEGUI/Checkbox" Renderer="Falagard/ToggleButton" LookNFeel="TaharezLook/Checkbox" /></GUIScheme>
接着提到的脚本是布局文件(*.layout)。它也是xml 格式的文件,用于定义显示在屏幕上的窗口的布局。比如想创建一个聊天窗口,我们可能需要一个ChatWindow.layout 文件存放在某个地方。它应该描述窗口外观(大小,屏幕位置等),输入框和发送消息按钮的摆放位置。下面是一个演示.layout 文件的小例子:
<?xml version="1.0" encoding="UTF-8"?><GUILayout >
<Window Type="TaharezLook/FrameWindow" Name="ConsoleRoot" >
<Property Name="Text" Value="Chat Window" />
<Property Name="TitlebarFont" Value="DejaVuSans-10" />
<Property Name="TitlebarEnabled" Value="True" />
<Property Name="UnifiedAreaRect" Value="{{0.114991,0},{0.358182,0},{0.519469,0},{0.775455,0}}" />
<Window Type="TaharezLook/Editbox" Name="ConsoleRoot/EditBox" >
<Property Name="MaxTextLength" Value="1073741823" />
<Property Name="UnifiedAreaRect" Value="{{0.0201637,0},{0.787097,0},{0.694549,0},{0.957693,0}}" />
<Property Name="TextParsingEnabled" Value="False" />
</Window></GUILayout>
字体(*.font)脚本也非常有用,用于描述CEGUI 中用到的字体,下面是一个例子:
<?xml version="1.0" ?><Font Name="DejaVuSans-10" Filename="DejaVuSans.ttf" Type="FreeType" Size="10" NativeHorzRes="800" NativeVertRes="600" AutoScaled="true"/>
另外一个重要的脚本是图像集(*.imageset),定义每种部件的视觉效果。CEGUI 中用户看到的部件视觉部分对应于一张大纹理文件中的坐标。比如,按钮在.imageset 中定义为一张纹理图像(*.png,*.bmp,*.jpg 等)中像素点100×320开始宽高为50×50的图形。这些是需要在图像集中定义的。下面是一个例子:
<?xml version="1.0" ?><Imageset Name="TaharezLook" Imagefile="TaharezLook.tga" NativeHorzRes="800" NativeVertRes="600" AutoScaled="true">
<Image Name="MouseArrow" XPos="138" YPos="127" Width="31" Height="25" XOffset="0" YOffset="0" /></Imageset>
最后是感观风格(*.looknfeel)脚本。这个文件看起来相当邪恶(译注:庞杂),却能将所有人从噩梦中拯救,这里为了节省空间不再提交例子。这个文件用于确定所有部件(CEGUI 中window/object/item 表示的)的感观和反馈效果。比如,按钮在鼠标悬停时的效果,如何构建窗口的边框和背景。每种配色方案一般都有自己的感观风格,使得CEGUI 部件的基本构造更加可定制化。
接着开始部分
现在我们对CEGUI 中用到的脚本文件有了一些基本认识(别担心,随着学习的深入,你会发现它们更容易理解,并不再那么吓人,开始阶段用到最多的是.layout 文件。),接下来让我们开始做一些有用的事情!
截止到上次的代码,仅仅是启动了CEGUI 。但就其本身而言,它并不知道你想干嘛。首当其冲的是告诉它我们想使用的配色方案。如上所述,.Scheme 文件包含一个部件列表和其它一些脚本文件,可以引入图像集、感观风格和字体各一个。
// Load the scheme
CEGUI::SchemeManager::getSingleton().create( "TaharezLook.scheme" );
如果你想使用.Scheme 文件中未指定的图像集或者字体,实现起来很简单,用相关的管理对象加载它们即可。由于本篇是入门教程,我将会在后面章节中解释这些管理对象。
下一步,定义一些缺省值:
// Set the defaults
CEGUI::System::getSingleton().setDefaultFont( "DejaVuSans-10" );
CEGUI::System::getSingleton().setDefaultMouseCursor( "TaharezLook", "MouseArrow" );
使用全局CEGUI::System 对象的函数来设置缺省字体和鼠标光标。参考TaharezLook.scheme (在cegui/datafiles/schemes文件夹中),你会发现它通过标签加载了DejaVuSans-10.font 文件中定义的字体。标记"MouseArrow" 可以在图像集"TharezLook" 中找到。我想这些都是自解释的,无需多言。
嗯,现在CEGUI 清楚了我们想使用的一些缺省设置。我们创建一个根窗口,作为其它一切窗口的载体。
CEGUI 采用父/子关系来组织窗口,所以第一要务是创建所有其它窗口的父窗口:
CEGUI::Window* myRoot = CEGUI::WindowManager::getSingleton().createWindow( "DefaultWindow", "_MasterRoot" );
上面WindowManager 单件的函数调用创建一个"DefaultWindow" 类型名为"_MasterRoot" 的窗口。这个缺省窗口就是根窗口。缺省窗口是空的(或者说透明的)。根窗口的名字是随意指定的,然而我个人喜欢用_MasterRoot ,因为我的其它窗口一般不会用这个名字。
窗口创建后,需要设置它为根窗口:
CEGUI::System::getSingleton().setGUISheet( myRoot );
系统对象的函数调用,把myRoot 作为缺省窗口。记住上面myRoot 创建时起的名字"_MasterRoot" 。
总结虽然本篇教程不是特别精彩,但CEGUI 到这里已经设置完毕,我们接下来不断添加窗口,做一些GUI 的小实验,比如创建窗口,按钮,进行点击等等有趣的事情。后面的教程会演示如何使CEGUI 识别点击,窗口拖拽,输入等等!谢谢阅读!