本系列是对Introducing Starling pdf的翻译,下文是对adobe开发人员中心的一片日志的转载,地址为http://www.adobe.com/cn/devnet/flashplayer/articles/introducing_Starling.htmlhtml
Starling 是在 Stage3D APIs 基础上开发的一种 ActionScript 3 2D 框架(可用于 Flash Player 11 和 Adobe AIR 3的桌面)。 Starling 是为游戏开发设计的,可是你能够将它应用于不少其它的应用程序。 在没必要涉及低级 Stage3D APIs 状况下,Starling 使得编写具备快速 GPU 加速功能的应用程序成为可能。git
大多数 Flash 开发人员但愿利用这种能力提升 GPU 的加速功能(经过使用 Stage3D 技术),而没必要编写如此高级的框架和深刻研究低级的 Stage3D APIs。 Starling 是彻底基于 Flash Player APIs 而设计,并将 Stage3D(Molehill)复杂性抽象化。 所以每一个人都能看到直观的程序。github
Starling 是为 ActionScript 3开发人员而设计,尤为是这些涉及2D游戏开发的人员。 在使用 ActionScript 3 以前,你必须基本了解它。因为 Starling 轻便、灵活并易于使用,你也能够将它应用于其它项目需求,例如 UI 编程。 这种框架要求设计得越直观越好,所以任何 Java™ 或者.Net™ 开发人员均可以立刻开始使用它。编程
Starling 直观并易于使用。Flash 和 Flex 开发人员可以快速地了解它,由于它遵循大多数 ActionScript 规则并将低级 Stage3D APIs 的复杂性抽象化。Starling 使用熟知的概念,例如DOM显示列表、事件模型以及熟知的如 MovieClip、Sprite、TextField 等APIs,而不是依靠诸如顶点缓冲(vertices buffer)、透视矩阵(perspective matrices)、着色程序(shader programs)和组合字节码(assembly bytecode)进行编码。浏览器
Starling在不少领域都很轻便。 类的数量是有限的(大概有80k的代码)。 除了Flash Player 11 或者 AIR 3(以及在将来的版本中使用的移动支持)以外,它没有外部依赖。 这些因素使得你的应用程序很小并使你的工做流程简单。安全
Starling可以无偿使用并富有朝气。 它根据 Simplified BSD 许可得到受权,所以你能够免费地使用它,即使是在商业应用程序中也是如此。 咱们天天都在使用它而且咱们依靠一个活跃的团队不断地完善它。app
在后台操做中,Starling 使用 Stage3D APIs —它们是在桌面上基于 OpenGL 和 DirectX ,在移动设备上基于 OpenGL ES2而运行的低级的 GPU APIs。 须要重点注意的是,Starling 是 Sparrow 的 ActionScript 3 端口,它等同于基于 OpenGL ES2 APIs 的ISO库(参见图1):框架
Starling 从新建立了不少 Flash 开发人员熟知的 APIs 。 下图列举了经过 Starling 暴露的图形元素 APIs(参见图2)。异步
在 3D GPU APIs 基础上能够建立 2D 内容,这看起来有点奇怪。 当涉及 Stage3D APIs 时,不少人认为这些 APIs 是严格地限制在 3D 内容中的。 实际上这是名称形成的误解:若是它叫作 Stage3D ,那么你怎么可使用它建立 2D 元素呢?下图说明了关于使用 drawTriangles API 绘制 MovieClip 能力的问题(参见图3)。ide
GPU 具备较高的效率并能快速地绘制三角形。 经过使用 drawTriangles API ,你能够绘制两个三角形,而后选取一种纹理而且使用UV映射将它应用到三角形中。 这样能够建立了一个带有纹理的四边形,它表明一个 sprite 。 经过更新每个帧上的三角形的纹理,最后的结果就是一个 MovieClip 。
幸亏咱们没有必要经过这些细节使用 Starling 。 你只须要提供帧数,将它们提供给一个 Starling MovieClip ,这就是全部须要作的(参见图4)。
为了更好地了解 Starling 如何下降复杂性,检查你必须写入的代码以便于用低级的 Stage3D APIs 显示简单的带有纹理的四边形。
1 // create the vertices 2 var vertices:Vector.<Number> = Vector.<Number>([ 3 -0.5,-0.5,0, 0, 0, // x, y, z, u, v 4 -0.5, 0.5, 0, 0, 1, 5 0.5, 0.5, 0, 1, 1, 6 0.5, -0.5, 0, 1, 0]); 7 8 // create the buffer to upload the vertices 9 var vertexbuffer:VertexBuffer3D = context3D.createVertexBuffer(4, 5); 10 11 // upload the vertices 12 vertexbuffer.uploadFromVector(vertices, 0, 4); 13 14 // create the buffer to upload the indices 15 var indexbuffer:IndexBuffer3D = context3D.createIndexBuffer(6); 16 17 // upload the indices 18 indexbuffer.uploadFromVector (Vector.<uint>([0, 1, 2, 2, 3, 0]), 0, 6); 19 20 // create the bitmap texture 21 var bitmap:Bitmap = new TextureBitmap(); 22 23 // create the texture bitmap to upload the bitmap 24 var texture:Texture = context3D.createTexture(bitmap.bitmapData.width, 25 26 bitmap.bitmapData.height, Context3DTextureFormat.BGRA, false); 27 28 // upload the bitmap 29 30 texture.uploadFromBitmapData(bitmap.bitmapData); 31 32 // create the mini assembler 33 var vertexShaderAssembler : AGALMiniAssembler = new AGALMiniAssembler(); 34 35 // assemble the vertex shader 36 vertexShaderAssembler.assemble( Context3DProgramType.VERTEX, 37 "m44 op, va0, vc0\n" + // pos to clipspace 38 "mov v0, va1" // copy uv 39 ); 40 41 // assemble the fragment shader 42 fragmentShaderAssembler.assemble( Context3DProgramType.FRAGMENT, 43 "tex ft1, v0, fs0 <2d,linear, nomip>;\n" + 44 "mov oc, ft1" 45 ); 46 47 // create the shader program 48 var program:Program3D = context3D.createProgram(); 49 50 // upload the vertex and fragment shaders 51 program.upload( vertexShaderAssembler.agalcode, fragmentShaderAssembler.agalcode); 52 53 // clear the buffer 54 context3D.clear ( 1, 1, 1, 1 ); 55 56 // set the vertex buffer 57 context3D.setVertexBufferAt(0, vertexbuffer, 0, Context3DVertexBufferFormat.FLOAT_3); 58 context3D.setVertexBufferAt(1, vertexbuffer, 3, Context3DVertexBufferFormat.FLOAT_2); 59 60 // set the texture 61 context3D.setTextureAt( 0, texture ); 62 63 // set the shaders program 64 context3D.setProgram( program ); 65 66 // create a 3D matrix 67 var m:Matrix3D = new Matrix3D(); 68 69 // apply rotation to the matrix to rotate vertices along the Z axis 70 m.appendRotation(getTimer()/50, Vector3D.Z_AXIS); 71 72 // set the program constants (matrix here) 73 context3D.setProgramConstantsFromMatrix(Co 74 ntext3DProgramType.VERTEX, 0, m, true); 75 76 // draw the triangles 77 context3D.drawTriangles( indexBuffer); 78 79 // present the pixels to the screen 80 context3D.present();
上述范例中的代码建立了一个正方形的2D实例(参见图5):
上述范例中所示的代码无疑是很是复杂的。 那是访问低级 APIs 须要付出的代价。 从另外一方面说,你能够控制不少方面,可是它须要大量的代码来设置一切。
经过 Starling,你能够编写以下代码替换上述代码:
1 // create a Texture object out of an embedded bitmap 2 var texture:Texture = Texture.fromBitmap ( new embeddedBitmap() ); 3 4 // create an Image object our of the Texture 5 var image:Image = new Image(texture); 6 7 // set the properties 8 quad.pivotX = 50; 9 quad.pivotY = 50; 10 quad.x = 300; 11 quad.y = 150; 12 quad.rotation = Math.PI/4; 13 14 // display it 15 addChild(quad);
做为一个熟知如何使用 Flash APIs 的 ActionScript 3 开发人员,你能够当即使用这些已暴露的 APIs 开始工做,与此同时 Stage3D APIs 的全部复杂部分均可以在后台进行处理。
若是你使用重绘区域(redraw regions)功能进行试验,在 Starling 将在 Stage3D 上,而不是在预期的传统显示列表上渲染一切。 以下的截图说明了这种行为。 该四边形在每一帧上旋转,重绘区域(redraw regions)只显示FTP计数器,而不是 Stage3D 的内容(参见图6):
须要记住在使用 Stage 3D 构架时,经过 GPU 能够彻底地渲染并合成相应的内容。 所以,在 GPU 上运行的用于显示列表的重绘区域(redraw regions)功能不能使用。
当你使用 Starling(以及Stage 3D)时,记住开发内容有一个限制。 正如以前所述,Stage3D 彻底是嵌入在 Flash Player 中的全新的渲染构架。 GPU 表层放置在显示列表之下,这意味着任何在显示列表中运行的内容将放置到 Stage3D 内容之上。 在编写这篇文章时,运行在显示列表里的内容仍然不能放置在 Stage3D 分层之下(参见图7)。
此外,还要注意 Stage3D 对象不是透明的。 若是这是可能的,那么你可使用 Stage Video 技术(Flash Player 10.2引入的功能)播放视频,同时能够用经过 Stage3D 渲染的内容覆盖视频。 但愿将来的 Flash Player 版本支持这一功能。
你能够访问官方的 Github页面下载Starling。 此外,你可能发现访问 Starling 网站也会受益不浅。
Starling根据 Simplified BSD许可得到受权,因此你能够在任何类型的商业或者非商业项目上使用Starling。 若是你须要更多的信息,你能够联系 Starling 框架团队。
在你下载Starling以后,你能够像引用其它AS3库同样引用Starling库。 为了使用Flash Player 11 beta的新版本,你必须把SWF版本13做为目标,这是经过将额外的编译器参数即-swf-version=13
传递给Flex编译器实现的。若是你正在使用 Adobe Flex SDK,那么请按照以下步骤操做:
在你已经准备好了你的开发环境以后,你就能够深刻研究相应的代码,而且看看你如何可以充分利用这一框架。 使用 Starling 很是简单,你只需建立一个 Starling
对象并添加到你的主类便可。 在本文中,当涉及到诸如 MovieClip
, Sprite
以及其它对象时,我所指的都是 Starling APIs,而不是来源于 Flash Player 的本地对象。
首先,Starling构造器(constructor)须要多重参数。 下面是签名:
1 public function Starling(rootClass:Class, stage:flash.display.Stage, viewPort:Rectangle=null, stage3D:Stage3D=null, renderMode:String="auto")
事实上,只有前面3个常用。 相关的 rootClass
参数须要一个至扩展 starling.display.Sprite
的类的引用,而第二个参数是咱们的 stage,而后是一个 Stage3D 对象:
1 package 2 { 3 import flash.display.Sprite; 4 import flash.display.StageAlign; 5 import flash.display.StageScaleMode; 6 import starling.core.Starling; 7 8 [SWF(width="1280", height="752", frameRate="60", backgroundColor="#002143")] 9 public class Startup extends Sprite 10 { 11 private var mStarling:Starling; 12 13 public function Startup() 14 { 15 // stats class for fps 16 addChild ( new Stats() ); 17 18 stage.align = StageAlign.TOP_LEFT; 19 stage.scaleMode = StageScaleMode.NO_SCALE; 20 21 // create our Starling instance 22 mStarling = new Starling(Game, stage); 23 24 // set anti-aliasing (higher is better quality but slower performance) 25 mStarling.antiAliasing = 1; 26 27 // start it! 28 mStarling.start(); 29 } 30 } 31 }
在下面的代码中,Game类在被添加到 Stage 时能够建立一个简单的四边形:
1 package
2 { 3 import starling.display.Quad; 4 import starling.display.Sprite; 5 import starling.events.Event; 6 7 public class Game extends Sprite 8 { 9 private var q:Quad; 10 11 public function Game() 12 { 13 addEventListener(Event.ADDED_TO_STAGE, onAdded); 14 } 15 16 private function onAdded ( e:Event ):void 17 { 18 q = new Quad(200, 200); 19 q.setVertexColor(0, 0x000000); 20 q.setVertexColor(1, 0xAA0000); 21 q.setVertexColor(2, 0x00FF00); 22 q.setVertexColor(3, 0x0000FF); 23 addChild ( q ); 24 } 25 } 26 }
上述代码将一个侦听器添加到 Event.ADDED_TO_STAGE 事件中,并在事件处理程序中对应用程序进行初始化。 这样你就能够安全地访问 Stage。
注意: 关注一下这个微妙的细节:上面描述的 Game 类从 starling.display 程序包中,而不是从 flash.display 程序包中扩展了 Sprite 类。必须检查你的导入语句并确保你不是使用本地 API 来替代 Starling API。
正如在 Flash 中所预期的,Starling 中的对象有一个默认的位置0,0。所以添加几行命令使四边形位于 Stage 的中央:
1 q.x = stage.stageWidth - q.width >> 1; 2 q.y = stage.stageHeight - q.height >> 1;
如今,测试一下项目以便于观察相应的结果(参见图8):
注意锯齿消除功能(anti-aliasing)值容许你设置锯齿消除功能所需的类型。 通常来讲,值为1就基本上能够接受,可是你能够选择其它值。 该框架支持的锯齿消除功能(anti-aliasing)值的变化范围是0到16,可是,下面的列表给出了最经常使用的值:
你不多须要用到超过2的设置,尤为是对2D内容。 然而,根据你的项目要求,你须要针对具体状况做出相应的决定。 在图9中,比较一下两个截图,观察两个锯齿消除(anti-aliasing)值(1和4)之间的细微差异。
试验一下使用2以上的值为你的项目设置所需的质量。 固然,选择较高的值会影响性能。 注意 Stage3D 不会受到 SWF 文件的 Stage 质量影响。
下面给出可以与 Starling 对象一块儿使用的其它 API 的描述:
一旦建立了你的 Starling
对象,调试记录会自动地输出,显示关于渲染的信息。 在默认情形下,当 SWF 文件正确地嵌入到页面或者当在独立的 Flash Player 中进行测试时,Starling 会输出以下代码:
[Starling] Initialization complete. [Starling] Display Driver:OpenGL Vendor=NVIDIA Corporation Version=2.1 NVIDIA-7.2.9 Renderer=NVIDIA GeForce GT 330M OpenGL Engine GLSL=1.20 (Direct blitting)
固然,特定的硬件细节将会随着你的配置而变化。 上述信息代表已经使用了 GPU 加速功能,由于它包括驱动版本的细节。 为了便于调试,你可能但愿可以强迫 Flash Player 内部使用的软件回退,以便了解当你的内容在软件上运行时它的表现如何。
添加以下的代码以便于通知 Starling 你但愿使用软件回退功能(software rasterizer):
1 mStarling = new Starling(Game, stage, null, null, Context3DRenderMode.SOFTWARE);
当你使用软件时,输出的信息会确认你正在使用software 模式:
[Starling] Initialization complete. [Starling] Display Driver:Software (Direct blitting)
确保你也在 software 模式下测试了你的内容,以便于更好地了解它在这种模式下的性能。 若是用户的配置使用旧版本的驱动(为了保持一致性,全部2009年以前的驱动都包含于黑名单中),那么你的内容可能回退到软件。
在下一节中,当你将你的 SWF 文件嵌入到页面时,你须要看一下 Stage3D 的要求。
你必须记住为了启用Stage 3D 和 GPU 加速功能,在页面中你必须使用 wmode=direct
做为嵌入模式。 若是你没有指定任何值或者选择除“direct”以外其它值,例如 “transparent”、“opaque” 或 “window”,则Stage 3D 将均不可用。相反,当 requestContext3D
on Stage3D
被调用时,你会获得一个运行时异常的提示,告知你Context3D对象的建立失败。
下图列举了一个运行时异常的对话框:
若是你的应用程序嵌入时使用了错误的wmode,那么必须当心处理这种情形。 你须要经过显示一条解释这一问题的信息以便给出合理的响应。 幸运的是,Starling为你自动地处理了这一问题并显示以下信息:
做为一个Flash开发人员,stage质量的概念对你来讲并不陌生。 记住当使用 Stage3D以及做为结果的Starling时,stage质量不会影响相应的性能。
当GPU加速功能不起做用时,Stage3D将回退到软件中,而且将在内部使用一个名称为SwiftShader (Transgaming)的软件回退引擎。 为了保证你的内容在此种情形下运行正常,你须要检测何时你应该在software模式下运行,而且移除在software模式下可能会减慢运行速度的潜在影响。
在2D内容环境下,软件回退功能可以处理不少对象并提供良好的性能,可是,为了检测这一点,你仍然可使用静态的属性环境从Starling对象中读取Context3D对象:
// are we running hardware or software? var isHW:Boolean = Starling.context.driverInfo.toLowerCase().indexOf("software") == -1;
记住使用软件回退功能设计你的内容是一种很好的作法,它将提供一种渐进式的体验,从而确保在任何情形下都能得到最佳体验效果