您的位置:首页 > 其它

Starling 2D框架简介(一)

2015-04-20 18:09 120 查看
本系列是对IntroducingStarlingpdf的翻译,下文是对adobe开发人员中心的一片日志的转载,地址为http://www.adobe.com/cn/devnet/flashplayer/articles/introducing_Starling.html

Starling是在Stage3DAPIs基础上开发的一种ActionScript32D框架(可用于FlashPlayer11和AdobeAIR3的桌面)。Starling是为游戏开发设计的,但是你可以将它应用于很多其它的应用程序。在不必涉及低级Stage3DAPIs情况下,Starling使得编写具有快速GPU加速功能的应用程序成为可能。

大多数Flash开发人员希望利用这种能力提高GPU的加速功能(通过使用Stage3D技术),而不必编写如此高级的框架和深入研究低级的Stage3DAPIs。Starling是完全基于FlashPlayerAPIs而设计,并将Stage3D(Molehill)复杂性抽象化。因此每个人都能看到直观的程序。

Starling是为ActionScript3开发人员而设计,尤其是这些涉及2D游戏开发的人员。在使用ActionScript3之前,你必须基本了解它。由于Starling轻便、灵活并易于使用,你也可以将它应用于其它项目需求,例如UI编程。这种框架要求设计得越直观越好,因此任何Java™或者.Net™开发人员都可以马上开始使用它。

Starling使用概述

Starling直观并易于使用。Flash和Flex开发人员能够快速地了解它,因为它遵循大多数ActionScript规则并将低级Stage3DAPIs的复杂性抽象化。Starling使用熟知的概念,例如DOM显示列表、事件模型以及熟知的如MovieClip、Sprite、TextField等APIs,而不是依靠诸如顶点缓冲(verticesbuffer)、透视矩阵(perspectivematrices)、着色程序(shaderprograms)和组合字节码(assemblybytecode)进行编码。

Starling在很多领域都很轻便。类的数量是有限的(大概有80k的代码)。除了FlashPlayer11或者AIR3(以及在未来的版本中使用的移动支持)之外,它没有外部依赖。这些因素使得你的应用程序很小并使你的工作流程简单。

Starling能够免费使用并富有朝气。它根据SimplifiedBSD许可获得授权,因此你可以免费地使用它,即便是在商业应用程序中也是如此。我们每天都在使用它并且我们依靠一个活跃的团队不断地完善它。

在后台操作中,Starling使用Stage3DAPIs—它们是在桌面上基于OpenGL和DirectX,在移动设备上基于OpenGLES2而运行的低级的GPUAPIs。需要重点注意的是,Starling是Sparrow的ActionScript3端口,它等同于基于OpenGLES2APIs的ISO库(参见图1):



图1.Stage3D(Molehill)分层位于Starling之上

Starling重新创建了很多Flash开发人员熟知的APIs。下图列举了通过Starling暴露的图形元素APIs(参见图2)。



图2.Starling支持DisplayObject继承

在3DGPUAPIs基础上可以创建2D内容,这看起来有点奇怪。当涉及Stage3DAPIs时,很多人认为这些APIs是严格地限制在3D内容中的。实际上这是名称造成的误解:如果它叫做Stage3D,那么你怎么可以使用它创建2D元素呢?下图说明了关于使用drawTrianglesAPI绘制MovieClip能力的问题(参见图3)。



图3.可以使用drawTrianglesAPI创建2D影片剪辑吗?

GPU具有较高的效率并能快速地绘制三角形。通过使用drawTrianglesAPI,你可以绘制两个三角形,然后选取一种纹理并且使用UV映射将它应用到三角形中。这样可以创建了一个带有纹理的四边形,它代表一个sprite。通过更新每一个帧上的三角形的纹理,最后的结果就是一个MovieClip。

幸好我们没有必要通过这些细节使用Starling。你只需要提供帧数,将它们提供给一个StarlingMovieClip,这就是所有需要做的(参见图4)。



