AGAL feedback

by wh0
goal: basic cloth simulation on GPU.

This is for a class project due  by December 6 2011.

part 1: learning Context3D and AGAL

In this movie, a fragment shader rotates the hue of some Perlin noise.

Two textures are alternately used as input and output buffers.

problem: textures have 8-bit channels
♥0 | Line 78 | Modified 2011-11-30 13:53:38 | MIT License
play

ActionScript3 source code

/**
 * Copyright wh0 ( http://wonderfl.net/user/wh0 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/bRGC
 */

package {
    import flash.display.*;
    import flash.display3D.*;
    import flash.display3D.textures.*;
    import flash.events.*;
    import flash.geom.*;
    
    import com.adobe.utils.AGALMiniAssembler;
    import net.hires.debug.Stats;
    public class FlashTest extends Sprite {

        private var stage3D:Stage3D;
        private var context3D:Context3D;
        private var indexBuffer3D:IndexBuffer3D;
        private var fs_in:Texture;
        private var fs_out:Texture;

        public function FlashTest() {
            loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, function (e:UncaughtErrorEvent):void { Wonderfl.log(e.error); } );
            if (stage.stage3Ds.length == 0) throw 'no stage3D';
            
            stage.frameRate = 60;
            addChild(new Stats());
            
            // Obtain a 3D rendering context by requesting one from an instance of Stage3D.
            stage3D = stage.stage3Ds[0];
            stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreate);
            stage3D.requestContext3D();
        }
        
        private function context3DCreate(e:Event):void {
            // The runtime dispatches this when the requested context is ready.
            context3D = stage3D.context3D;
            context3D.configureBackBuffer(stage.stageWidth, stage.stageHeight, 0, false);
            prepareTestProgram();
            addEventListener(Event.ENTER_FRAME, draw);
        }
        
        private function prepareTestProgram():void {
            // The rendering pipeline consists of two shader programs.
            // We can assemble these programs from AGAL strings using a library from Adobe.
            // This vertex shader returns the xyz coordinates and stores the uv coordinates in v0.
            var vsa:AGALMiniAssembler = new AGALMiniAssembler();
            vsa.assemble(Context3DProgramType.VERTEX, <![CDATA[
mov op, va0 // return xyz coords
mov v0, va1 // store uv in v0
            ]]>);
            // This fragment shader reads a pixel from the input texture and returns it multiplied by a constant matrix.
            var fsa:AGALMiniAssembler = new AGALMiniAssembler();
            fsa.assemble(Context3DProgramType.FRAGMENT, <![CDATA[
tex ft0, v0, fs0 <nearest> // sample input at uv coords
m44 oc, ft0, fc0 // rotate by matrix
            ]]>);
            var p:Program3D = context3D.createProgram();
            p.upload(vsa.agalcode, fsa.agalcode);
            context3D.setProgram(p);
            
            // Define are the input vertices. It's a triangle that covers the entire viewport.
            var va:VertexBuffer3D = context3D.createVertexBuffer(3, 5);
            va.uploadFromVector(new <Number> [
            //   x   y   z    u  v
                -1,  1,  0,   0, 0,
                -1, -3,  0,   0, 2,
                 3,  1,  0,   2, 0
            ], 0, 3);
            // Store the xyz coordinates (columns 0-2) in va0.
            context3D.setVertexBufferAt(0, va, 0, Context3DVertexBufferFormat.FLOAT_3);
            // Store the uv coordinates (columns 3-4) in va1.
            context3D.setVertexBufferAt(1, va, 3, Context3DVertexBufferFormat.FLOAT_2);
            
            // Create the seed image.
            var bd:BitmapData = new BitmapData(64, 64, true, 0x00000000);
            bd.perlinNoise(64, 64, 6, 9988, false, true);
            // Move the generated image to a texture.
            fs_in = context3D.createTexture(64, 64, Context3DTextureFormat.BGRA, true);
            fs_in.uploadFromBitmapData(bd);
            // Put the texture in fs0.
            context3D.setTextureAt(0, fs_in);
            
            // Allocate a buffer for the result.
            fs_out = context3D.createTexture(64, 64, Context3DTextureFormat.BGRA, true);
            
            // Create a rotation matrix to play with the colors.
            var m:Matrix3D = new Matrix3D();
            m.appendRotation(2, new Vector3D(1, 1, 1));
            // Put the matrix in fc0-fc3. A 4x4 matrix occupies 4 adjacent registers.
            context3D.setProgramConstantsFromMatrix(Context3DProgramType.FRAGMENT, 0, m, true);
            
            // Create an index buffer that defines a mesh over the vertices. Here, it's a single triangle.
            indexBuffer3D = context3D.createIndexBuffer(3);
            indexBuffer3D.uploadFromVector(new <uint> [0, 1, 2], 0, 3);
        }
        
        private function draw(e:Event):void {
            // First, pick where to draw. Here, we draw to the back buffer.
            context3D.setRenderToBackBuffer();
            // They require that you clear the buffer before you draw anything.
            context3D.clear();
            // Call drawTriangles to do the work.
            context3D.drawTriangles(indexBuffer3D);
            // Call present to swap the back buffer and display buffer. This shows the result on the stage.
            context3D.present();
            
            // Now, we draw to the output texture.
            context3D.setRenderToTexture(fs_out);
            // Since we've called present and switched render destinations, we must call clear again.
            context3D.clear();
            // Draw to the texture.
            context3D.drawTriangles(indexBuffer3D);
            
            // Swap the texture pointers.
            var temp:Texture = fs_in;
            fs_in = fs_out;
            fs_out = temp;
            // Put the new input buffer in fs0.
            context3D.setTextureAt(0, fs_in);
        }

    }
}

Forked