当前位置: BOLT界面引擎 > 知识库文章 > LayerObject的使用指南

LayerObject的使用指南

作者:李亚星 2013-05-30

BOLT引擎从1.6(1.7)版本起引入了层渲染功能,其核心是使用LayerObject元对象和其它元对象/控件的组合能力,来实现更强大的功能和支持更丰富的扩展元对象,关于层渲染在《BOLT引擎的分层渲染机制》里面有详细介绍,这里主要介绍一下LayerObject的使用

 

LayerObject的绑定模式

LayerObject自身需要组合其它元对象或者来使用,单独一个LayerObject可以说没有什么额外的意义,任意一个元对象(包括LayerObject)都可以绑定到指定的LayerObject上,并且支持自动绑定和手动绑定模式:

l  自动绑定模式 auto

一个LayerObject的所有子对象都会自动绑定到该层上面,但是如果一个子对象又是LayerObject,那么该子LayerObject的子对象不会被绑定了,也就是不会跨LayerObject绑定

自动绑定模式是默认的绑定模式,也应该是大部分情况下都应该使用的模式,因为该绑定自动依赖元对象的父子关系,会更直观和方便,包括相对的位置的计算等

 

l  手动绑定模式 manual

在该模式下,一个不会有任何一个对象会被自动的绑定到该LayerObject上面,如果某个元对象想绑定到LayerObject,那么需要显式的调用元对象的BingLayer方法,并指定想要绑定的目标LayerObjectBindLayer是根对象的基础方法,原型如下

         bool BindLayer(layerobj, bool isRecursive)

其中layerobj是想要绑定到的目标对象,isRecursive指定是否递归绑定,这个函数需要注意的下面几点:

a)         如果该元对象已经被绑定到一个auto模式的层对象上面,那么该次绑定不会生效;但如果该元对象还没有被绑定到某个LayerObject,或者绑定到了manual模式的LayerObject上,那么该次绑定会生效,但是无论哪种情况都不会影响isRecursive=true情况下对子对象的绑定

b)         isRecursive=true情况下,会对该元对象的子对象也进行绑定,这个绑定也会遵循a)里面描述的要点

 

绑定模式可以在xml里面配置属性<bindmode>auto</bindmode>或者<bindmode>manual</bindmode>来指定,也可以通过下述接口来动态修改和查询:

void SetBindMode(string mode)

string GetBindMode()

 

无论哪种绑定模式,元对象绑定到层对象上面,都遵循下面的规则:

l  一个元对象同时最多绑定到一个LayerObject

l  一个元对象绑定到一个LayerObject上以后,可以解除绑定,或者再绑定到其它LayerObject上面

l  LayerObject支持嵌套,也就是LayerObject也可以绑定到另外的LayerObject上面,但是LayerObject不能绑定到自身

l  如果一个对象已经绑定到auto模式的LayerObject,那么不能再被绑定到其它manual模式的LayerObject了,这点很重要

 

LayerObject的剪裁敏感特性

剪裁敏感特性是LayerObject的一个关键特性,很多时候可以用来支持一些特殊效果的元对象比如各种后置渲染对象,关于剪裁敏感特性,详细内容可以参考《BOLT引擎的分层渲染机制》里面的详细介绍,这里介绍一下使用和注意事项

 

l  剪裁不敏感 clipsens=0

这是LayerObject的默认设置,这种情况下,对于一个可渲染元对象,绑定到LayerObject和没有绑定到任何LayerObject,绘制策略是一致的,也就是该元对象可能被任意裁剪进行绘制,而元对象本身的渲染也必须支持该种分块模式。

引擎内置的可渲染元对象都满足剪裁绘制模式,扩展的可渲染对象也必须满足该模式,这样引擎内部的渲染器只在必须的时候绘制元对象的一部分或者全部,很多时候会有更高的性能,比如一个元对象被limitchild属性限制,或者超出了hostwnd可见区域,那么就只需要绘制一部分,减少不必要的开销

 

