【Stage3D学习笔记续】山寨Starling(三):Starling核心渲染流程

时间:2022-04-24 23:47:19

这篇文章我们剔除Starling的Touch事件体系和动画体系,专门来看看Starling中的渲染流程实现,以及其搭建的显示列表结构。

由于Starling是模仿Flash的原生显示列表,所以我们可以参照原有的知识体系来阅读Straling的代码。

Starling类:

Straling类是整个Starling框架的核心,该类会管理Straling的显示列表、Touch事件、动画处理等等多个模块的功能;

同时Starling类会实现框架内部的帧循环;

实例化Starling类后会Starling的实例会作为一个静态量存储在Starling类中,可避免被垃圾回收;

Starling类的启动大致流程:

  1. 请求Stage3D对象;
  2. Starling类会创建和持有一个Stage对象,该对象为所有显示对象的基类;
  3. 实例化传入的文档类对象,该文档类作为第一个添加到Stage对象中的显示对象,类似于Flash中的root;
  4. 侦听Stage(flash.display.Stage)的ENTER_FRAME事件,每帧调用rander方法进行渲染;
  5. rander方法会调用stage(starling.display.Stage)的render方法开始对所有的子项进行渲染;

渲染处理,每个可显示的子项具体的渲染涉及到两个问题需要解决:

  1. 显示对象的最终状态。这里指的状态是:我添加了一个显示图像的纹理,坐标是0,0点,没有旋转,但是最终进行绘制时真的就把他绘制到0,0点么?这其实要看其父层到顶层(stage)的状态,比如其父层位置是100,100,旋转了50度,那么最终绘制时必须把这个数据考虑到;
  2. 显示对象的层级关系。即先绘制谁,Starling使用的是画家算法(后绘制的区域覆盖先绘制的区域),所以应该先绘制底层的图像,由于显示列表是一个树形结构,所以这块处理起来是比较方便的;

RenderSupport:

对象的绘制顺序只需要从根显示容器(即stage)开始从最底层到最上层的显示对象递归处理即可,这里主要说一下每个显示对象最终状态的处理,这就需要涉及到一个类,即RenderSupport。

RenderSupport内部维护一个名为mMatrixStack数组,该数组作为一个栈来使用,内部存放模型矩阵数据;mModelViewMatrix为当前处理的模型视图的矩阵数据。

渲染是从Stage开始处理,Stage本身是一个容器,会调用Stage的render方法。

如果为容器则render方法会依次处理每个子项:

  1. 每处理一个子项时会有一个当前矩阵的拷贝入栈(栈最开始时为空);
  2. 接下来会处理当前矩阵的数据,把当前处理的子项的位置、旋转和缩放等信息添加到该矩阵中;
  3. 调用子项的render方法进行,如果子项仍然是容器则会递归处理,如果是可显示的对象则会根据当前的矩阵信息绘制该对象;
  4. 将第一步入栈的对象出栈并设定为当前矩阵(其作用是还原到子项处理之前的矩阵数据);

我们可以发现,Starling利用栈方便的保存了显示列表中的一个分支的每个层级的矩阵信息,比如栈中的第一个元素是Stage的矩阵数据,第二个元素是第一个元素的数据添加了当前子项的转换矩阵的矩阵数据,后面的以此类推,每向下进入一个层级对当前的矩阵进行入栈,出来后会还原之前保存的矩阵信息;

由于每一帧都会对所有存在显示列表上的对象执行上面的render方法,所以矩阵对象会被大量创建,故Starling的新版使用了对象池来管理所有的矩阵信息可以减轻程序的开销,但是我们作为了解实现原理,先使用最清晰的方法来山寨该框架,后期如果有时间会添加优化方面的文章。

开始渲染:

Starling的DisplayObject类是一个抽象类,其render方法是一个抽象方法,并不会绘制任何图像,但是我们可以通过继承该类来实现具有绘制能力的类,具体的绘制方法之前的笔记有详细的代码和注释,写法不变,具体的类有如下几个,注:都不是容器哦:

  1. Quad:单纯显示矩形颜色的类;
  2. Image:可以显示一个纹理的类;
  3. MovieClip:注意了,Starling的MovieClip可不是继承Sprite的了(继承Image),他不是一个容器,可以理解为一个可以播放动画帧的显示对象,用来播放动画时使用;

下面的两个类其实是从容器类中添加额外的逻辑扩展得出的,本身是不需要绘制逻辑的:

  1. Button:加入了按钮的3态显示逻辑,更重要的是加入了显示文本的逻辑;
  2. TextField:可以显示文本的类;

解读到这来,其实对Starling的渲染流程有了一个大概的了解了,下一个笔记中,我们就照着Starling的写法开始山寨吧。