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

fire effect for stage3d

Get Adobe Flash player
by flashisobar 20 Sep 2012
/**
 * Copyright flashisobar ( http://wonderfl.net/user/flashisobar )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/9yxv
 */

package 
{
    import com.adobe.utils.AGALMiniAssembler;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.GradientType;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.display3D.Context3D;
    import flash.display3D.Context3DBlendFactor;
    import flash.display3D.Context3DProgramType;
    import flash.display3D.Context3DTextureFormat;
    import flash.display3D.Context3DTriangleFace;
    import flash.display3D.Context3DVertexBufferFormat;
    import flash.display3D.IndexBuffer3D;
    import flash.display3D.Program3D;
    import flash.display3D.textures.Texture;
    import flash.display3D.textures.TextureBase;
    import flash.display3D.VertexBuffer3D;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Matrix;
    import flash.geom.Matrix3D;
    import flash.utils.ByteArray;
    import net.hires.debug.Stats;
    
    /**
     * fire effect for stage3d
     * @author flashisobar
     */
    [SWF(width = "465", height = "465", frameRate = "60")]
    public class Main extends Sprite 
    {
        private static const FRAME_CREATE_PARTICLE_NUM:int = 3;
        private var vertexParticle:VertexBuffer3D;
        private var indexParticle:IndexBuffer3D;
        private var textureParticle:Texture;
        private var vertexShader:ByteArray;
        private var fragmentShader:ByteArray;
        private var transformConstants:Vector.<Number>;
        private var colorConstants:Vector.<Number>;
        private var matrix3d:Matrix3D;
        private var isStart:Boolean = true;
        private var particles:Vector.<Particle> = new Vector.<Particle>();

        private var _context3D:Context3D;
        private var _program:Program3D;
        
        ///private var sc:BitmapData = new BitmapData(465, 465, false);
        
        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);

            Wonderfl.disable_capture();
            //Wonderfl.capture_delay(5);
            ///addChild(new Bitmap(sc));

            //Security.loadPolicyFile('http://assets.wonderfl.net/crossdomain.xml');
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            
            prepareStage3D();
        }
        
        private function prepareStage3D():void 
        {
            stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, handleContextCreate);
            stage.stage3Ds[0].requestContext3D();
        }
        
        /*
         * configureBackBuffer: enableDepthAndStencil default is true
         * enableErrorChecking: slow rendering - only turn on when developing/testing
         */
        private function handleContextCreate(e:Event):void 
        {
            _context3D = stage.stage3Ds[0].context3D;
            if (!_context3D) {
                return;
            }
            _context3D.configureBackBuffer(stage.stageWidth, stage.stageHeight, 2, false);
            _context3D.setCulling(Context3DTriangleFace.BACK);
            _context3D.enableErrorChecking = true;
            _program = _context3D.createProgram();
            
            main();
            start();
        }

        private function main():void
        {
            this.addChild(new Stats);
            
            // set vertex/index data
            var vertices:Vector.<Number>=Vector.<Number>([
                -0.5, 0.5, 0, 0,
                0.5, 0.5, 0, 1,
                0.5, -0.5, 1, 1,
                -0.5, -0.5, 0, 1
            ]);
            vertexParticle = setVertexData(vertices, 4);
            indexParticle = setIndexData(Vector.<uint>([0, 1, 2, 2, 3, 0]));
            
            // set texture
            var sp:Sprite = new Sprite();
            var m:Matrix = new Matrix();
            m.createGradientBox(64, 64, 0, -32, -32);
            sp.graphics.beginGradientFill(GradientType.RADIAL, [0xFF8888, 0xFF8888], [0.5, 0], [0, 255], m);
            //sp.graphics.beginFill(0xFF8888, 1);
            sp.graphics.drawCircle(0, 0, 64);
            sp.graphics.endFill();
            var bmpd:BitmapData = new BitmapData(64, 64, true, 0);
            bmpd.draw(sp, new Matrix(1, 0, 0, 1, 32, 32));
            textureParticle = setTextureData(bmpd);
            
            // set register
            setVertexBuffer(0, vertexParticle, 0, Context3DVertexBufferFormat.FLOAT_2); // register0: va0
            setVertexBuffer(1, vertexParticle, 2, Context3DVertexBufferFormat.FLOAT_2); // register1: va1
            setTexture(0, textureParticle);                                                // fragment sampler0: fs0

            // set constants for setProgramConstantsFromMatrix
            transformConstants = new <Number>[0, 0, 0, 1];
            colorConstants = new <Number>[1, 1, 1, 1];
            
            // AGAL code
            // Register components can be accessed both through the coordinate accessors (xyzw), and through the color accessors (rgba).
            var assembler:AGALMiniAssembler = new AGALMiniAssembler();
            var code:String = '';
            code += "mov vt0, va0\n";                // pos: vt0 = va0;
            code += "mul vt0.xy, vt0, vc4.ww\n";     // size: vt0.xy = vt0 * vc4.ww
            code += "add vt0.xy, vt0, vc4.xy\n";     // move: vt0.xy = vt0 + vc4.xy
            code += "m44 op, vt0, vc0\n";            // m44: vt0 * vc0
            code += "mov v0, va1";                   // uv: v0 = va1;
            vertexShader = assembler.assemble(Context3DProgramType.VERTEX, code);

            code = "tex ft0, v0, fs0<2d,linear, nomip, repeat>\n"; // 參照 v0 從材質 fs0 取樣放入 ft0
            code += "mul oc, ft0, fc0";                            // add color: ft0 * fc0
            fragmentShader = assembler.assemble(Context3DProgramType.FRAGMENT, code);
            // set shader
            setShaders(vertexShader, fragmentShader);
            
            // set projection view or scale
            matrix3d = new Matrix3D();
            matrix3d.appendScale(1 / (500 / 4), 1 / (500 / 4), 1);
            context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, matrix3d, true); // vc0

            /*
             * set depthAndStencil = false
             * if enable BlendFactors(Additive)
             * see: http://goo.gl/yFmmk
             * https://github.com/PrimaryFeather/Starling-Framework/issues/150
             * http://forum.starling-framework.org/topic/flashdevelop-starling-air-32-stage3d-android-love
             * http://forum.starling-framework.org/topic/enabling-depth-buffer
             */
            context3D.setBlendFactors(Context3DBlendFactor.ONE, Context3DBlendFactor.ONE);
            
            // set click
            //stage.addEventListener(MouseEvent.CLICK, createParticles);
        }

        private function createParticles(e:MouseEvent = null):void 
        {
            isStart = true;
            for (var i:int = 0; i < FRAME_CREATE_PARTICLE_NUM; i++) {
                particles.push(new Particle());
            }
        }
        
        private function draw():void
        {
            if (!isStart)
                return;
            
            createParticles();
            var p:Particle;
            var len:int = particles.length;
            var i:int = len;
            while (i--)
            {
                p = particles[i];
                p.x += Math.random() * 2 - 1; // -1~1
                p.y += 1.5;
                p.size -= Math.random() * 1.2;
                if (p.size <= 0)
                {
                    particles.splice(i, 1);
                }
            }
            len = particles.length;
            for (i = 0; i < len; i++) 
            {
                p = particles[i];
                transformConstants[0] = p.x;
                transformConstants[1] = p.y;
                transformConstants[3] = p.size;
                colorConstants[0] = p.r;
                colorConstants[1] = p.g;
                colorConstants[2] = p.b;
                context3D.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 4, transformConstants);// vc4
                context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, colorConstants);    // fc0
                context3D.drawTriangles(indexParticle);
            }
        }
        
        protected function render(e:Event = null):void 
        {
            clear();
            draw();
            ///_context3D.drawToBitmapData(sc);
            present();
        }
        
        protected function clear(__red:Number=0, __green:Number=0, __blue:Number=0, __alpha:Number=1):void {
            _context3D.clear(__red, __green, __blue, __alpha);
        }

        protected function present():void 
        {
            _context3D.present();
        }
        
        public function pause():void 
        {
            removeEventListener(Event.ENTER_FRAME, render);
        }
        
        public function start():void 
        {
            addEventListener(Event.ENTER_FRAME, render);
        }
        
        public function setVertexData(__vertexData:Vector.<Number>, __data32Per:int):VertexBuffer3D
        {
            var numVertices:int = __vertexData.length/__data32Per;
            // create buffer
            var vertexBuffer3D:VertexBuffer3D = _context3D.createVertexBuffer(numVertices, __data32Per);
            vertexBuffer3D.uploadFromVector(__vertexData, 0, numVertices);
            return vertexBuffer3D;
        }
        
        /*
         * 建立索引"緩衝區"/定義索引資料/上傳索引資料
         */
        public function setIndexData(__indexData:Vector.<uint>):IndexBuffer3D
        {
            // create buffer
            var indexBuffer:IndexBuffer3D = _context3D.createIndexBuffer(__indexData.length);
            indexBuffer.uploadFromVector(__indexData, 0, __indexData.length);
            return indexBuffer;
        }
        
        /*
         * 建立貼圖材質
         */
        public function setTextureData(__bmd:BitmapData):Texture
        {
            var texture:Texture = _context3D.createTexture(__bmd.width, __bmd.height, Context3DTextureFormat.BGRA, false);
            texture.uploadFromBitmapData(__bmd);
            return texture;
        }
        
        /*
         * 設定暫存器
         */
        public function setVertexBuffer(__index:int, __buffer:VertexBuffer3D, __bufferOffset:int=0, __format:String="float4"):void
        {
            _context3D.setVertexBufferAt(__index, __buffer, __bufferOffset, __format);
        }
        
        /*
         * 設定貼圖材質取樣暫存器
         */
        public function setTexture(__sampler:int, __texture:TextureBase):void
        {
            _context3D.setTextureAt(__sampler, __texture);
        }
        
        /*
         * 設定頂點及片段著色器
         */
        public function setShaders(__vertexProgram:ByteArray, __fragmentProgram:ByteArray):void
        {
            _program.upload(__vertexProgram, __fragmentProgram);
            _context3D.setProgram(_program);
        }
        
        public function get context3D():Context3D 
        {
            return _context3D;
        }
        
        public function set context3D(value:Context3D):void 
        {
            _context3D = value;
        }
    }
    
}

class Particle 
{
    public var x:Number;
    public var y:Number;
    public var size:Number;
    public var r:Number;
    public var g:Number;
    public var b:Number;
    
    public function Particle() 
    {
        //this.x = Math.sin(getTimer()/1000)*10;
        this.x = 0;
        this.y = -50;

        size = 50 * Math.random() + 20;
        r = Math.random();
        g = Math.random() * 0.5;
        b = Math.random() * 0.5;
    }
    
}