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 Animation using setVector

Modified code from Lee Brimelow posted here : https://plus.google.com/110495278155587072613/posts/U8oXcET3TE9

Performance example of using Stage3D to draw a animation.
/**
 * Copyright leichtgewicht ( http://wonderfl.net/user/leichtgewicht )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/7FdG
 */

/**
 * Modified code from Lee Brimelow posted here : https://plus.google.com/110495278155587072613/posts/U8oXcET3TE9
 *
 * Performance example of using Stage3D to draw a animation.
 */
package {
    import com.adobe.utils.Sprite3D;
    import flash.display.Stage3D;
    import flash.display.StageQuality;
    import flash.display3D.Context3D;
    import flash.display3D.Context3DBlendFactor;
    import flash.display3D.Context3DCompareMode;
    import flash.display3D.Context3DTriangleFace;
    import flash.display3D.textures.Texture;
    import flash.system.Capabilities;
    import flash.utils.describeType;
    import flash.display.LoaderInfo;
    import flash.display.Bitmap;
    import flash.system.LoaderContext;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.system.Security;
    import flash.display.Loader;
    import flash.net.URLRequest;
    import flash.display.Sprite;
    import flash.geom.Rectangle;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.display.BitmapData;
    
    import net.hires.debug.Stats;

    [SWF(frameRate=60)]
    public class Stage3DExample extends Sprite
    {
        
        // Holds all current blit sprites
        private var animations:Vector.<SpriteSheet> = new Vector.<SpriteSheet>();
        private var numAnimations:int = 0;
        
        private var stage3D:Stage3D;
        private var context3D:Context3D;
        private var context:SpriteSheetContext; 
        
        public function Stage3DExample()
        {
            // THIS CODE CAN NOT BE COMPILED BY WONDERFL, I POSTED IT ANYWAYS
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            stage.quality = StageQuality.HIGH;
            stage.frameRate = 60;
            
            addEventListener(Event.ADDED_TO_STAGE, onAdded);
        }
        
        private function onAdded(e:Event):void {
            removeEventListener(Event.ADDED_TO_STAGE, onAdded);
            stage3D = stage.stage3Ds[0];
            if(stage3D) {
                stage3D.addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreate);
                stage3D.requestContext3D("auto");
            }
        }
        
        private function resizeStage(e:Event=null):void
        {
            if( context ) context.setSize(stage.stageWidth,stage.stageHeight);
        }
        
        private function onContext3DCreate(e:*=null):void
        {
            
            init();
            // Remove existing frame handler. Note that a context
            // loss can occur at any time which will force you
            // to recreate all objects we create here.
            // A context loss occurs for instance if you hit
            // CTRL-ALT-DELETE on Windows.            
            // It takes a while before a new context is available
            // hence removing the enterFrame handler is important!
            removeEventListener(Event.ENTER_FRAME, loop);
            
            stage.addEventListener(Event.RESIZE, resizeStage);
            context3D = stage3D.context3D;
            if ( context3D ) {
                // disabling error checking will drastically improve performance
                // so only enable this during developement
                context3D.enableErrorChecking = true;
                context3D.setBlendFactors(Context3DBlendFactor.SOURCE_ALPHA,Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA);
                context3D.setCulling(Context3DTriangleFace.NONE);
                context3D.setDepthTest(false, Context3DCompareMode.ALWAYS);
                
                context = new SpriteSheetContext(context3D);
                resizeStage();
                
                addEventListener(Event.ENTER_FRAME, loop);
            }
        }
        
        private function init():void
        {
            // You gotta track that shit
            addChild(new Stats());
            
            // Start with 50, good to compare
            addAnimations(50);
            
            // When you click the stage you get 10 more
            stage.addEventListener(MouseEvent.CLICK, onClick);
        }
        
        protected function onClick(event:MouseEvent):void
        {
            // Create another 10 more
            addAnimations(10);
        }
        
        protected function addAnimations(amount:int):void
        {
            for(var i:int=0; i<amount; ++i)
            {
                var s:SpriteSheet = new SpriteSheet(SnakeData.sheet);
                s.x = Math.random() * stage.stageWidth * 2;
                s.y = Math.random() * stage.stageHeight * 2;
                animations.push(s);
            }
            numAnimations = animations.length;
        }

        
        protected function loop(event:Event):void
        {
            // Loop through snakes and render them
            context3D.clear(1.0,1.0,1.0);
            for ( var i:uint = 0; i < numAnimations; ++i ) {
                var s: SpriteSheet = animations[i];
                s.rotation -= 0.03490658503988659; // 2*Math.PI/180
                s.nextFrame();
                context.render(s);
            }
            context3D.present();
        }
    }
}

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.utils.Dictionary;

