Starling 2D框架簡介

本系列是對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™ 開發人員均可以立刻開始使用它。web

Starling使用概述

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 許可得到受權,所以你能夠免費地使用它,即使是在商業應用程序中也是如此。 咱們天天都在使用它而且咱們依靠一個活躍的團隊不斷地完善它。安全

在後臺操做中,Starling 使用 Stage3D APIs —它們是在桌面上基於 OpenGL 和 DirectX ,在移動設備上基於 OpenGL ES2而運行的低級的 GPU APIs。 須要重點注意的是,Starling 是 Sparrow 的 ActionScript 3 端口,它等同於基於 OpenGL ES2 APIs 的ISO庫(參見圖1):app

圖1. Stage3D (Molehill) 分層位於 Starling 之上
圖1. Stage3D (Molehill) 分層位於 Starling 之上

Starling 從新建立了不少 Flash 開發人員熟知的 APIs 。 下圖列舉了經過 Starling 暴露的圖形元素 APIs(參見圖2)。框架

圖2. Starling支持DisplayObject繼承
圖2. Starling支持DisplayObject繼承

在 3D GPU APIs 基礎上能夠建立 2D 內容,這看起來有點奇怪。 當涉及 Stage3D APIs 時,不少人認爲這些 APIs 是嚴格地限制在 3D 內容中的。 實際上這是名稱形成的誤解:若是它叫作 Stage3D ,那麼你怎麼可使用它建立 2D 元素呢?下圖說明了關於使用 drawTriangles API 繪製 MovieClip 能力的問題(參見圖3)。異步

圖3. 可使用drawTriangles API建立2D影片剪輯嗎?
圖3. 可使用 drawTriangles API 建立2D影片剪輯嗎?

GPU 具備較高的效率並能快速地繪製三角形。 經過使用 drawTriangles API ,你能夠繪製兩個三角形,而後選取一種紋理而且使用UV映射將它應用到三角形中。 這樣能夠建立了一個帶有紋理的四邊形,它表明一個 sprite 。 經過更新每個幀上的三角形的紋理,最後的結果就是一個 MovieClip 。

幸虧咱們沒有必要經過這些細節使用 Starling 。 你只須要提供幀數,將它們提供給一個 Starling MovieClip ,這就是全部須要作的(參見圖4)。

圖4. 使用 drawTriangles API 和一個帶有紋理的四邊形,你能夠建立一個2D圖形
圖4. 使用 drawTriangles API 和一個帶有紋理的四邊形,你能夠建立一個2D圖形

爲了更好地瞭解 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):

圖5. 使用drawTriangles API 和一個帶有紋理的四邊形建立一個2D對象的結果
圖5. 使用drawTriangles API 和一個帶有紋理的四邊形建立一個2D對象的結果

上述範例中所示的代碼無疑是很是複雜的。 那是訪問低級 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):

圖6. 使用Stage3D渲染內容的範例
圖6. 使用Stage3D渲染內容的範例

須要記住在使用 Stage 3D 構架時,經過 GPU 能夠徹底地渲染併合成相應的內容。 所以,在 GPU 上運行的用於顯示列表的重繪區域(redraw regions)功能不能使用。

分層限制

當你使用 Starling(以及Stage 3D)時,記住開發內容有一個限制。 正如以前所述,Stage3D 徹底是嵌入在 Flash Player 中的全新的渲染構架。 GPU 表層放置在顯示列表之下,這意味着任何在顯示列表中運行的內容將放置到 Stage3D 內容之上。 在編寫這篇文章時,運行在顯示列表裏的內容仍然不能放置在 Stage3D 分層之下(參見圖7)。

圖7. 使用Stage3D渲染內容的堆疊順序
圖7. 使用Stage3D渲染內容的堆疊順序

此外,還要注意 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,那麼請按照以下步驟操做:

  1.  Flash Player 11下載新的playerglobal.swc。
  2. 從Flex 4.5 SDK表中下載 Flex 4.5 SDK (4.5.0.20967)。
  3. 將相應的版本安裝到你的開發環境中。
  4. 在 Flash Builder 中,經過選中File > New > ActionScript project 建立一個新的ActionScript項目。
  5. 打開 Property inspector(右擊並選中Properties選項)。 在左邊的菜單列表中,選中ActionScript Compiler。
  6. 使用右上角的 Configure Flex SDK 選項將項目指向 Flex build 20967。單擊OK。
  7. 設置你的項目目標爲SWF版本13。
  8. 打開Property inspector並從左側菜單列表選中 ActionScript Compiler。
  9.  -swf-version=13 添加至 'Additional compiler arguments' 輸入。這就保證了輸出的 SWF 把 SWF 版本13當作目標版本。若是你在命令行而不在 Flash Builder 中進行編譯,那麼你必須添加相同的編譯器參數。
  10. 覈查你已經在你的瀏覽器中安裝了新的Flash Player 11 版本。

設置場景

在你已經準備好了你的開發環境以後,你就能夠深刻研究相應的代碼,而且看看你如何可以充分利用這一框架。 使用 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):

圖8. 四邊形位於Stage的中央
圖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(右)之間的視覺差異
圖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可以在其內部處理了一切事務(例如着色程序(shader programs)、紋理和其它一切事務)。

一旦建立了你的 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 的要求。

Wmode 要求

你必須記住爲了啓用Stage 3D 和 GPU 加速功能,在頁面中你必須使用 wmode=direct 做爲嵌入模式。 若是你沒有指定任何值或者選擇除「direct」以外其它值,例如 「transparent」、「opaque」 或 「window」,則Stage 3D 將均不可用。相反,當 requestContext3D onStage3D被調用時,你會獲得一個運行時異常的提示,告知你Context3D對象的建立失敗。

下圖列舉了一個運行時異常的對話框:

圖10. 在 Context3D不可用的情形下,運行時異常對話框
圖10. 在 Context3D不可用的情形下,運行時異常對話框

若是你的應用程序嵌入時使用了錯誤的wmode,那麼必須當心處理這種情形。 你須要經過顯示一條解釋這一問題的信息以便給出合理的響應。 幸運的是,Starling爲你自動地處理了這一問題並顯示以下信息:

圖11. 當應用程序沒有正確嵌入時顯示的警告信息
圖11. 當應用程序沒有正確嵌入時顯示的警告信息

Stage質量

做爲一個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;

記住使用軟件回退功能設計你的內容是一種很好的作法,它將提供一種漸進式的體驗,從而確保在任何情形下都能得到最佳體驗效果

相關文章
相關標籤/搜索