package { //参考元: Adobe Flash Platform 用 ActionScript® 3.0 リファレンスガイド //参考元: http://help.adobe.com/ja_JP/FlashPlatform/reference/actionscript/3/flash/display3D/Context3D.html //参考元: の Context3DExample.as を元に変更してあります import com.adobe.utils.AGALMiniAssembler; import com.adobe.utils.PerspectiveMatrix3D; import flash.display.Sprite; import flash.display.Stage3D; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.display3D.Context3D; import flash.display3D.Context3DProgramType; import flash.display3D.Context3DRenderMode; import flash.display3D.Context3DTriangleFace; import flash.display3D.Context3DVertexBufferFormat; import flash.display3D.IndexBuffer3D; import flash.display3D.Program3D; import flash.display3D.VertexBuffer3D; import flash.events.ErrorEvent; import flash.events.Event; import flash.geom.Matrix3D; import flash.geom.Vector3D; import flash.display3D.textures.Texture; import flash.display3D.Context3DTextureFormat; import flash.display3D.Context3DBlendFactor; public class Main extends Sprite { [Embed(source="demo.png")] static private const EmbedTexture:Class; public const viewWidth:Number = 600; public const viewHeight:Number = 400; public const zNear:Number = 1; public const zFar:Number = 500; public const fov:Number = 45; private var stage3D:Stage3D; private var renderContext:Context3D; private var indexList:IndexBuffer3D; private var vertexes:VertexBuffer3D; private var projection:PerspectiveMatrix3D = new PerspectiveMatrix3D(); private var model:Matrix3D = new Matrix3D(); private var view:Matrix3D = new Matrix3D(); private var finalTransform:Matrix3D = new Matrix3D(); //For rotating the cube private const pivot:Vector3D = new Vector3D(); private const VERTEX_SHADER:String = "m44 op, va0, vc0 \n" + // 4x4 matrix transform "mov v0, va1"; //copy color to varying variable v0 private const FRAGMENT_SHADER:String = //"mov oc, v0"; //Set the output color to the value interpolated from the three triangle vertices "mov ft0 v0\n" + "tex ft0, ft0, fs0<2d,clamp,linear>\n" + "mov oc ft0\n"; private var vertexAssembly:AGALMiniAssembler = new AGALMiniAssembler(); private var fragmentAssembly:AGALMiniAssembler = new AGALMiniAssembler(); private var programPair:Program3D; public function Main() { this.stage.scaleMode = StageScaleMode.NO_SCALE; this.stage.align = StageAlign.TOP_LEFT; //this.stage.nativeWindow.activate(); //AIR only stage3D = this.stage.stage3Ds[0]; stage3D.x = 10; stage3D.y = 10; //Add event listener before requesting the context stage3D.addEventListener( Event.CONTEXT3D_CREATE, contextCreated ); stage3D.addEventListener( ErrorEvent.ERROR, contextCreationError ); stage3D.requestContext3D( Context3DRenderMode.AUTO ); //Compile shaders vertexAssembly.assemble( Context3DProgramType.VERTEX, VERTEX_SHADER, false ); fragmentAssembly.assemble( Context3DProgramType.FRAGMENT, FRAGMENT_SHADER, false ); } //Note, context3DCreate event can happen at any time, such as when the hardware resources are taken by another process private function contextCreated( event:Event ):void { renderContext = Stage3D( event.target ).context3D; trace( "3D driver: " + renderContext.driverInfo ); setupScene(); } private function setupScene():void { renderContext.enableErrorChecking = true; //Can slow rendering - only turn on when developing/testing renderContext.configureBackBuffer( viewWidth, viewHeight, 2, false ); renderContext.setCulling( Context3DTriangleFace.BACK ); //Create vertex index list for the triangles forming a cube var triangles:Vector. = Vector.( [ 2,1,0, //front face 3,2,0, 4,7,5, //left face 7,6,5, 8,11,9, //back face 9,11,10, 12,15,13, //right face 13,15,14, 16,19,17, //bottom face 17,19,18, /* 20,23,21, //top face 21,23,22 */ ] ); //double side face 両面化 triangles = triangles.concat().reverse(); //面を裏返す (内側の面) triangles = triangles.concat(triangles.concat().reverse()); //内側の面の集合の後に 外側の面 (元の面) を足す indexList = renderContext.createIndexBuffer( triangles.length ); indexList.uploadFromVector( triangles, 0, triangles.length ); //Create vertexes - cube faces do not share vertexes const dataPerVertex:int = 5; var vertexData:Vector. = Vector.( [ // x,y,z u,v format 0,0,0, 0,0, //front face 0,1,0, 0,.374, 1,1,0, .374,.374, 1,0,0, .374,0, 0,1,1, .749,.374, //left face 0,1,0, .749,0, 0,0,0, .376,0, 0,0,1, .376,.374, 0,0,1, 0,.376, //back face 1,0,1, .374,.376, 1,1,1, .374,.749, 0,1,1, 0,.749, 1,1,0, .749,.376, //right face 1,1,1, .749,.749, 1,0,1, .376,.749, 1,0,0, .376,.376, 0,0,0, .751,0, //bottom face 1,0,0, 1,0, 1,0,1, 1,.374, 0,0,1, .751,.374, 0,1,1, 0,1, //top face 1,1,1, 1,1, 1,1,0, 1,0, 0,1,0, 0,0, ] ); vertexes = renderContext.createVertexBuffer( vertexData.length/dataPerVertex, dataPerVertex ); vertexes.uploadFromVector( vertexData, 0, vertexData.length/dataPerVertex ); //Upload programs to render context programPair = renderContext.createProgram(); programPair.upload( vertexAssembly.agalcode, fragmentAssembly.agalcode ); renderContext.setProgram( programPair ); // //texture var texture:Texture = renderContext.createTexture(512, 512, Context3DTextureFormat.BGRA, false); texture.uploadFromBitmapData(new EmbedTexture().bitmapData); renderContext.setTextureAt(0, texture); //Identify vertex data inputs for vertex program renderContext.setVertexBufferAt( 0, vertexes, 0, Context3DVertexBufferFormat.FLOAT_3 ); //va0 is position renderContext.setVertexBufferAt( 1, vertexes, 3, Context3DVertexBufferFormat.FLOAT_2 ); //va1 is UV //alpha blend for transparent mapping 透明マッピング用 アルファブレンドで drawTriangles() renderContext.setBlendFactors( Context3DBlendFactor.SOURCE_ALPHA, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA ); //alpha //Set up 3D transforms projection.perspectiveFieldOfViewRH( fov, viewWidth/viewHeight, zNear, zFar ); view.appendTranslation( 0, 0, -2 ); //Move view back model.appendTranslation( -.5, -.5, -.5 ); //center cube on origin this.stage.addEventListener( Event.ENTER_FRAME, render ); } private function render( event:Event ):void { //Rotate model on each frame model.appendRotation( .12, Vector3D.Z_AXIS, pivot ); model.appendRotation( .31, Vector3D.Y_AXIS, pivot ); model.appendRotation( .5, Vector3D.X_AXIS, pivot ); //view.appendTranslation( 0,0,-.01 ); //Combine transforms finalTransform.identity(); finalTransform.append( model ); finalTransform.append( view ); finalTransform.append( projection ); //Pass the final transform to the vertex shader as program constant, vc0 renderContext.setProgramConstantsFromMatrix( Context3DProgramType.VERTEX, 0, finalTransform, true ); //Clear is required before drawTriangles on each frame renderContext.clear( .7,.3,.3 ); //Draw the 12 triangles that make up the cube //renderContext.drawTriangles( indexList, 0, 12 ); renderContext.drawTriangles( indexList, 0, -1 ); //Show the frame renderContext.present(); } private function contextCreationError( error:ErrorEvent ):void { trace( error.errorID + ": " + error.text ); } } }