import flash.display3D.Context3D;
import com.adobe.utils.AGALMiniAssembler;
import com.adobe.utils.AGALMiniAssembler;
    
import flash.display3D.*;
import flash.display3D.textures.*;
import flash.display3D.textures.Texture;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;

/**
 * Renderer context that can render SpriteSheet's
 */
class SpriteSheetContext {

    private static const vertexShader:AGALMiniAssembler = new AGALMiniAssembler();
        vertexShader.assemble( Context3DProgramType.VERTEX,
            "mov vt0.xyzw, va0.xyww\n" +
            "m33 vt0.xyz, vt0, vc0\n" +
            "mov op, vt0\n" +
            "mov v0, va1\n"
        );
    
    private static const fragmentShader:AGALMiniAssembler = new AGALMiniAssembler();
        fragmentShader.assemble( Context3DProgramType.FRAGMENT,    
            "tex oc, v0, fs0 <2d,linear,miplinear>\n"
        );

    private var _matrix:Matrix = new Matrix();
    private var _matrixVector:Vector.<Number> = new Vector.<Number>();
    private var _transformVector:Vector.<Number> = new Vector.<Number>();
    private var _shaderProgram:Program3D = null;
    private var _context3D:Context3D = null;
    
    private var _backBufferWidth:uint = 0;
    private var _backBufferWidthInv:Number = 0;
    
    private var _backBufferHeight:uint = 0;
    private var _backBufferHeightInv:Number = 0;
    
    private var _textures:Dictionary = new Dictionary(true);
    
    public function SpriteSheetContext(context3D:Context3D) {
        _context3D = context3D;
        
        _shaderProgram = _context3D.createProgram();
        _shaderProgram.upload( vertexShader.agalcode, fragmentShader.agalcode);
        
        for ( var c:uint = 0; c < 12; c++)
            _matrixVector[c] = 0.0;
        
        _matrixVector[3] = 1.0; _matrixVector[7] = 1.0; _matrixVector[11] = 1.0;
    }
    
    public function setSize(backBufferWidth:uint, backBufferHeight:uint):void
    {
        _backBufferWidth = backBufferWidth;
        _backBufferWidthInv = 1.0 / backBufferWidth;
        
        _backBufferHeight = backBufferHeight;
        _backBufferHeightInv = 1.0 / backBufferHeight;
        
        _context3D.configureBackBuffer(_backBufferWidth, _backBufferHeight, 1);
    }
    
    public function render(sprite:SpriteSheet):void 
    {
        var data: SheetData = _textures[sprite.sheet];
        if ( !data ) {
            _textures[sprite.sheet] = data = new SheetData(_context3D,sprite.sheet);
        }
        
        // Applying transformations and render
        _context3D.setProgram(_shaderProgram);
        _matrix.createBox(1.0, 1.0, sprite.rotation, sprite.x - _backBufferWidth, _backBufferHeight - sprite.y);
        _matrix.scale(_backBufferWidthInv, _backBufferHeightInv);
        _matrixVector[0] = _matrix.a; _matrixVector[1] = _matrix.c; _matrixVector[2] = _matrix.tx;
        _matrixVector[4] = _matrix.b; _matrixVector[5] = _matrix.d; _matrixVector[6] = _matrix.ty;
        _context3D.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 0, _matrixVector, 3);
        _context3D.setTextureAt(0, data.texture);
        _context3D.setVertexBufferAt(0, data.vertices, 0, Context3DVertexBufferFormat.FLOAT_2);
        _context3D.setVertexBufferAt(1, data.vertices, 2, Context3DVertexBufferFormat.FLOAT_2);
        _context3D.drawTriangles(data.indices, sprite.frame * 6, 2);
    }
}

/**
 * Spritesheet that allows positioning and rotation
 */
class SpriteSheet {
    public var sheet: Sheet;
    public var x: Number = 0.0;
    public var y: Number = 0.0;
    public var rotation: Number = 0.0;
    public var frame: uint = 0;
    
    public function SpriteSheet(sheet:Sheet) {
        this.sheet = sheet;
    }
    
    public function nextFrame():void {
        (frame == sheet.frames - 1) ? frame = 0 : ++frame;
    }
}

/**
 * A Sheet of Frame data
 */
class Sheet {
    public var indices: Vector.<uint>;
    public var vertices: Vector.<Number>;
    public var bmp: BitmapData;
    public var frames: uint;
    
