Stage3D test02
「Stage3Dプログラミング」読みながらいじってみました。その2。
行列計算はm44。
/**
* Copyright sakef ( http://wonderfl.net/user/sakef )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/4doF
*/
package {
// AGALプログラム文字列をバイトコード仕様に変換する
import com.adobe.utils.AGALMiniAssembler;
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.display3D.Context3D;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.VertexBuffer3D;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.Vector3D;
[SWF(backgroundColor="#000000")]
public class Main extends Sprite
{
private const WIDTH:int = 465;
private const HEIGHT:int = 465;
private var stage3d:Stage3D;
private var ctx:Context3D;
private var indexBuffer:IndexBuffer3D;
private var mtx:Matrix3D;
public function Main()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.quality = StageQuality.HIGH;
stage.frameRate = 60;
// stage3D取得
stage3d = stage.stage3Ds[0];
// イベントリスナの追加
stage3d.addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreate);
// Context3D のインスタンスが初期化
stage3d.requestContext3D();
}
private function onContext3DCreate(e:Event):void
{
// Context3Dの取得
ctx = Stage3D(e.target).context3D;
// 表示バッファの初期化
ctx.configureBackBuffer(WIDTH, HEIGHT, 2, true);
ctx.enableErrorChecking = true;
// x, y, z, r, g, b, a のフォーマットで頂点情報&色情報を指定
var vertices:Vector.<Number> = new <Number>[
-0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 1.0,
-0.5, 0.5, 0.0, 0.0, 1.0, 0.0, 1.0,
0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 1.0,
0.5, -0.5, 0.0, 0.0, 1.0, 1.0, 1.0
];
// 7つの値を持つ3つの頂点用の頂点バッファを作成
var vb:VertexBuffer3D = ctx.createVertexBuffer(4, 7);
// 上で定義したverticesの全データをアップロード
vb.uploadFromVector(vertices, 0, 4);
// 頂点シェーダの割り当て
// va0
ctx.setVertexBufferAt(0, vb, 0, Context3DVertexBufferFormat.FLOAT_3);
// va1
ctx.setVertexBufferAt(1, vb, 3, Context3DVertexBufferFormat.FLOAT_4);
// 頂点インデックスの指定
var indices:Vector.<uint> = new <uint>[0,1,2, 2,3,0];
// GPUにインデックスバッファを取得
indexBuffer = ctx.createIndexBuffer(6);
// 上で定義したindexDataの全データをアップロード
indexBuffer.uploadFromVector(indices, 0, 6);
//コンパイルされたシェーダを GPUにアップロードするクラス
var program:Program3D = ctx.createProgram();
//頂点シェーダ
var vertexPrg:String = "m44 op, va0, vc0\n" +"mov v0, va1";
//断片シェーダ
var fragmentPrg:String = "mov oc, v0";
// 頂点シェーダと断片シェーダのコードをアップロード
var assembler:AGALMiniAssembler = new AGALMiniAssembler();
program.upload(
assembler.assemble(Context3DProgramType.VERTEX, vertexPrg),
assembler.assemble(Context3DProgramType.FRAGMENT, fragmentPrg)
);
ctx.setProgram(program);
mtx = new Matrix3D;
addEventListener(Event.ENTER_FRAME, onFrame);
stage.addEventListener(Event.RESIZE, onResize);
onResize();
}
// フレームイベント
private function onFrame(e:Event=null):void
{
// Matrix3Dの計算
mtx.appendRotation(1,Vector3D.Z_AXIS);
ctx.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, mtx, true);
// GPUバッファのクリア
ctx.clear();
// GPUに転送したインデックスで描画
ctx.drawTriangles(indexBuffer,0,-1);
// GPUのバッファを表示
ctx.present();
}
// リサイズイベント
private function onResize(e:Event=null):void
{
if(stage3d)
{
stage3d.x = (stage.stageWidth - WIDTH) / 2;
stage3d.y = (stage.stageHeight - HEIGHT) / 2;
}
}
}
}