/**
* Copyright lizhi ( http://wonderfl.net/user/lizhi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/zwsW
*/
package {
import com.adobe.utils.AGALMiniAssembler;
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display3D.Context3D;
import flash.display3D.Context3DCompareMode;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DStencilAction;
import flash.display3D.Context3DTriangleFace;
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.geom.Vector3D;
/**
* ...
* @author lizhi
*/
public class Stage3dStencilTest extends Sprite
{
private var stage3D:Stage3D;
private var context3D:Context3D;
private var vertexBuffer:VertexBuffer3D;
private var indexBuffer:IndexBuffer3D;
private var program:Program3D;
private var texture:Texture;
private var ss:Vector.<Sprite3D> = new Vector.<Sprite3D>;
public function Stage3dStencilTest()
{
super();
if (stage) {
init(null);
}else {
addEventListener(Event.ADDED_TO_STAGE, init);
}
}
private function init(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
stage3D = stage.stage3Ds[0];
stage3D.addEventListener(Event.CONTEXT3D_CREATE, stage3D_context3dCreate);
stage3D.requestContext3D();
}
private function stage3D_context3dCreate(e:Event):void
{
context3D = stage3D.context3D;
context3D.enableErrorChecking = true;
context3D.configureBackBuffer(400, 400, 0, true);
addEventListener(Event.ENTER_FRAME, enterFrame);
var minia:AGALMiniAssembler = new AGALMiniAssembler
program = context3D.createProgram();
program.upload(minia.assemble(Context3DProgramType.VERTEX,
<![CDATA[
m44 op, va0, vc0
]]>),
minia.assemble(Context3DProgramType.FRAGMENT,
<![CDATA[
mov oc,fc0
]]>
));
vertexBuffer = context3D.createVertexBuffer(4, 3);
vertexBuffer.uploadFromVector(new <Number>[
-1., -1, 0,
1, -1, 0,
-1,1,0,
1,1,0]
, 0, 4);
indexBuffer = context3D.createIndexBuffer(6);
indexBuffer.uploadFromVector(new <uint>[0, 1, 2, 1, 3, 2], 0, 6);
context3D.setProgram(program);
context3D.setVertexBufferAt(0, vertexBuffer,0,Context3DVertexBufferFormat.FLOAT_3);
var s:Sprite3D = new Sprite3D;
ss.push(s);
s.color = new <Number>[1,0,0,1];
s = new Sprite3D;
s.x = 50;
ss.push(s);
}
private function enterFrame(e:Event) :void
{
context3D.clear(0,0,0,0,1,0);
for (var i:int = 0; i < ss.length;i++ ) {
var s:Sprite3D = ss[i];
s.rotation++;
context3D.setDepthTest(true, Context3DCompareMode.LESS_EQUAL);
if (i == 0) {
context3D.setStencilActions(Context3DTriangleFace.FRONT_AND_BACK, Context3DCompareMode.ALWAYS, Context3DStencilAction.SET, Context3DStencilAction.KEEP, Context3DStencilAction.KEEP);
context3D.setStencilReferenceValue(1,0xff,0xff);
}else {
context3D.setStencilActions(Context3DTriangleFace.FRONT_AND_BACK, Context3DCompareMode.EQUAL, Context3DStencilAction.KEEP, Context3DStencilAction.KEEP, Context3DStencilAction.KEEP);
context3D.setStencilReferenceValue(1,0xff,0xff);
}
draw(s);
}
context3D.present();
}
private function draw(s:Sprite3D):void {
var matr:Matrix3D = new Matrix3D;
matr.appendScale(s.width / 400, -s.height / 400, 1);
matr.appendRotation( -s.rotation , Vector3D.Z_AXIS);
matr.appendTranslation(s.x/200,-s.y/200,0);
context3D.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0,s.color);
context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, matr, true);
context3D.drawTriangles(indexBuffer);
}
}
}
class Sprite3D {
public var x:Number = 0;
public var y:Number = 0;
public var rotation:Number = 0;
public var width:Number = 100;
public var height:Number = 100;
public var color:Vector.<Number> = new <Number>[1,1,1,1];
}