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 Waves

Get Adobe Flash player
by bongiovi015 28 Jan 2012
    Embed
/**
 * Copyright bongiovi015 ( http://wonderfl.net/user/bongiovi015 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/r2R0
 */

package {
    import com.adobe.utils.AGALMiniAssembler;
    import com.bit101.components.PushButton;
    
    import flash.display.BitmapData;
    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.Point;
    import flash.geom.Vector3D;
    import flash.text.TextField;
    import flash.utils.ByteArray;
    
    public class Stage3DWave extends Sprite {
        public const ROW : int = 80;
        public const COL : int = 40;
        public const SEED : int = Math.random() * 0xFFFF;
        public const SPEED : Number = .5;
        public const SPACE : int = 8;
        public const DEPTH : int = 200;
        
        public var W : int;
        public var H : int;
        public var context : Context3D;
        public var bmpd : BitmapData;
        public var offset : Array = [new Point, new Point];
        public var count : int = 0;
        private var program:Program3D;
        private var vBuffer:VertexBuffer3D;
        private var iBuffer:IndexBuffer3D;
        private var debug:TextField;
        
        public function Stage3DWave() {
            W = stage.stageWidth;
            H = stage.stageHeight;
            
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, _onContext);
            stage.stage3Ds[0].requestContext3D();
        }
        
        private function _onContext(e:Event) : void {
            context = stage.stage3Ds[0].context3D;
            context.configureBackBuffer(W, H, 2, false);
            
            bmpd = new BitmapData(ROW, COL, false, 0);
            
            new PushButton(this, 10, 10, "START", startAnim);
            new PushButton(this, 10, 40, "STOP", stopAnim);
            
            _initShader();
            _initBuffer();
            
            addEventListener(Event.ENTER_FRAME, render);
        }
        
        
        public function startAnim(e:Event=null) : void {
            stopAnim();
            addEventListener(Event.ENTER_FRAME, render);
        }
        
        
        public function stopAnim(e:Event=null) : void {
            removeEventListener(Event.ENTER_FRAME, render);
        }
        
        
        private function _initBuffer() : void {
            vBuffer = context.createVertexBuffer(ROW*COL, 6);
            
            var indices : Vector.<uint> = new Vector.<uint>();
            var tmp0:int, tmp1:int, tmp2:int, tmp3:int, tmp4:int, tmp5:int; 
            
            var i:int, j:int;
            for(j=0; j<COL-1; j++) {
                for(i=0; i<ROW-1; i++) {
                    
                    tmp0 = i + j * ROW;
                    tmp1 = tmp0 + 1;
                    tmp2 = i + 1 + (j + 1) * ROW;
                    
                    tmp3 = tmp0;
                    tmp4 = tmp2;
                    tmp5 = tmp2-1;
                    
                    indices.push(tmp0, tmp1, tmp2, tmp3, tmp4, tmp5);
                }
            }
            
            iBuffer = context.createIndexBuffer(indices.length);
            iBuffer.uploadFromVector(indices, 0, indices.length);
        }        
        
        
        private function _initShader() : void {
            var agal : AGALMiniAssembler = new AGALMiniAssembler;
            var code : String = "";
            code += "mov vt1, va0\n";
            code += "div vt2, va1, vc9\n";
            code += "mul vt3, vt2, vt2\n";
            code += "add vt3.x, vt3.x, vt3.y\n";
            code += "add vt3.x, vt3.x, vt3.z\n";
            code += "div vt3.x, vt3.x, vc13.y\n";
            code += "mul vt3.x, vt3.x, vc13.z\n";
            code += "mov vt1.y, vt3.x\n";
            
            code += "m44 op, vt1, vc0\n";
            code += "mov v0, vt2\n";
            var vertexShader:ByteArray = agal.assemble(Context3DProgramType.VERTEX, code);
            
            code = "mov oc, v0\n";
            var fragmentShader:ByteArray = agal.assemble(Context3DProgramType.FRAGMENT, code);
            
            program = context.createProgram();
            program.upload(vertexShader, fragmentShader);
            
            context.setProgram(program);
            
            var data:Vector.<Number> = Vector.<Number>([255, 3, DEPTH, 1]);
            context.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 13, data, 1);
            context.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 9, Vector.<Number>([255, 255, 255, 1]))
        }
        
        
        public function render(e:Event=null):void {
            if( count % 3 == 0)  bmpd.perlinNoise(ROW, COL, 3, SEED, false, false, 7, true, offset);
            
            var vBuf:Vector.<Number> = new Vector.<Number>(4*6);
            var i:int, j:int, color:uint, index:int;
            var oColor:Object;
            for ( j=0; j<COL; j++) {
                for ( i=0; i<ROW; i++) {
                    color = bmpd.getPixel(i, j);
                    oColor = getRGB(color);
                    
                    vBuf[index++] = i * SPACE;
                    vBuf[index++] = 0;
                    vBuf[index++] = j  / COL;
                    
                    vBuf[index++] = oColor.r;
                    vBuf[index++] = oColor.g;
                    vBuf[index++] = oColor.b;
                }
            }
            
            
            vBuffer.uploadFromVector(vBuf, 0, ROW*COL);
            
            context.setVertexBufferAt(0, vBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
            context.setVertexBufferAt(1, vBuffer, 3, Context3DVertexBufferFormat.FLOAT_3);
            
            var model:Matrix3D = new Matrix3D;
            model.appendTranslation(-ROW*SPACE*.5, -DEPTH*.2, 1);
            model.appendScale(2/W, 2/H, 1);
            
            var view:Matrix3D = new Matrix3D;
            view.appendRotation(-(stage.mouseY/H)*60, Vector3D.X_AXIS, new Vector3D(0, 0, 1.5));
            view.appendRotation(-(stage.mouseX/W - .5)*60, Vector3D.Y_AXIS, new Vector3D(0, 0, 1.5));
            
            var project : Matrix3D = new Matrix3D;
            var fov:Number = 45;
            var aspect:Number = 4/3;
            var zNear:Number = 0.1;
            var zFar:Number = 3;
            var yScale:Number = 1.0/Math.tan(fov/2.0);
            var xScale:Number = yScale / aspect; 
            project.copyRawDataFrom(Vector.<Number>([    xScale, 0.0, 0.0, 0.0,
                0.0, yScale, 0.0, 0.0,
                0.0, 0.0, zFar/(zFar-zNear), 1.0,
                0.0, 0.0, (zNear*zFar)/(zNear-zFar), 0.0 ]));    
            
            model.append(view);
            model.append(project);
            
            context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, model, true);
            
            
            context.clear(0, 0, 0, 1);
            context.drawTriangles(iBuffer);
            context.present();
            
            
            offset[0].x += SPEED;
            offset[1].y += SPEED;
            count ++;
        }
        
        
        public static function getRGB(pixelValue:uint) : Object {
            var red:uint = pixelValue >> 16 & 0xFF;
            var green:uint = pixelValue >> 8 & 0xFF;
            var blue:uint = pixelValue & 0xFF;
            
            return {r:red, g:green, b:blue};
        }
    }
}