cegui作为gui库也算是相当庞大的类库,最大的特点是相当容易扩展和通用性非常好。这两个特性也给cegui带来了不少问题,api和配置项复杂难用,动态效率低等。比如通用性好,里面有n多功能(有的控件功能与标准window控件几乎没有区别),这样使得结构变得相对复杂,在性能与效率上也很难完全兼顾到。容易扩展也给动态变化的时候性能带来不少影响,通常情况下cegui在没有任何控件状态变化下效率非常,原因是cegui对所有需要绘制的窗口顶点全都缓冲到相应渲染器缓冲的buffer(注意:这里缓冲分两级,较高一级是缓冲在每个控件上,这个缓冲只有状态改变是发生改变的时候才改变),一旦发生改变,这个缓冲就会重新构造(注意:这里的鼠标的光标在任何时刻都是特殊),效率下降非常明显,所以在UI上做帧动画和位置改变的一些操作是几乎不可行的。还是回归优点,要强调的是cegui在looknfeel上所做的扩展性很好和如何使用这一个特点来进行开发。
先从cegui整体结构再看looknfeel的结构。 cegui主体部分的构成是控件和对应的渲染器构成,注意,这里是对应的渲染,就是说这个渲染器是依赖于这个控件而设计的,然后通过scheme配置来关联这些控件和相应的渲染器。渲染的时候控件调用渲染器,然后渲染器会根据控件的状态调用looknfeel相对应的statery进行渲染。这里渲染全部是将顶点信息和材质信息缓冲到这个控件的,然后系统再根据是否重绘标记,再将这些数据转换成渲染器对应的缓冲。这里渲染器充当的角色是就是根据控件状态根据looknfeel的配置来绘制这个控件,比如你有一个倒计时控件,控件本身就是能精确到毫秒的计时器,然而渲染器则可自己表现,比如在UI显示一个电子钟,或则精确到毫秒的跑表,或则渲染成带指针钟也可以。所以控件,渲染器和looknfeel就有这样的关系,一个渲染器是遵循一个具体的控件设计,一个looknfeel是遵循具体的渲染器设计的。你可以为一个控件设计多个渲染器,也可以为一个渲染器配置多个looknfeel配置,然后通过sheme配置将这三个关联起来组合出不同种类控件。
现在再回头看looknfeel,存在的好处,里面到底能做些什么,有那些主要配置项目,如何使用这些配置。looknfeel存在不但使得配置项目的重用度增加,也提高了,而且给控件换种风格也是变得相当容易,还有使得控件在编辑器里面编辑变得可能(其实可视化编辑所做的功能相当有限的,主要集中在位置和大小上,和一些指定的属性,就是控件内部配置都是由looknfeel配置完成,否则对于界面编辑人员开发难度也是一种挑战,开发人员做编辑器接口也加大工作量)。再看looknfeel到底能做什么,首先looknfeel作为配置,可以为控件提供资源配置,子控件配置,添加自定义属性,为里面特定配置项关联属性(包括子控件导出)。
looknfeel配置属性项:
looknfeel主要 WidgetLook ,StateImagery,ImagerySection,TextComponent,FrameComponent,ImageryComponent。上面只是列出主要的配置节点,在实际配置项目中是有更多配置节点。
WidgetLook :这个是配置一个控件最顶层的一个配置元素,因为这个是scheme配置中关联控件和渲染器就是通过这个节点的名字来进行关联,当然这个也可以不用作关联,配置一些公共框架。【示例xml】
StateImagery:这个原则上是渲染器调用的最小配置,但是一些控件比较特殊,可能会直接调用ImagerySection来进行渲染。且一次渲染过程中还可以调用多个。【示例xml】
ImagerySection:渲染元素节点,是可以被渲染器直接调用的最小元素,里面包含多个ImagerySection,TextComponent,FrameComponent。
ImagerySection:是渲染图片的组件
TextComponent:渲染文字组件
FrameComponent:渲染框架的组件
配置应用说明:
普通属性定义:
<PropertyDefinition name="ReadOnlyBGColour" initialValue="FFDFDFDF" redrawOnWrite="true" />
其实cegui自定义属性都是字符传,存入和获取都是
渲染组件关联的属性:
<StateImagery name="ReadOnly"> <Layer> <Section look="Vanilla/Shared" section="Frame" > <ColourProperty name="ReadOnlyBGColour" /> </Section> </Layer> </StateImagery>
这里将上面的属性关联到section里面的ColourProperty,这个不是任意都可以关联的,只有特定属性才可以,
如下属性都可以的,
ColourProperty ColourRectProperty VertFormatProperty HorzFormatProperty AreaProperty ImageProperty TextProperty FontProperty
这种可能文档不会这么提及的,开发可以到代码中查,有那些属性,具体作用。
关联子控件属性:
<PropertyLinkDefinition name="CaptionColour" widget="__auto_titlebar__" targetProperty="CaptionColour" initialValue="FFFFFFFF" />
第一name属性是这个控件直接访问的,而第二个widget是这个控件的子控件,最后targetProperty指定的是关联该子控件的那个属性
,最后一个顾名思义就是初始值。
这里需要注意的是,子控件必须有CaptionColour,否则会出现警告。
下面是控件里面对应的子控件对应
<Child type="Vanilla/Titlebar" nameSuffix="__auto_titlebar__"> <Area> <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim> <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim> <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim> <Dim type="Height" ><FontDim type="LineSpacing" padding="14" /></Dim> </Area> <Property name="AlwaysOnTop" value="False" /> </Child>
ImagerySection的定义:
这属性定义必须带名字,因为这个属性只有被调用的,没有直接嵌入的写法,不像namearea,有两种,一种直接嵌入需要的属性节点内,
还有一种带名字,专门供需要的调用。
<ImagerySection name="selection"> <ImageryComponent> <Area> <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim> <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim> <Dim type="RightEdge" ><UnifiedDim scale="1.0" type="RightEdge" /></Dim> <Dim type="BottomEdge" ><UnifiedDim scale="1.0" type="BottomEdge" /></Dim> </Area> <Image imageset="Vanilla-Images" image="GenericBrush" /> <VertFormat type="Stretched" /> <HorzFormat type="Stretched" /> </ImageryComponent> </ImagerySection>
这个里面可以定义Area属性,定义大小和位置,再是三种Componet,Component是cegui渲染的最小元素
cegui另一部分的麻烦的地方也是跟配合编辑器有关,就是控件的添加修改不改动到编辑器