開発環境 Apache Flex SDK 4.12.1
FlashDevelop 4.6.1
実行環境 Microsoft Windows 8.1 (64bit)
プロジェクトの種類 ActionScript 3/AS3 Project
プロジェクト名 HelloTriangleColored

参考

Main.as
package 
{
    import com.adobe.utils.AGALMiniAssembler;
    import flash.display.Sprite;
    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;
    import flash.utils.getTimer;
 
    public class Main extends Sprite 
    {
        protected var context3D:Context3D;
        protected var program:Program3D;
        protected var vertexbuffer:VertexBuffer3D;
        protected var indexbuffer:IndexBuffer3D;
 
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
 
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
 
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, initMolehill);
            stage.stage3Ds[0].requestContext3D();
 
            addEventListener(Event.ENTER_FRAME, onRender);
        }
 
        private function initMolehill(e:Event):void 
        {
            context3D = stage.stage3Ds[0].context3D;
            context3D.configureBackBuffer(800, 600, 1, true);
 
            var vertices:Vector.<Number> = Vector.<Number>([
            //  x,    y,    z, r, g, b,
                -0.3, -0.3, 0, 1, 0, 0,
                -0.3, 0.3, 0, 0, 1, 0,
                0.3, 0.3, 0, 0, 0, 1,
            ]);
            vertexbuffer = context3D.createVertexBuffer(3, 6);
            vertexbuffer.uploadFromVector(vertices, 0, 3);
 
            var indices:Vector.<uint> = Vector.<uint>([0, 1, 2]);
            indexbuffer = context3D.createIndexBuffer(3);
            indexbuffer.uploadFromVector(indices, 0, 3);
 
            var vertexShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
            vertexShaderAssembler.assemble(Context3DProgramType.VERTEX,
                "m44 op, va0, vc0\n" +
                "mov v0, va1"
            );
 
            var fragmentShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
            fragmentShaderAssembler.assemble(Context3DProgramType.FRAGMENT,
                "mov oc, v0"
            );
 
            program = context3D.createProgram();
            program.upload(vertexShaderAssembler.agalcode, fragmentShaderAssembler.agalcode);
 
            // va0 : vertex position
            context3D.setVertexBufferAt(0, vertexbuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
            // va1 : color
            context3D.setVertexBufferAt(1, vertexbuffer, 3, Context3DVertexBufferFormat.FLOAT_3);
            context3D.setProgram(program);
        }
 
        private function onRender(e:Event):void 
        {
            if (!context3D) return;
 
            context3D.clear(0.3, 0.3, 0.3);
 
            var m:Matrix3D = new Matrix3D();
            m.appendRotation(getTimer() / 40, Vector3D.Z_AXIS);
            context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, m, true);
 
            context3D.drawTriangles(indexbuffer);
 
            context3D.present();
        }
 
    }
 
}
 

四角形
package 
{
    import adobe.utils.CustomActions;
    import com.adobe.utils.AGALMiniAssembler;
    import flash.display.Sprite;
    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.events.KeyboardEvent;
    import flash.ui.Keyboard;
 
    public class Main extends Sprite 
    {
        private var context3D:Context3D;
        private var program:Program3D;
        private var vertexbuffer:VertexBuffer3D;
        private var indexbuffer:IndexBuffer3D;
        private var blue:Number = 0;
 
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
 
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
 
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, initMolehill);
            stage.stage3Ds[0].requestContext3D();
 
            addEventListener(Event.ENTER_FRAME, onRender);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
        }
 
        private function initMolehill(e:Event):void 
        {
            context3D = stage.stage3Ds[0].context3D;
            context3D.configureBackBuffer(800, 600, 1, true);
 
            const vertices:Vector.<Number> = Vector.<Number>([
            //  x,  y,  u, v,
                -1, -1, 0, 0, // LD
                -1, 1, 0, 1, // LU
                1, 1, 1, 1, // RU
                1, -1, 1, 0, // RD
            ]);
            const perVertex:int = 4;
            const numVertices:int = vertices.length / perVertex;
            vertexbuffer = context3D.createVertexBuffer(numVertices, perVertex);
            vertexbuffer.uploadFromVector(vertices, 0, numVertices);
 
            const indices:Vector.<uint> = Vector.<uint>([0, 1, 2, 2, 3, 0]);
            indexbuffer = context3D.createIndexBuffer(indices.length);
            indexbuffer.uploadFromVector(indices, 0, indices.length);
 
            var vertexShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
            vertexShaderAssembler.assemble(Context3DProgramType.VERTEX,
                "mov op va0\n" + // op:output position va0:vertex attribute 0
                "mov v0 va1"     // v0:varying 0
            );
 
            var fragmentShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
            fragmentShaderAssembler.assemble(Context3DProgramType.FRAGMENT,
                "mov ft0.x v0.y\n" +  // ft0:fragment temporary 0
                "mov ft0.y v0.x\n" +
                "mov ft0.z fc0.z\n" + // fc0:fragment constant 0
                "mov ft0.w fc0.w\n" +
                "mov oc ft0"          // oc:output color
            );
            // AGALMiniAssembler.asを見る限り、rgbaではなくxyzwでしかアクセスできないようだ
 
            program = context3D.createProgram();
            program.upload(vertexShaderAssembler.agalcode, fragmentShaderAssembler.agalcode);
 
            // va0 : xy
            context3D.setVertexBufferAt(0, vertexbuffer, 0, Context3DVertexBufferFormat.FLOAT_2);
            // va1 : uv
            context3D.setVertexBufferAt(1, vertexbuffer, 2, Context3DVertexBufferFormat.FLOAT_2);
            context3D.setProgram(program);
        }
 
        private function onRender(e:Event):void 
        {
            if (!context3D) return;
 
            context3D.setProgramConstantsFromVector(
                Context3DProgramType.FRAGMENT, 0, Vector.<Number>([0, 0, blue, 1])); // fc0
 
            context3D.clear();
            context3D.drawTriangles(indexbuffer);
            context3D.present();
        }
 
        private function onKeyDown(e:KeyboardEvent):void 
        {
            switch (e.keyCode) 
            {
                case Keyboard.W:
                    blue += 0.1;
                    if (1 < blue) blue = 1;
                    break;
                case Keyboard.S:
                    blue -= 0.1;
                    if (blue < 0) blue = 0;
                    break;
            }
            // 一度flashをクリックする必要あり
        }
 
    }
 
}
 
最終更新:2014年06月15日 16:03