    public function Sheet(bmp:BitmapData, frames:Vector.<Rectangle>) {
        this.bmp = bmp;
        this.frames = frames.length;
        var v:uint = 0;
        var i:uint = 0;
        vertices = new Vector.<Number>(frames.length*16);
        indices = new Vector.<uint>(frames.length * 6);
        
        var ws:int = 2.0;
        var hs:int = 2.0;

        var width:int = bmp.width;
        var height:int = bmp.height;

        while(ws < width) {
            ws <<= 1;
        }

        while(hs < height) {
            hs <<= 1;
        }
        for ( var c:uint = 0, iO: uint = 0; c < frames.length; c++, iO += 4 ) {
            var frame: Rectangle = frames[c];
            
            var u0:Number =  frame.x                 / ws;
            var v0:Number =  frame.y                 / hs;
            var u1:Number = (frame.x + frame.width)  / ws;
            var v1:Number = (frame.y + frame.height) / hs;

            
            vertices[v++] = -frame.width; vertices[v++] =  frame.height; vertices[v++] = u0; vertices[v++] = v0;
            vertices[v++] =  frame.width; vertices[v++] =  frame.height; vertices[v++] = u1; vertices[v++] = v0;
            vertices[v++] =  frame.width; vertices[v++] = -frame.height; vertices[v++] = u1; vertices[v++] = v1;
            vertices[v++] = -frame.width; vertices[v++] = -frame.height; vertices[v++] = u0; vertices[v++] = v1;
            
            indices[i++] = (iO+0); indices[i++] = (iO+1); indices[i++] = (iO+3);
            indices[i++] = (iO+1); indices[i++] = (iO+2); indices[i++] = (iO+3);
        }
    }
}
/**
 * Data for a Sheet within one Context3D
 */
class SheetData {
    public var texture: Texture;
    public var vertices: VertexBuffer3D;
    public var indices: IndexBuffer3D;
    
    public function SheetData(context3D:Context3D, sheet:Sheet) {
        
        var ws:int = 2.0;
        var hs:int = 2.0;

        var width:int = sheet.bmp.width;
        var height:int = sheet.bmp.height;

        while(ws < width) {
            ws <<= 1;
        }

        while(hs < height) {
            hs <<= 1;
        }
        
        var level:int = 0;
        var tmp:BitmapData = new BitmapData(ws, hs, true, 0);
        var transform:Matrix = new Matrix();
        var rect:Rectangle = new Rectangle();
        
        texture = context3D.createTexture(ws, hs, Context3DTextureFormat.BGRA, true);

        while (ws >= 1.0 && hs >= 1.0) {
            tmp.draw(sheet.bmp, transform, null, null, null, true);
            texture.uploadFromBitmapData(tmp, level);
            rect.width = ws;
            rect.height = hs;
            tmp.fillRect(rect, 0);
            transform.scale(0.5, 0.5);
            level++;
            ws >>= 1;
            hs >>= 1;
        }
        tmp.dispose();
        
        indices = context3D.createIndexBuffer(sheet.indices.length);
        indices.uploadFromVector(sheet.indices, 0, sheet.indices.length);
        
        vertices = context3D.createVertexBuffer(sheet.vertices.length/4, 4);
        vertices.uploadFromVector(sheet.vertices, 0, sheet.vertices.length/4);
    }
}

class SnakeData {
        
    [Embed(source="snake.png")]
    private static const snakeRaw:Class;
    private static const snakeBmp:BitmapData = new snakeRaw().bitmapData;
    
    private static const rects:Vector.<Rectangle> = new Vector.<Rectangle>(20);
    {
        rects[0] = new Rectangle(0,0,106,62);
        rects[1] = new Rectangle(106,0,104,62);
        rects[2] = new Rectangle(210,0,104,64);
        rects[3] = new Rectangle(314,0,102,64);
        rects[4] = new Rectangle(0,64,100,64);
        rects[5] = new Rectangle(100,64,100,64);
        rects[6] = new Rectangle(200,64,100,64);
        rects[7] = new Rectangle(300,64,100,64);
        rects[8] = new Rectangle(400,64,98,66);
        rects[9] = new Rectangle(0,130,100,64);
        rects[10] = new Rectangle(100,130,100,66);
        rects[11] = new Rectangle(200,130,100,66);
        rects[12] = new Rectangle(300,130,100,66);
        rects[13] = new Rectangle(400,130,100,66);
        rects[14] = new Rectangle(0,196,102,64);
        rects[15] = new Rectangle(102,196,102,64);
        rects[16] = new Rectangle(204,196,104,64);
        rects[17] = new Rectangle(308,196,106,64);
        rects[18] = new Rectangle(0,260,106,62);
        rects[19] = new Rectangle(106,260,106,64);
    }
    
    private static var _sheet: Sheet;
    
    public static function get sheet():Sheet {
        if ( !_sheet ) {
            _sheet = new Sheet(snakeBmp, rects);
        }
        return _sheet;
    }
}