forked from: Crosshatch Shader on Webcam Vid
Crosshatch shader applied to webcam video
/**
* Copyright animaacija ( http://wonderfl.net/user/animaacija )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/5djy
*/
// forked from devon_o's Crosshatch Shader on Webcam Vid
package {
import com.adobe.utils.AGALMiniAssembler;
import flash.display.BitmapData;
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.geom.Matrix3D;
import flash.media.Camera;
import flash.media.Video;
import flash.text.AntiAliasType;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.utils.ByteArray;
/**
* Crosshatch shader applied to webcam video
*/
[SWF(width='465', height='465', backgroundColor='#FFFFFF', frameRate='60')]
public class Cam extends Sprite {
private static const FRAGMENT_SHADER:String =
<![CDATA[
tex ft0, v0.xy, fs0<2d, clamp, linear, mipnone>
dp3 ft0.x, ft0.xyz, ft0.xyz
sqt ft0.x, ft0.x
add ft1.x, v0.x, v0.y
div ft4.z, ft1.x, fc1.x
frc ft4.w, ft4.z
sub ft4.w, ft4.z, ft4.w
mul ft4.z, fc1.x, ft4.w
sub ft1.x, ft1.x, ft4.z
sub ft1.y, v0.x, v0.y
div ft4.z, ft1.y, fc1.x
frc ft4.w, ft4.z
sub ft4.w, ft4.z, ft4.w
mul ft4.z, fc1.x, ft4.w
sub ft1.y, ft1.y, ft4.z
add ft1.z, v0.x, v0.y
sub ft1.z, ft1.z, fc1.y
div ft4.z, ft1.z, fc1.x
frc ft4.w, ft4.z
sub ft4.w, ft4.z, ft4.w
mul ft4.z, fc1.x, ft4.w
sub ft1.z, ft1.z, ft4.z
sub ft1.w, v0.x, v0.y
sub ft1.w, ft1.w, fc1.y
div ft4.z, ft1.w, fc1.x
frc ft4.w, ft4.z
sub ft4.w, ft4.z, ft4.w
mul ft4.z, fc1.x, ft4.w
sub ft1.w, ft1.w, ft4.z
mov ft2, fc2
slt ft4.x, ft0.x, fc0.x
seq ft4.y, ft1.x, fc1.z
mul ft4.z, ft4.x, ft4.y
sub ft2.xyz, ft2.xyz, ft4.zzz
slt ft4.x, ft0.x, fc0.y
seq ft4.y, ft1.y, fc1.z
mul ft4.z, ft4.x, ft4.y
sub ft2.xyz, ft2.xyz, ft4.zzz
slt ft4.x, ft0.x, fc0.z
seq ft4.y, ft1.z, fc1.z
mul ft4.z, ft4.x, ft4.y
sub ft2.xyz, ft2.xyz, ft4.zzz
slt ft4.x, ft0.x, fc0.w
seq ft4.y, ft1.w, fc1.z
mul ft4.z, ft4.x, ft4.y
sub ft2.xyz, ft2.xyz, ft4.zzz
mov ft2.w, ft0.w
mov oc, ft2
]]>
private static const VERT_SHADER:String =
<![CDATA[
m44 op, va0, vc0
mov v0, va1
]]>
private var mVideoData:BitmapData;
private var mVBuffer:VertexBuffer3D;
private var mIBuffer:IndexBuffer3D;
private var mProgram:Program3D;
private var mNumVerts:int;
private var mContext:Context3D;
private var mTexture:Texture;
private var mAppWidth:int;
private var mAppHeight:int;
private var mWebCam:Camera;
private var mVideo:Video;
private var mVidSize:int = 256;
public function Cam()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(event:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
initStage();
}
private function initStage():void
{
mAppWidth = stage.stageWidth;
mAppHeight = stage.stageHeight;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onContext);
stage.stage3Ds[0].requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
stage.addEventListener(Event.RESIZE, onStageResize);
}
private function onStageResize(event:Event):void
{
if (!mContext) return;
mAppWidth = stage.stageWidth;
mAppHeight = stage.stageHeight;
mContext.configureBackBuffer(mAppWidth, mAppHeight, 4, true);
}
protected function onContext(event:Event):void{
stage.stage3Ds[0].removeEventListener(Event.CONTEXT3D_CREATE, onContext);
mContext = stage.stage3Ds[0].context3D;
mContext.configureBackBuffer(mAppWidth, mAppHeight, 4, true);
initApp();
}
private function initApp():void {
if (!initCam())
{
exit();
return;
}
initBuffers();
initTexture();
initShader();
start();
}
private function exit():void
{
var tf:TextField = new TextField();
tf.selectable = false;
tf.mouseEnabled = false;
tf.mouseWheelEnabled = false;
tf.autoSize = TextFieldAutoSize.LEFT;
tf.defaultTextFormat = new TextFormat("_sans", 12, 0xFFF9FF);
tf.antiAliasType = AntiAliasType.ADVANCED;
tf.text = "No Web Cam detected.";
tf.x = (mAppWidth - tf.width) >> 1;
tf.y = (mAppHeight - tf.height) >> 1;
addChild(tf);
}
private function initCam():Boolean
{
var camIndex:int = 0;
for ( var i:int = 0 ; i < Camera.names.length ; i++ ) {
if ( Camera.names[ i ] == "USB Video Class Video" ) {
camIndex = i;
break;
}
}
mWebCam = Camera.getCamera(String(camIndex));
if (!mWebCam) return false;
mWebCam.setMode(mVidSize, mVidSize, 24);
mVideo = new Video(mVidSize, mVidSize);
mVideo.attachCamera(mWebCam);
mVideoData = new BitmapData(mVideo.width, mVideo.height, false, 0x066000);
return true;
}
public function start():void
{
mWebCam.addEventListener(Event.VIDEO_FRAME, onFrame);
}
private function initBuffers():void
{
var vertices:Vector.<Number> = Vector.<Number>([
-1.0, -1.0, 0, 0, 0,
-1.0, 1.0, 0, 0, 1,
1.0, 1.0, 0, 1, 1,
1.0, -1.0, 0, 1, 0 ]);
mVBuffer = mContext.createVertexBuffer(4, 5);
mVBuffer.uploadFromVector(vertices, 0, 4);
mIBuffer = mContext.createIndexBuffer(6);
mIBuffer.uploadFromVector (Vector.<uint>([0, 1, 2, 2, 3, 0]), 0, 6);
}
private function initTexture():void
{
mTexture = mContext.createTexture(mVidSize, mVidSize, Context3DTextureFormat.BGRA, true);
}
private function initShader():void
{
var assembler:AGALMiniAssembler = new AGALMiniAssembler();
var vs:ByteArray = assembler.assemble(Context3DProgramType.VERTEX, VERT_SHADER);
var fs:ByteArray = assembler.assemble(Context3DProgramType.FRAGMENT, FRAGMENT_SHADER);
mProgram = mContext.createProgram();
mProgram.upload(vs, fs);
}
private var mVideoMat:Matrix3D = new Matrix3D();
public function onFrame(event:Event = null):void
{
if ( !mContext )
return;
mContext.clear(1.0, 1.0, 1.0, 1.0);
mVideoMat.identity();
mVideoMat.prependScale(1, -1, 1);
mVideoMat.appendScale(mVidSize / mAppWidth, mVidSize / mAppHeight, 1);
mVideoData.draw(mVideo);
mTexture.uploadFromBitmapData(mVideoData);
mContext.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, mVideoMat, true);
mContext.setVertexBufferAt(0, mVBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
mContext.setVertexBufferAt(1, mVBuffer, 3, Context3DVertexBufferFormat.FLOAT_2);
mContext.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, new <Number>[1, .2, .87, .3465], 1);
mContext.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, new <Number>[10/mVidSize, 5/mVidSize, 0, 1], 1);
mContext.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 2, new <Number>[1, 1, 1, 1], 1);
mContext.setTextureAt(0, mTexture);
mContext.setProgram(mProgram);
mContext.drawTriangles(mIBuffer);
mContext.present();
}
}
}