CEGUI-渲染流程

CEGUI的渲染用到了“渲染到纹理”:每一个对话框或者其他复杂的界面元素首先渲染到一个纹理当中保存起来,如果这个对话框没有任何外形的改变,那么以后的渲染都直接使用这个纹理,而不用再把这个对话框的各个子元素都渲染一遍。这即缩短了渲染流程,同时也减少了提交给Gup的面片数目。游戏运行的时候,除了当前操作的对话框以外,其他界面元素一般都是不变的,所以这种渲染方式效率比较高。


渲染相关和几个核心类为GeometryBuffer、Window、WindowRenderer、RenderingSurface、RenderTarget。


GeometryBuffer类可以简单理解为面片的集合,它保存纹理指针、面片顶点数据、以及面片顶点和纹理的对应关系;

Window类为所有控件的基类,保存逻辑信息,Window有一个GeometryBuffer对象,把自己(不包括子元素)的外形面片保存在它里面;

WindowRenderer是一个工具类,生成Window外形面片并保存到Window类的GeometryBuffer对象中;

RenderingSurface类可以看成是GeometryBuffer对象的集合,绘制之前,首先将面片提交给RenderingSurface对象,然后RenderingSurface提交给绘制目标,即RenderTarget对象;

RenderTarget类即最终的绘制目标,可以是屏幕,也可以是纹理。


程序有一个顶层Window对象,所有界面元素都是它的子元素,或者它的子元素的子元素......。一般情况下,整个程序只有一个RenderingSurface对象,即顶层RenderingSurface对象。

没有对话框或者复杂元素的情况下,绘制的流程为:递归遍历顶层Window对象的子元素链表,每一个界面元素调用它保存的WindowRenderer对象,生成外形的面片,保存到它的GeometryBuffer对象中,然后把该对象提交到顶层RenderingSurface对象中,全部提交完毕后,顶层RenderingSurface对象把面片提交给代表屏幕的RenderTarget对象,绘制到屏幕上。在以后的渲染中,如果元素没有变化,则不更新它的GeometryBuffer对象,直接提交即可,这与“渲染到纹理”有异曲同工之妙,也提高了渲染效率。

有对话框或者复杂元素的情况下,就要用到“渲染到纹理”技术了,这是通过RenderingSurface的派生类RenderingWindow完成的,该类有一个GeometryBuffer对象。以对话框为例,对话框本身以及对话框的子元素并不把自己的GeometryBuffer对象提交到顶层的RenderingSurface对象中,而是提交到一个RenderingWindow对象中,该对象首先设置好自己的GeometryBuffer对象,即设置好6个顶点并把目标纹理清空,然后把提交过来的面片绘制到目标纹理上,最后再把这个GeometryBuffer对象提交到顶层RenderingSurface对象。


下面举个例子,这个例子中有一个FrameWindow和一个独立的Button,FrameWindow有一个子元素--Titlebar,FrameWindow的绘制用到了“渲染到纹理”,下面是绘制过程的协作图:


图中还有一个上文没有提到的D3DRenderer对象,它在绘制之前和绘制之后做一些准备工作,这里可以暂时不管它。

图中可以看到3个三角形——【aWindow-aWindowRenderer-aGeometryBuffer】,分别对应FrameWindow、Titlebar和PushButton,这个三角形完成的工作就是上文提到的,Window对象调用自己的WindowRenderer对象,把自己的外形面片保存到自己的GeometryBuffer对象中。如果Window对象的外形没有变化,则不进入三角形流程内,直接调用RenderingSurface::addGeometryBuffer提交之前的GeometryBuffer对象。


渲染功能的类图如下:


System::d_gui_redraw:标识界面是否需要重画,如果没有任何控件发生变化,则整个界面的面片都可以重用,此时跳过协作图中[2,29]步。

WIndow::d_needRedraw:标识Window对象自身是否需要重绘,如果不需要,则跳过协作图中的那个三角形。

RenderingSurface::d_invalidated:标识d_queues中的面片是否需要重新绘制到d_target中。

RenderingWindow::d_geometryValid:标识d_geometry是否有效,一般情况下d_geometry初始化之后就一直有效,但也有实效的时候,例如FrameWindow的尺寸变了,那么存储它外形的纹理的大小也需要变化,此时d_geometry就失效了。

Window::d_surface:不用“渲染到纹理”的元素,它为空,用到的,它指向一个RenderingWindow。


类图中还有一个类没提到——RenderingContext,它是一个简单的struct,只有4个字段,在渲染流程里面起到数据运送的作用,应该是很妙的一招,但怎么个妙法,我现在也讲不清楚。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值