但是对于有些对象,尤其是很多后置渲染类对象,每次绘制可能都需要该对象覆盖区域的全部目标位图信息,剪裁绘制会导致该对象无法正常工作,这种情况下就需要使用剪裁敏感的层对象了

 

l  剪裁敏感 clipsens=1

在这种情况下,对于一个绑定到该LayerObject的可渲染元对象,每个绘制周期内,如果该该元对象需要重绘,那么都会对该元对象进行全部绘制,不会尝试进行任何剪裁,同时该元对象也不会受任何父对象的limitchild属性限制

 

如果一个LayerObject是剪裁敏感,那么需要注意下面几点:       

a)         绑定到该LayerObject上的元对象,位置不可以超出该元对象的位置大小,否则会导致该元对象绘制时候被强制剪裁,导致出现非预期的效果

b)         绑定到该LayerObject上的所有元对象,绘制时候都不再受任何父对象的limitchild属性限制,如果需要limitchild来对该组元对象进行限制和剪裁,只能把该组元对象当成一个整体,对该LayerObject进行limitchild限制

c)         由于剪裁敏感LayerObject托管下的元对象具有相对较低的绘制效率,该LayerObject不宜有过多的元对象,最好只放置依赖剪裁敏感的元对象和一些必要的辅助对象,比如扩展元对象里面的MirrorObject,如果要对一个ImageObject进行镜像处理,那么该LayerObject上只需要放置一个ImageObject和一个MirrorObject就可以了

 

剪裁敏感属性可以在xml里面配置属性<clipsens>1</clipsens>来指定,也可以通过下述接口来动态修改和查询:

void SetClipSens(bool isClipsens)

bool GetClipSens()

 

LayerObject的缓存特性

这是LayerObject默认的特性,也不需要用户进行额外的配置,绑定到同一个LayerObject上的元对象,如果在某个绘制周期内,没有任何一个元对象需要绘制,那么该LayerObject的所有子对象就不需要参与本周期的绘制,一定程度上可以提高性能,详细的介绍请参考《BOLT引擎的分层渲染机制》里面的详细介绍

 

LayerObject的渲染特性

基于LayerObject的层渲染机制,和传统的渲染机制有所不同:

l  一个元对象被绑定到LayerObject上后,所有渲染都会渲染到该LayerObject上,然后再被渲染到hostwnd

l  一个元对象被绑定到LayerObject上后,超出该LayerObject的部分会被剪裁掉,无法显示

l  同一个LayerObject上的所有元对象,绘制次序依然遵循zorder由小到大的次序进行

l  LayerObject支持嵌套,嵌套LayerObject之间的绘制次序是按照父子关系的拓扑顺序,而非zorder大小,也就是子LayerObject一定在父LayerObject渲染之前进行渲染

 

 

 

下面是一个LayerObject配合剪裁敏感元对象(MirrorObject)的典型示例:

<obj class="LayerObject">

         <attr>

                   <left>100</left>

                   <top>100</top>

                   <width>240</width>

                   <height>170</height>

                   <clipsens>1</clipsens>

         </attr>

         <children>

                   <obj class="SeqImageObject">

                            <attr>

                                     <width>father.width</width>

                                     <height>father.height</height>

                                     <gif>cat</gif>

                                     <loop>1</loop>

                            </attr>

                            <eventlist>

                                     <event name="OnInitControl">

                                               local arg = {...}

                                               local self = arg[1]

                                               self:Play()

                                     </event>

                            </eventlist>

                   </obj>

                   <obj id="mirror" class="MirrorObject">

                            <attr>

                                     <width>father.width</width>

                                     <height>father.height</height>

                                     <mirrortype>none</mirrortype>

                            </attr>

                   </obj>

         </children>

</obj>

 

迅雷公司 版权所有 Copyright 2003-2010 Thunder Inc.All Rights Reserved. 意见反馈:xl7doc@xunlei.com