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

这篇文章我们剔除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的写法开始山寨吧。

时间: 2024-10-15 01:18:34

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

【Stage3D学习笔记续】山寨Starling(二):VertexData探幽

还记得之前的学习笔记中我们的顶点缓冲数组中的顶点数据么,我们使用一个一维数组来记录所有的顶点数据,这是由于顶点缓冲上传数据时是使用的一维数组. 如果对顶点数据进行一层代码的封装,就能更加的方便我们来操作顶点数据了. 所以引入了VertexData(顶点数据)这个类来进行封装. 在Starling中一个顶点需要记录9个数据,分别如下: 坐标数据 x 和 y(2D游戏就不需要z轴了,但是Starling中留下了 z 轴的位置的),开始索引为 0: 颜色数据 r.g.b.a(顶点颜色),开始索引为 3

【Stage3D学习笔记续】山寨Starling(十一):Touch事件体系

我们的山寨Starling版本将会在这里停止更新了,主要还是由于时间比较有限,而且我们的山寨版本也很好的完成了他的任务“了解Starling的核心渲染”,接下来的Starling解析我们将会直接阅读Starling的源码来了解其它的内部运行方式. Touch事件体系无疑是除了核心渲染外最重要的东西了,我们笔记中的Touch事件体系是基于Starling v1.1来解读的. Touch事件体系简介: 在Starling的承继关系里是没有InteractiveObject类,因此所有的显示对象都默认

【Stage3D学习笔记续】真正的3D世界(一):透视矩阵

如果各位看官跟着我的学习笔记一路看过来的话,一定会吐槽我的,这都是什么3D啊?从头到尾整个都是在使用GPU绘制一堆2D图像而已,的确,之前我们一直使用正交矩阵利用GPU加速来实现2D世界的展示,算不上真3D,但是正是由于有了之前的学习我们实现真3D世界的学习才会更加轻松,下面的笔记就让我们真正的进入3D世界吧! 补充一下,我们的这部分学习笔记是基于<Adobe Flash 11 Stage3D(Molehill) 游戏编程初学者指南>一书的学习而来的. 赶快进入我们的主题,是否还记得之前的2D

【Stage3D学习笔记续】山寨Starling(十二):总结和一些没提到的东西

我们的山寨Starling到这里就告一段落了,不得不说这是一个非常优秀的2D框架,他的设计和架构为后来的许多框架都提供了很好的参考,比如现在正在崛起的Egret,我们的一番解读也只是窥见了Starling内部的一部分,有兴趣的朋友可以继续看Starling的源码,一定会有更多的收获! 后悔的是我到这个时间才悔悟过来(切确的说是面试被鄙视的结果),开始看3D这块的知识,但我始终坚信一个道理,付出永远不会太迟,Let`s keep moving! 查看Starling的更新日志来了解这个框架的动态也

【Stage3D学习笔记续】山寨Starling(十):高效游戏设计、纹理集和ATF

我发布了经过批处理优化的v0.3版,点击下载:https://github.com/hammerc/hammerc-study-Stage3D/archive/v0.3.zip 先看看我们批处理优化后程序的效果吧! 首先,为了能明显的看出差距,我把未优化v0.2版本的MovieClipTest.swf的动画数量调到250个,同时QuadBatchTest.swf的代码一致也是250个动画,只是使用的是经过批处理优化的v0.3版本. 为了查看实际的性能差异,我使用了scout,下面看看我们的成果吧

【Stage3D学习笔记续】山寨Starling(九):上下文丢失处理方法

Stage3D在运行中是存在随时会丢失上下文的尴尬情况. 渲染内容丢失的问题本身就说明是因为丢失了Context3D对象.出现此问题的原因很多,通常还不是因为Stage3D应用.比如在win7系统中,当按下Ctrl+Alt+Delete键时会出现类似“锁定计算机”和“启动任务管理器”的菜单选项,这就会引起渲染内容丢失.但这不是唯一的可能,还有些情况,在某些屏保程序激活时又或笔记本盖子合上时也会引起渲染内容丢失.甚至可以通过调用Context3D.dispose()方法来模拟渲染内容丢失事件.所以

【Stage3D学习笔记续】山寨Starling(五):纹理计算和尺寸计算

尺寸计算: Starling中的尺寸是以像素为单位的,这一切都得力于我们使用的正交矩阵,还记得我们顶点数据中的位置数据么,如果我们提交的矩形的四个顶点为(0, 0)(0, 100)(100, 0)(100, 100),那么最终通过正交矩阵的转换后绘制到舞台时将会是长宽都为100个像素的矩形. 那么Starling中的尺寸获取其实就是基于顶点数据来进行获取,详细代码可以参考DisplayObject中的getBounds方法,主要看继承类DisplayObjectContainer和Quad的具体

【Stage3D学习笔记续】真正的3D世界(三):纹理效果

混合模式: 代码 示例是<Stage3D指南>中的直接弄出来的,可以通过点击键盘上的Q.W.E这3个按键,更换混合模式.模型和纹理,可以直观的查看不同混合模式的效果,住:下方的地形使用"context3D.setBlendFactors(Context3DBlendFactor.ONE, Context3DBlendFactor.ZERO);"正常混合模式渲染,上方中心的模型使用特定的混合模式渲染. 深度测试(Z-Buffer): 使用Z-Buffer的话,GPU会把每个像

【Stage3D学习笔记续】真正的3D世界(五):粒子特效

先看效果,按下空格键添加粒子特效: 一般而言粒子特效的实现都是比较复杂的,且不说实现粒子特效的编码和设计,光是编写一个粒子编辑器就不是简单的一件事,但是作者使用了很取巧的方式来完成,我们接下来深入代码看看作者是怎么处理的. Particle 在我还没有看这本书的这章之前我认为一个Particle应该是一个单一的粒子(或许是一个面片或者是一个简单的模型),而最终的粒子效果则是有成千上万个Particle组成渲染得出的,所以应该存在一个JSON或XML描述文件来指定每个粒子的运动轨迹和生命周期,不过