Mona Lego
/**
* Copyright devon_o ( http://wonderfl.net/user/devon_o )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/pGIS
*/
package
{
import com.adobe.utils.AGALMiniAssembler;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display3D.Context3D;
import flash.display3D.Context3DProfile;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DRenderMode;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.textures.Texture;
import flash.display3D.VertexBuffer3D;
import flash.events.Event;
import flash.filters.DropShadowFilter;
import flash.geom.Matrix3D;
import flash.net.URLRequest;
import flash.system.LoaderContext;
/**
* Mona Lego (or is it Lego Lisa)
* @author Devon O.
*/
[SWF(width='465', height='465', backgroundColor='#000000', frameRate='60')]
public class Main extends Sprite
{
private static var VERTEX_SHADER:String =
<![CDATA[
m44 op, va0, vc0
mov v0, va1
]]>;
private static var FRAGMENT_SHADER:String =
<![CDATA[
div ft0, v0, fc0
frc ft1, ft0
sub ft0, ft0, ft1
mul ft0, ft0, fc0
tex ft1, ft0, fs0<2d, clamp, linear, mipnone>
tex ft2, v0, fs1<2d, clamp, linear, mipnone>
mul oc, ft1, ft2
]]>;
private var context:Context3D;
private var isReady:Boolean;
private var program:Program3D;
private var renderMatrix:Matrix3D;
private var vertexBuffer:VertexBuffer3D;
private var indexBuffer:IndexBuffer3D;
private var textureData:BitmapData;
private var texture:Texture;
private var brickTexture:Texture;
private var textureWidth:int;
private var textureHeight:int;
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);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
this.isReady = false;
this.renderMatrix = new Matrix3D();
loadImage();
startRender();
}
private function loadImage():void
{
var l:Loader = new Loader();
l.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoad);
l.load(new URLRequest("http://assets.wonderfl.net/images/related_images/1/12/1247/124761a085cc7a1704c9fb601fe9d35e2e5a8b2e"), new LoaderContext(true));
}
private function onImageLoad(event:Event=null):void
{
event.currentTarget.removeEventListener(Event.COMPLETE, onImageLoad);
var l:Loader = (event.currentTarget as LoaderInfo).loader;
this.textureData = (l.content as Bitmap).bitmapData;
requestContext();
}
private function startRender():void
{
addEventListener(Event.ENTER_FRAME, onFrame);
}
private function requestContext():void
{
stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onStage3dContext);
stage.stage3Ds[0].requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
}
private function onStage3dContext(e:Event):void
{
this.context = stage.stage3Ds[0].context3D;
this.context.configureBackBuffer(stage.stageWidth, stage.stageHeight, 1, false, false);
createVertexBuffer();
createIndexBuffer();
createTextures();
createPrograms();
this.isReady = true;
}
private function createVertexBuffer():void
{
var vertices:Vector.<Number> = new <Number>[
// x y u v
-1.0, 1.0, 0, 0,
1.0, 1.0, 1, 0,
-1.0, -1.0, 0, 1,
1.0, -1.0, 1, 1 ];
this.vertexBuffer = this.context.createVertexBuffer(4, 4);
this.vertexBuffer.uploadFromVector(vertices, 0, 4);
}
private function createIndexBuffer():void
{
this.indexBuffer = this.context.createIndexBuffer(6);
// 2 triangles (0, 1, 2) & (1, 3, 2)
// 0 - 1
// | / |
// 2 - 3
this.indexBuffer.uploadFromVector(new <uint>[0, 1, 2, 1, 3, 2], 0, 6);
}
private function createTextures():void
{
var dat:BitmapData = this.textureData;
this.textureWidth = dat.width;
this.textureHeight = dat.height;
this.texture = this.context.createTexture(dat.width, dat.height, Context3DTextureFormat.BGRA, false);
this.texture.uploadFromBitmapData(dat);
dat.dispose();
dat = brickData(this.textureWidth, this.textureHeight);
this.brickTexture = this.context.createTexture(dat.width, dat.height, Context3DTextureFormat.BGRA, false);
this.brickTexture.uploadFromBitmapData(dat);
dat.dispose();
}
private function createPrograms():void
{
var vertexShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
vertexShaderAssembler.assemble(Context3DProgramType.VERTEX, VERTEX_SHADER);
var fragmentShaderAssembler:AGALMiniAssembler = new AGALMiniAssembler();
fragmentShaderAssembler.assemble(Context3DProgramType.FRAGMENT, FRAGMENT_SHADER);
this.program = this.context.createProgram();
this.program.upload(vertexShaderAssembler.agalcode, fragmentShaderAssembler.agalcode);
}
private var shaderConstants:Vector.<Number> = new Vector.<Number>(4, true);
private function onFrame(e:Event):void
{
if (!this.isReady)
return;
this.context.clear(0, 0, 0, 1);
this.renderMatrix.identity();
this.renderMatrix.appendScale(this.textureWidth / stage.stageWidth, this.textureHeight / stage.stageHeight, 1.0);
this.context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, this.renderMatrix, true);
this.context.setVertexBufferAt(0, this.vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_2);
this.context.setVertexBufferAt(1, this.vertexBuffer, 2, Context3DVertexBufferFormat.FLOAT_2);
this.shaderConstants[0] = 16 / this.textureWidth;
this.shaderConstants[1] = 8 / this.textureHeight;
this.context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, this.shaderConstants, 1);
this.context.setTextureAt(0, this.texture);
this.context.setTextureAt(1, this.brickTexture);
this.context.setProgram(this.program);
this.context.drawTriangles(this.indexBuffer);
this.context.present();
}
private function brickData(w:Number, h:Number):BitmapData
{
var col:uint = 0xCDCDCD;
var s:Sprite = new Sprite();
s.graphics.beginFill(col);
s.graphics.drawRect(0, 0, 8, 8);
s.graphics.endFill();
var c:Shape = new Shape();
c.graphics.beginFill(col);
c.graphics.drawCircle(4, 4, 3);
c.graphics.endFill();
c.filters = [new DropShadowFilter(2, 45, 0, .65)];
s.addChild(c);
var dat:BitmapData = new BitmapData(8, 8, false, 0x0);
dat.draw(s);
s.removeChildren();
s = new Sprite();
s.graphics.beginBitmapFill(dat);
s.graphics.drawRect(0, 0, 16, 8);
s.graphics.endFill();
s.graphics.lineStyle(1, 0x000000, 1);
s.graphics.moveTo(0, 8);
s.graphics.lineTo(16, 8);
s.graphics.moveTo(16, 0);
s.graphics.lineTo(16, 8);
var fill:BitmapData = new BitmapData(16, 8, false, 0x0);
fill.draw(s);
s.graphics.clear();
var brick:Shape = new Shape();
brick.graphics.beginBitmapFill(fill);
brick.graphics.drawRect(0, 0, w, h);
brick.graphics.endFill();
var bdata:BitmapData = new BitmapData(w, h, false, 0x0);
bdata.draw(brick);
brick.graphics.clear();
dat.dispose();
return bdata;
}
}
}