2012年7月10日 星期二

Introduction to Stage3D: Part 1

Stage3D 基本介紹及教學
Stage3D 簡單講就是提供 API 讓 Flash 可以使用 GPU 進行 3D 硬體加速以提升效能,

架構示意圖
   GPU   
OpenGL or DirectX
  Stage3D  

顯示的順序如下,
Stage(最上層為傳統的 flash 顯示層)
Stage3D[2]
Stage3D[1]
Stage3D[0]
StageVideo
如下圖,

注意:Stage3D/StageVideo layer 皆為不透明。

這裡並不打算就 Stage3D 原理做深入討論,有興趣可自行參考[ref],

直接來直接看 code 比較清楚,

要求 stage3D 取得 context3D 物件
因為是非同步的,記得監聽 Event.CONTEXT3D_CREATE 事件
取得後記得移除,不然有可能會重覆建立,
例如當行動裝置的電力不足或裝置進入"鎖定螢幕"狀態,context3D 會 dispose。
stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, __onCreate);
stage.stage3Ds[0].requestContext3D();

取得 context3D
context = stage.stage3Ds[0].context3D;

建立 800 x 600 pixel rendering viewport,
這個動作很吃資源,應避免在 render 時不斷更動。
w: 800
h: 600
antiAlias: 0/2/4/16
enableDepthAndStencil: ture(creating depth and stencil buffers)

context.configureBackBuffer(800, 600, 0, true);

建立 VertexBuffer ,準備上傳的頂點"緩衝區"
vertexBuffer = context.createVertexBuffer(3, 6);
定義 VertexData,這邊定義三筆頂點資料
var vertexData:Vector.<Number>=Vector.<Number>([
-0.5, -0.5, 0, 1, 0, 0, // - 1st vertex x,y,z,r,g,b
0, 0.5, 0, 0, 1, 0,    // - 2nd vertex x,y,z,r,g,b
0.5, -0.5, 0, 0, 0, 1  // - 3rd vertex x,y,z,r,g,b
]);
上傳頂點資料,從第一個頂點開始上傳,共三個
vertexBuffer.uploadFromVector(vertexData, 0, 3);

建立頂點索引緩衝區
indexBuffer = context.createIndexBuffer(3);
上傳頂點索引資料
indexBuffer.uploadFromVector(Vector.<uint>([0, 1, 2]), 0, 3);

頂點座標資料 -> 暫存器-0(x,y,z)
context.setVertexBufferAt(0, vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
頂點顏色資料 -> 暫存器-1(r,g,b)
context.setVertexBufferAt(1, vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_3);

建立頂點及片段著色器程式(Program3D)
program = context.createProgram();
AGAL assembly 基本語法為 opcode destination, source1[, source2][, options]
var assembler:AGALMiniAssembler = new AGALMiniAssembler();

Vertex Shader
op:output point(一個特殊的暫存器,用來存放最後要輸出的座標)
mov op, va0 等同於 op = va0

code = "mov op, va0\n";
v0:variable register 0(總共可以設定八個變數暫存器)
mov v0, va1 等同於 v0 = va1

code += "mov v0, va1\n";
編譯 AGAL code
vertexShader = assembler.assemble(Context3DProgramType.VERTEX, code);

Fragment Shader
oc:output color(一個特殊的暫存器,用來存放最後要輸出的顏色)
move oc, v0 等同於 oc = v0

code = "mov oc, v0\n"
編譯 AGAL code fragmentShader = assembler.assemble(Context3DProgramType.FRAGMENT, code);
upload bytecode(in the video ram)
program.upload(vertexShader, fragmentShader);
設定要用的 Program3D
context.setProgram(program);

開始 render
清除資料,準備寫入新的值
context.clear(1, 1, 1, 1);
依據頂點索引,繪製三角形
context.drawTriangles(indexBuffer);
顯示 render 結果於螢幕
context.present();

結果如下圖。


[ref]
1.http://www.adobe.com/devnet/flashplayer/articles/how-stage3d-works.html
2.http://www.adobe.com/devnet/flashplayer/articles/vertex-fragment-shaders.html

沒有留言:

張貼留言