Time Remap
http://blog.bongiovi.tw/?p=544
/**
* Copyright bongiovi015 ( http://wonderfl.net/user/bongiovi015 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/s44n
*/
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display3D.Context3D;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.VertexBuffer3D;
import flash.display3D.textures.Texture;
import flash.events.Event;
import flash.geom.Matrix;
import flash.geom.Matrix3D;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.media.Camera;
import flash.media.Video;
import net.hires.debug.Stats;
[SWF(width=465, height=465, frameRate=60, backgroundColor=0)]
public class TimeRemap extends Sprite {
public static const SIZE : int = 2;
private var W:int;
private var H:int;
private var _bmpd:BitmapData;
private var context:Context3D;
private var _cam:Camera;
private var _video:Video;
private var _vBuffer:VertexBuffer3D;
private var _iBuffer:IndexBuffer3D;
private var _pass:Pass;
private var _bmpds:Array = [];
private var _texture:Texture;
private var _bmp:Bitmap;
public function TimeRemap() {
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
W = 256;
H = 256;
_bmpd = new BitmapData(W, H, false, 0);
// _bmp = new Bitmap(_bmpd);
// addChild(_bmp);
stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, _onContext);
stage.stage3Ds[0].requestContext3D();
addChild(new Stats);
}
private function _onContext(event:Event):void {
stage.stage3Ds[0].removeEventListener(Event.CONTEXT3D_CREATE, _onContext);
context = stage.stage3Ds[0].context3D;
context.configureBackBuffer(stage.stageWidth, stage.stageHeight, 1, true);
context.enableErrorChecking = true;
_cam = Camera.getCamera();
_cam.setMode(W, H, 30);
_video = new Video(W,H);
_video.attachCamera(_cam);
_initBitmaps();
_initBuffer();
_initShader();
addEventListener(Event.ENTER_FRAME, _loop);
}
private function _loop(event:Event):void {
context.clear();
context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, new Matrix3D, true);
_generateTexture();
_pass.render(_iBuffer);
context.present();
}
private function _generateTexture():void {
var bmpd:BitmapData = new BitmapData(W, H, false, 0);
bmpd.draw(_video);
_bmpds.unshift(bmpd);
_bmpds.pop().dispose();
for(var i:int=0; i<_bmpds.length; i++) {
var tmp:BitmapData = _bmpds[i];
var rect:Rectangle = new Rectangle(0, i*SIZE, W, SIZE);
_bmpd.copyPixels(tmp, rect, new Point(0, i*SIZE), null, null, true);
}
_texture = createTexture(context, _bmpd);
context.setTextureAt(0, _texture);
_bmp.bitmapData = _bmpd;
}
private function _initBitmaps():void {
var totalSlices:int = H / SIZE;
for(var i:int=0; i<totalSlices; i++) {
var bmpd:BitmapData = new BitmapData(W, H, false, 0);
_bmpds.push(bmpd);
}
}
private function _initShader():void {
_pass = new PassCopy(context, true, false).assemble();
}
private function _initBuffer():void {
_vBuffer = getOthoVertexBuffer(context, 0.5);
_iBuffer = getOthoIndexBuffer(context);
context.setVertexBufferAt(0, _vBuffer, 0, "float3");
context.setVertexBufferAt(1, _vBuffer, 3, "float2");
}
public static function createTexture(context:Context3D, source:BitmapData) : Texture {
var w:Number, h:Number, level:int=0;
w = source.width, h = source.height;
var texture:Texture = context.createTexture(w, h, Context3DTextureFormat.BGRA, false);
var bmpd:BitmapData;
var mtx:Matrix = new Matrix;
while(w&&h) {
bmpd = new BitmapData(w, h, true, 0);
bmpd.draw(source, mtx, null, null, null, true);
texture.uploadFromBitmapData(bmpd, level);
>>= 1;
h >>= 1;
mtx.scale(.5, .5);
level++;
}
bmpd.dispose();
return texture;
}
public static function getOthoVertexBuffer(context:Context3D, depth:Number = 0) : VertexBuffer3D {
var vbuffer:VertexBuffer3D = context.createVertexBuffer(4, 5);
var vbuf:Vector.<Number> = Vector.<Number>([
-1, 1, depth, 0, 0,
1, 1, depth, 1, 0,
1, -1, depth, 1, 1,
-1, -1, depth, 0, 1
]);
vbuffer.uploadFromVector(vbuf, 0, 4);
return vbuffer;
}
public static function getOthoIndexBuffer(context:Context3D) : IndexBuffer3D {
var iOthoBuffer:IndexBuffer3D = context.createIndexBuffer(6);
iOthoBuffer.uploadFromVector(Vector.<uint>([0, 1, 2, 0, 2, 3]), 0, 6);
return iOthoBuffer;
}
}
}
import com.adobe.utils.AGALMiniAssembler;
import flash.display3D.Context3D;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.textures.Texture;
import flash.utils.ByteArray;
class Pass {
//--------------------------------------
// CLASS CONSTANTS
//--------------------------------------
protected static const agal:AGALMiniAssembler = new AGALMiniAssembler();
protected var _shaderVertex:String;
protected var _shaderFragment:String;
protected var _program:Program3D;
protected var _context:Context3D;
protected var _isRenderBackToBuffer:Boolean;
protected var _isRenderToTexture:Boolean;
protected var _texture:Texture;
public var isClearing:Boolean = true;
public function Pass(context:Context3D, isRenderBackToBuffer:Boolean, isRenderToTexture:Boolean, width:Number=1, height:Number=1) {
_context = context;
_isRenderBackToBuffer = isRenderBackToBuffer;
_isRenderToTexture = isRenderToTexture;
if(_isRenderToTexture) _texture = _context.createTexture(width, height, Context3DTextureFormat.BGRA, true);
}
public function assemble() : Pass {
var vertexShader:ByteArray = agal.assemble(Context3DProgramType.VERTEX, _shaderVertex);
var fragmentShader:ByteArray = agal.assemble(Context3DProgramType.FRAGMENT, _shaderFragment);
_program = _context.createProgram();
_program.upload(vertexShader, fragmentShader);
return this;
}
public function render(iBuffer:IndexBuffer3D) : void {
if(_isRenderToTexture) isClearing = true;
if(_isRenderBackToBuffer) _context.setRenderToBackBuffer();
else _context.setRenderToTexture(_texture, false, 1);
if(isClearing) _context.clear(0, 0, 0, 0);
_context.setProgram(_program);
_context.drawTriangles(iBuffer);
}
public function getTexture() : Texture { return _texture; }
}
import flash.display3D.Context3D;
import flash.display3D.Context3DProgramType;
import flash.display3D.IndexBuffer3D;
class PassCopy extends Pass {
public function PassCopy(context:Context3D, isRenderBackToBuffer:Boolean, isRenderToTexture:Boolean, width:Number=1, height:Number=1, miplinear:Boolean=false) {
super(context, isRenderBackToBuffer, isRenderToTexture, width, height);
_shaderVertex = "" +
"m44 op, va0, vc0\n" +
"mov v0, va1\n";
if(!miplinear) _shaderFragment = "tex oc, v0, fs0, <2d,linear,mipnone>\n";
else _shaderFragment = "tex oc, v0, fs0, <2d,linear,miplinear>\n";
}
}