图4.使用drawTrianglesAPI和一个带有纹理的四边形,你可以创建一个2D图形

为了更好地了解Starling如何降低复杂性,检查你必须写入的代码以便于用低级的Stage3DAPIs显示简单的带有纹理的四边形。



1//createthevertices
2varvertices: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,
50.5,0.5,0,1,1,
60.5,-0.5,0,1,0]);
7
8//createthebuffertouploadthevertices
9varvertexbuffer:VertexBuffer3D=context3D.createVertexBuffer(4,5);
10
11//uploadthevertices
12vertexbuffer.uploadFromVector(vertices,0,4);
13
14//createthebuffertouploadtheindices
15varindexbuffer:IndexBuffer3D=context3D.createIndexBuffer(6);
16
17//uploadtheindices
18indexbuffer.uploadFromVector(Vector.<uint>([0,1,2,2,3,0]),0,6);
19
20//createthebitmaptexture
21varbitmap:Bitmap=newTextureBitmap();
22
23//createthetexturebitmaptouploadthebitmap
24vartexture:Texture=context3D.createTexture(bitmap.bitmapData.width,
25
26bitmap.bitmapData.height,Context3DTextureFormat.BGRA,false);
27
28//uploadthebitmap
29
30texture.uploadFromBitmapData(bitmap.bitmapData);
31
32//createtheminiassembler
33varvertexShaderAssembler:AGALMiniAssembler=newAGALMiniAssembler();
34
35//assemblethevertexshader
36vertexShaderAssembler.assemble(Context3DProgramType.VERTEX,
37"m44op,va0,vc0\n"+//postoclipspace
38"movv0,va1"//copyuv
39);
40
41//assemblethefragmentshader
42fragmentShaderAssembler.assemble(Context3DProgramType.FRAGMENT,
43"texft1,v0,fs0<2d,linear,nomip>;\n"+
44"movoc,ft1"
45);
46
47//createtheshaderprogram
48varprogram:Program3D=context3D.createProgram();
49
50//uploadthevertexandfragmentshaders
51program.upload(vertexShaderAssembler.agalcode,fragmentShaderAssembler.agalcode);
52
53//clearthebuffer
54context3D.clear(1,1,1,1);
55
56//setthevertexbuffer
57context3D.setVertexBufferAt(0,vertexbuffer,0,Context3DVertexBufferFormat.FLOAT_3);
58context3D.setVertexBufferAt(1,vertexbuffer,3,Context3DVertexBufferFormat.FLOAT_2);
59
60//setthetexture
61context3D.setTextureAt(0,texture);
62
63//settheshadersprogram
64context3D.setProgram(program);
65
66//createa3Dmatrix
67varm:Matrix3D=newMatrix3D();
68
69//applyrotationtothematrixtorotateverticesalongtheZaxis
70m.appendRotation(getTimer()/50,Vector3D.Z_AXIS);
71
72//settheprogramconstants(matrixhere)
73context3D.setProgramConstantsFromMatrix(Co
74ntext3DProgramType.VERTEX,0,m,true);
75
76//drawthetriangles
77context3D.drawTriangles(indexBuffer);
78
79//presentthepixelstothescreen
80context3D.present();






上述范例中的代码创建了一个正方形的2D实例(参见图5):



图5.使用drawTrianglesAPI和一个带有纹理的四边形创建一个2D对象的结果

上述范例中所示的代码无疑是非常复杂的。那是访问低级APIs需要付出的代价。从另一方面说,你可以控制很多方面,但是它需要大量的代码来设置一切。

通过Starling,你可以编写如下代码替换上述代码:



1//createaTextureobjectoutofanembeddedbitmap2vartexture:Texture=Texture.fromBitmap(newembeddedBitmap());34//createanImageobjectouroftheTexture5varimage:Image=newImage(texture);67//settheproperties8quad.pivotX=50;9quad.pivotY=50;10quad.x=300;11quad.y=150;12quad.rotation=Math.PI/4;1314//displayit15addChild(quad);




