In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Stage3D test02

「Stage3Dプログラミング」読みながらいじってみました。その2。
行列計算はm44。
Get Adobe Flash player
by sakef 02 Sep 2012
    Embed
/**
 * 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;
            }
        }
    }
}