作为一个熟知如何使用FlashAPIs的ActionScript3开发人员,你可以立即使用这些已暴露的APIs开始工作,与此同时Stage3DAPIs的所有复杂部分都可以在后台进行处理。

如果你使用重绘区域(redrawregions)功能进行试验,在Starling将在Stage3D上,而不是在预期的传统显示列表上渲染一切。如下的截图说明了这种行为。该四边形在每一帧上旋转,重绘区域(redrawregions)只显示FTP计数器,而不是Stage3D的内容(参见图6):



图6.使用Stage3D渲染内容的范例

需要记住在使用Stage3D构架时,通过GPU可以完全地渲染并合成相应的内容。因此,在GPU上运行的用于显示列表的重绘区域(redrawregions)功能不能使用。

分层限制

当你使用Starling(以及Stage3D)时,记住开发内容有一个限制。正如之前所述,Stage3D完全是嵌入在FlashPlayer中的全新的渲染构架。GPU表层放置在显示列表之下,这意味着任何在显示列表中运行的内容将放置到Stage3D内容之上。在编写这篇文章时,运行在显示列表里的内容仍然不能放置在Stage3D分层之下(参见图7)。



图7.使用Stage3D渲染内容的堆叠顺序

此外,还要注意Stage3D对象不是透明的。如果这是可能的,那么你可以使用StageVideo技术(FlashPlayer10.2引入的功能)播放视频,同时可以用通过Stage3D渲染的内容覆盖视频。希望未来的FlashPlayer版本支持这一功能。

设置项目

你可以访问官方的Github页面下载Starling。此外,你可能发现访问Starling网站也会受益匪浅。

Starling根据SimplifiedBSD许可获得授权,所以你可以在任何类型的商业或者非商业项目上使用Starling。如果你需要更多的信息,你可以联系Starling框架团队。

在你下载Starling之后,你可以像引用其它AS3库一样引用Starling库。为了使用FlashPlayer11beta的新版本,你必须把SWF版本13作为目标,这是通过将额外的编译器参数即
-swf-version=13
传递给Flex编译器实现的。如果你正在使用AdobeFlexSDK,那么请按照如下步骤操作:

FlashPlayer11下载新的playerglobal.swc。

从Flex4.5SDK表中下载Flex4.5SDK(4.5.0.20967)。

将相应的版本安装到你的开发环境中。

在FlashBuilder中,通过选中File>New>ActionScriptproject创建一个新的ActionScript项目。

打开Propertyinspector(右击并选中Properties选项)。在左边的菜单列表中,选中ActionScriptCompiler。

使用右上角的ConfigureFlexSDK选项将项目指向Flexbuild20967。单击OK。

设置你的项目目标为SWF版本13。

打开Propertyinspector并从左侧菜单列表选中ActionScriptCompiler。

-swf-version=13添加至'Additionalcompilerarguments'输入。这就保证了输出的SWF把SWF版本13当做目标版本。如果你在命令行而不在FlashBuilder中进行编译,那么你必须添加相同的编译器参数。

核查你已经在你的浏览器中安装了新的FlashPlayer11版本。

设置场景

在你已经准备好了你的开发环境之后,你就可以深入研究相应的代码,并且看看你如何能够充分利用这一框架。使用Starling非常简单,你只需创建一个
Starling
对象并添加到你的主类即可。在本文中,当涉及到诸如
MovieClip
,
Sprite
以及其它对象时,我所指的都是StarlingAPIs,而不是来源于FlashPlayer的本地对象。

首先,Starling构造器(constructor)需要多重参数。下面是签名:

1publicfunctionStarling(rootClass:Class,stage:flash.display.Stage,viewPort:Rectangle=null,stage3D:Stage3D=null,renderMode:String="auto")




事实上,只有前面3个经常使用。相关的
rootClass
参数需要一个至扩展
starling.display.Sprite
的类的引用,而第二个参数是我们的stage,然后是一个Stage3D对象:



1package2{3importflash.display.Sprite;4importflash.display.StageAlign;5importflash.display.StageScaleMode;6importstarling.core.Starling;78[SWF(width="1280",height="752",frameRate="60",backgroundColor="#002143")]9publicclassStartupextendsSprite10{11privatevarmStarling:Starling;1213publicfunctionStartup()14{15//statsclassforfps16addChild(newStats());1718stage.align=StageAlign.TOP_LEFT;19stage.scaleMode=StageScaleMode.NO_SCALE;2021//createourStarlinginstance22mStarling=newStarling(Game,stage);2324//setanti-aliasing(higherisbetterqualitybutslowerperformance)25mStarling.antiAliasing=1;2627//startit!28mStarling.start();29}30}31}






在下面的代码中,Game类在被添加到Stage时可以创建一个简单的四边形:



1package
2{
3importstarling.display.Quad;
4importstarling.display.Sprite;
5importstarling.events.Event;
6
7publicclassGameextendsSprite
8{
9privatevarq:Quad;
10
11publicfunctionGame()
12{
13addEventListener(Event.ADDED_TO_STAGE,onAdded);
14}
15
16privatefunctiononAdded(e:Event):void
17{
18q=newQuad(200,200);
19q.setVertexColor(0,0x000000);
20q.setVertexColor(1,0xAA0000);
21q.setVertexColor(2,0x00FF00);
22q.setVertexColor(3,0x0000FF);
23addChild(q);
24}
25}
26}




上述代码将一个侦听器添加到Event.ADDED_TO_STAGE事件中,并在事件处理程序中对应用程序进行初始化。这样你就可以安全地访问Stage。

注意:关注一下这个微妙的细节:上面描述的Game类从starling.display程序包中,而不是从flash.display程序包中扩展了Sprite类。必须检查你的导入语句并确保你不是使用本地API来替代StarlingAPI。

正如在Flash中所预期的,Starling中的对象有一个默认的位置0,0。因此添加几行命令使四边形位于Stage的中央:

1q.x=stage.stageWidth-q.width>>1;2q.y=stage.stageHeight-q.height>>1;


现在,测试一下项目以便于观察相应的结果(参见图8):



图8.四边形位于Stage的中央

注意锯齿消除功能(anti-aliasing)值允许你设置锯齿消除功能所需的类型。一般来说,值为1就基本上可以接受,但是你可以选择其它值。该框架支持的锯齿消除功能(anti-aliasing)值的变化范围是0到16,但是,下面的列表给出了最常用的值:

0:无锯齿消除(anti-aliasing)。

2:最低程度的锯齿消除(anti-aliasing)。

4:高质量的锯齿消除(anti-aliasing)。

16:极高质量的锯齿消除(anti-aliasing)。

你很少需要用到超过2的设置,尤其是对2D内容。然而,根据你的项目要求,你需要针对具体情况作出相应的决定。在图9中,比较一下两个截图,观察两个锯齿消除(anti-aliasing)值(1和4)之间的细微差别。



图9.比较一下锯齿消除(anti-aliasing)值为1(左)和4(右)之间的视觉差别

试验一下使用2以上的值为你的项目设置所需的质量。当然,选择较高的值会影响性能。注意Stage3D不会受到SWF文件的Stage质量影响。

下面给出能够与Starling对象一起使用的其它API的描述:

enableErrorChecking:允许你启用或者禁止启用错误检查。指定是否将渲染器遇到的问题报告给应用程序。当enableErrorChecking设置为ture时,Starling内部调用的clear()和drawTriangles()方法是同步的并可以抛出错误。当enableErrorChecking设置为false时,clear()和drawTriangles()方法是异步的且不报告错误。启用错误检查将会减弱渲染性能。只有当调试项目时启用错误检查功能,而在部署最终版本前禁止启用该功能。

isStarted:指示是否调用了start。

juggler:juggler是一个简单对象。它仅保存了一列执行IAnimatable的对象,并且在被要求这样做的情形下提前了它们的时间(通过调用它自己的advanceTime:方法)。当一个动画完成时,它将会将其抛弃。

start:开始渲染和进行事件处理。

stop:停止渲染和进行事件处理。当游戏进入后台运行状态以节约资源时,使用这个方法可以停止渲染。

dispose:当你希望处理当前GPU内存上已渲染的全部内容时,调用这个方法。该API能够在其内部处理了一切事务(例如着色程序(shaderprograms)、纹理和其它一切事务)。

一旦创建了你的
Starling
对象,调试记录会自动地输出,显示关于渲染的信息。在默认情形下,当SWF文件正确地嵌入到页面或者当在独立的FlashPlayer中进行测试时,Starling会输出如下代码:

[Starling]Initializationcomplete.[Starling]DisplayDriver:OpenGLVendor=NVIDIACorporationVersion=2.1NVIDIA-7.2.9Renderer=NVIDIAGeForceGT330MOpenGLEngineGLSL=1.20(Directblitting)




当然,特定的硬件细节将会随着你的配置而变化。上述信息表明已经使用了GPU加速功能,因为它包括驱动版本的细节。为了便于调试,你可能希望能够强迫FlashPlayer内部使用的软件回退,以便了解当你的内容在软件上运行时它的表现如何。

添加如下的代码以便于通知Starling你希望使用软件回退功能(softwarerasterizer):

1mStarling=newStarling(Game,stage,null,null,Context3DRenderMode.SOFTWARE);


当你使用软件时,输出的信息会确认你正在使用software模式:

[Starling]Initializationcomplete.[Starling]DisplayDriver:Software(Directblitting)


确保你也在software模式下测试了你的内容,以便于更好地了解它在这种模式下的性能。如果用户的配置使用旧版本的驱动(为了保持一致性,所有2009年之前的驱动都包含于黑名单中),那么你的内容可能回退到软件。

在下一节中,当你将你的SWF文件嵌入到页面时,你需要看一下Stage3D的要求。

Wmode要求

你必须记住为了启用Stage3D和GPU加速功能,在页面中你必须使用
wmode=direct
作为嵌入模式。如果你没有指定任何值或者选择除“direct”之外其它值,例如“transparent”、“opaque”或“window”,则Stage3D将均不可用。相反,当
requestContext3D
on
Stage3D
被调用时,你会得到一个运行时异常的提示,告知你Context3D对象的创建失败。

下图列举了一个运行时异常的对话框:



图10.在Context3D不可用的情形下,运行时异常对话框

如果你的应用程序嵌入时使用了错误的wmode,那么必须小心处理这种情形。你需要通过显示一条解释这一问题的信息以便给出合理的响应。幸运的是,Starling为你自动地处理了这一问题并显示如下信息:



图11.当应用程序没有正确嵌入时显示的警告信息

Stage质量

作为一个Flash开发人员,stage质量的概念对你来说并不陌生。记住当使用Stage3D以及作为结果的Starling时,stage质量不会影响相应的性能。

渐进的增强功能

当GPU加速功能不起作用时,Stage3D将回退到软件中,并且将在内部使用一个名称为SwiftShader(Transgaming)的软件回退引擎。为了保证你的内容在此种情形下运行正常,你需要检测什么时候你应该在software模式下运行,并且移除在software模式下可能会减慢运行速度的潜在影响。

在2D内容环境下,软件回退功能能够处理很多对象并提供良好的性能,但是,为了检测这一点,你仍然可以使用静态的属性环境从Starling对象中读取Context3D对象:

//arewerunninghardwareorsoftware?varisHW:Boolean=Starling.context.driverInfo.toLowerCase().indexOf("software")==-1;


记住使用软件回退功能设计你的内容是一种很好的做法,它将提供一种渐进式的体验,从而确保在任何情形下都能获得最佳体验效果
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: