方向鍵可以控制車輛移動,
空白鍵停止。
車輛的材質還有反光效果。

demo
package
{
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.Context3DRenderMode;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.display3D.VertexBuffer3D;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.geom.Matrix3D;
import flash.geom.Vector3D;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.textures.Texture;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.net.URLRequest;
import flash.display.Loader;
import MonitorKit;
/**
* ...Flash 3D API(Molehill) 貼圖範例
* @author Max
*/
public class Flash3D_Texture extends Sprite
{
private var sta3D:Stage3D;
private var con3D:Context3D;
private var vertexBuffer:VertexBuffer3D;
private var indexBuffer:IndexBuffer3D;
private var perspection:PerspectiveMatrix3D;
private var modelProjection:Matrix3D;
private var modelView:Matrix3D;
private var texture:Texture;
private var loaderObj:Loader;
private var shaderpg3d:Program3D;
public function Flash3D_Texture()
{
addEventListener(Event.ADDED_TO_STAGE, onAddtoStage);
}
private function onAddtoStage(event:Event):void
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
sta3D = stage.stage3Ds[0];
sta3D.addEventListener(Event.CONTEXT3D_CREATE, onCreateContext3D);
sta3D.requestContext3D(Context3DRenderMode.AUTO);
var FPS:MonitorKit = new MonitorKit(MonitorKit.MKMODE_TL);
addChild(FPS);
}
private function onCreateContext3D(event:Event):void
{
con3D = sta3D.context3D;
con3D.enableErrorChecking = true;
initTexture();
}
private function initTexture():void
{
loaderObj = new Loader();
loaderObj.contentLoaderInfo.addEventListener(Event.COMPLETE,
onLoaderBmpComple);
loaderObj.load(new URLRequest("pic.jpg"));
}
private function onLoaderBmpComple(event:Event):void
{
var tmploaderBmp:Bitmap = event.target.content as Bitmap;
texture = con3D.createTexture( 256, 256,
Context3DTextureFormat.BGRA, false);
texture.uploadFromBitmapData(tmploaderBmp.bitmapData,0);
initMesh();
}
private function initMesh():void
{
var vertexShader:Array =["dp4 op.x, va0, vc0",
"dp4 op.y, va0, vc1",
"dp4 op.z, va0, vc2",
"dp4 op.w, va0, vc3",
"mov v0, va1.xyzw"];
var vertexAssembler:AGALMiniAssembler = new AGALMiniAssembler();
vertexAssembler.assemble(flash.display3D.Context3DProgramType.VERTEX,
vertexShader.join("\n"));
var fragmentShader:Array =["mov ft0, v0\n",
"tex ft1, ft0, fs1 <2d,clamp,linear>\n",
"mov oc, ft1\n"];
var fragmentAssembler:AGALMiniAssembler = new AGALMiniAssembler();
fragmentAssembler.assemble(flash.display3D.Context3DProgramType.FRAGMENT,
fragmentShader.join("\n"));
shaderpg3d = con3D.createProgram();
shaderpg3d.upload(vertexAssembler.agalcode, fragmentAssembler.agalcode);
indexBuffer = con3D.createIndexBuffer(6);
indexBuffer.uploadFromVector(Vector.([0, 1, 2, 0, 2, 3]), 0, 6);
vertexBuffer = con3D.createVertexBuffer(4, 4);
vertexBuffer.uploadFromVector(Vector.([-1.0, 1.0,0.0,1.0,
-1.0,-1.0,0.0,0.0,
1.0,-1.0,1.0,0.0,
1.0, 1.0,1.0,1.0]),0,4);
con3D.setVertexBufferAt( 0, vertexBuffer, 0,
Context3DVertexBufferFormat.FLOAT_2);
con3D.setVertexBufferAt( 1, vertexBuffer, 2,
Context3DVertexBufferFormat.FLOAT_2);
con3D.setTextureAt(1, texture);
addEventListener(Event.ENTER_FRAME, on3DRender);
stage.addEventListener(Event.RESIZE, onResizeStage);
onResizeStage();
}
private function drawMesh():void
{
con3D.setProgram(shaderpg3d);
modelView = new Matrix3D();
modelView.identity();
modelView.position = new Vector3D(0, 0, 2, 1);
modelView.appendScale(1, -1, 1);
perspection = new PerspectiveMatrix3D();
perspection.identity();
perspection.perspectiveLH(5.5, 4, 1, 100);
modelProjection = new Matrix3D();
modelProjection.identity();
modelProjection.position = new Vector3D(0, 0, 0, 1);
modelProjection.appendRotation(stage.mouseX/4,
new Vector3D(0, 1, 0, 1),null);
modelProjection.append(modelView);
modelProjection.append(perspection);
con3D.setCulling("none");
con3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX,
0,modelProjection,true);
con3D.drawTriangles(indexBuffer, 0, 2);
}
private function onResizeStage(event:Event=null):void
{
con3D.configureBackBuffer(stage.stageWidth, stage.stageHeight,2,true);
sta3D.viewPort = new Rectangle(0,0,stage.stageWidth,stage.stageHeight);
on3DRender();
}
private function on3DRender(event:Event=null):void
{
con3D.clear(0.0, 0.0, 0.5, 1.0);
drawMesh();
con3D.present();
}
}
}

package
{
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.Context3DTextureFormat;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.VertexBuffer3D;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.Rectangle;
import flash.geom.Vector3D;
public class Flash3D_DrawMesh extends Sprite
{
private var sta3D:Stage3D;
private var con3D:Context3D;
private var indexBuffer:IndexBuffer3D;
private var perspection:PerspectiveMatrix3D;
private var modelProjection:Matrix3D;
private var modelView:Matrix3D;
private var ro:Number = 5;
public function Flash3D_DrawMesh()
{
addEventListener(Event.ADDED_TO_STAGE, onAddtoStage);
}
public function onAddtoStage(event:Event):void
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.frameRate = 30;
sta3D = stage.stage3Ds[0];
sta3D.addEventListener(Event.CONTEXT3D_CREATE,onCreateContext3D);
sta3D.requestContext3D(Context3DRenderMode.AUTO);
var FPS:MonitorKit = new MonitorKit(MonitorKit.MKMODE_TL);
addChild(FPS);
}
public function onCreateContext3D(event:Event):void
{
con3D = sta3D.context3D;
con3D.enableErrorChecking = true;
initMesh();
addEventListener(Event.ENTER_FRAME,on3DRender);
stage.addEventListener(Event.RESIZE,onResizeStage);
onResizeStage();
}
public function onResizeStage(event:Event = null):void
{
con3D.configureBackBuffer(stage.stageWidth,stage.stageHeight,2,true);
sta3D.viewPort = new Rectangle(0,0,stage.stageWidth,stage.stageHeight);
on3DRender();
}
public function initMesh():void
{
var vertexAssembler:AGALMiniAssembler = new AGALMiniAssembler();
vertexAssembler.assemble(Context3DProgramType.VERTEX,"m44 op,va0,vc \n"+
"mov v0,va1");
var fragmentAssembler:AGALMiniAssembler = new AGALMiniAssembler();
fragmentAssembler.assemble(Context3DProgramType.FRAGMENT,"mov oc,v0");
var vertexBuffer:VertexBuffer3D = con3D.createVertexBuffer(4,6);
vertexBuffer.uploadFromVector(Vector.([-1, 1,0,1,0,0,
-1,-1,0,1,1,0,
1,-1,0,1,0,1,
1, 1,0,1,0,0]),0,4);
con3D.setVertexBufferAt(0,vertexBuffer,0,
Context3DVertexBufferFormat.FLOAT_3);
con3D.setVertexBufferAt(1,vertexBuffer,3,
Context3DVertexBufferFormat.FLOAT_3);
indexBuffer= con3D.createIndexBuffer(6);
indexBuffer.uploadFromVector(Vector.([0,1,2,0,2,3]),0,6);
var program:Program3D = con3D.createProgram();
program.upload(vertexAssembler.agalcode,fragmentAssembler.agalcode);
con3D.setProgram(program);
modelView = new Matrix3D();
modelView.identity();
perspection = new PerspectiveMatrix3D();
perspection.identity();
perspection.perspectiveLH(5.5, 4, 1, 10000);
modelProjection = new Matrix3D();
}
private function drawMesh():void
{
modelView.position = new Vector3D(0,0,1.5,1);
modelView.appendRotation(ro,Vector3D.Z_AXIS, null);
modelProjection.identity();
modelProjection.append(modelView);
modelProjection.append(perspection);
con3D.setCulling("front");
con3D.setProgramConstantsFromMatrix( Context3DProgramType.VERTEX,
0,modelProjection,true);
con3D.drawTriangles(indexBuffer,0,2);
}
private function on3DRender(event:Event=null):void
{
con3D.clear(0.0, 0.0, 0.5, 1.0);
drawMesh();
con3D.present();
}
}
}


package
{
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.Context3DTextureFormat;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.VertexBuffer3D;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.Rectangle;
import flash.geom.Vector3D;
public class Flash3D_DrawTriangle extends Sprite
{
private var sta3D:Stage3D;
private var con3D:Context3D;
private var vertexBuffer:VertexBuffer3D;
private var indexBuffer:IndexBuffer3D;
private var modelView:Matrix3D;
private var modelProjection:Matrix3D;
private var perspection:PerspectiveMatrix3D;
private var ro:Number = 5;
private var pos:Vector3D;
public function Flash3D_DrawTriangle()
{
addEventListener(Event.ADDED_TO_STAGE, onAddtoStage);
}
public function onAddtoStage(event:Event):void
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.frameRate = 30;
sta3D = stage.stage3Ds[0];
sta3D.addEventListener(Event.CONTEXT3D_CREATE, onCreateContext3D);
sta3D.requestContext3D(Context3DRenderMode.AUTO);
var FPS:MonitorKit = new MonitorKit(MonitorKit.MKMODE_TL);
addChild(FPS);
}
public function onCreateContext3D(event:Event):void
{
con3D = sta3D.context3D;
con3D.enableErrorChecking = true;
initMesh();
addEventListener(Event.ENTER_FRAME, on3DRender);
stage.addEventListener(Event.RESIZE, onResizeStage);
onResizeStage();
}
public function onResizeStage(event:Event = null):void
{
con3D.configureBackBuffer(stage.stageWidth, stage.stageHeight, 2, true);
sta3D.viewPort = new Rectangle(0,0,stage.stageWidth, stage.stageHeight);
on3DRender();
}
public function initMesh():void
{
var vertexAssembler:AGALMiniAssembler = new AGALMiniAssembler();
vertexAssembler.assemble(Context3DProgramType.VERTEX,"m44 op,va0,vc0 \n"+
"mov v0,va1");
var fragmentAssembler:AGALMiniAssembler = new AGALMiniAssembler();
fragmentAssembler.assemble(Context3DProgramType.FRAGMENT,"mov oc,v0");
vertexBuffer = con3D.createVertexBuffer(3,6);
vertexBuffer.uploadFromVector(Vector.([ 0, 1,0,1,0,0,
-1,-1,0,0,1,0,
1,-1,0,0,0,1,]),0, 3);
con3D.setVertexBufferAt(0,vertexBuffer,0,
Context3DVertexBufferFormat.FLOAT_3);
con3D.setVertexBufferAt(1,vertexBuffer,3,
Context3DVertexBufferFormat.FLOAT_3);
indexBuffer = con3D.createIndexBuffer(3);
indexBuffer.uploadFromVector(Vector.([0,1,2]),0,3);
var program:Program3D = con3D.createProgram();
program.upload(vertexAssembler.agalcode,fragmentAssembler.agalcode);
con3D.setProgram(program);
modelView = new Matrix3D();
modelView.identity();
pos = new Vector3D(0,0,2,1);
perspection = new PerspectiveMatrix3D();
perspection.identity();
perspection.perspectiveLH(2.8,2,1,10000);
}
public function DrawMesh():void
{
modelView.position = pos;
modelView.appendRotation(ro,Vector3D.Y_AXIS, null);
modelProjection = new Matrix3D();
modelProjection.identity();
modelProjection.append(modelView);
modelProjection.append(perspection);
con3D.setCulling("none");
con3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX,
0,modelProjection,true);
con3D.drawTriangles(indexBuffer,0,-1);
}
public function on3DRender(event:Event):void
{
con3D.clear(0.0, 0.0, 0.5, 1.0);
DrawMesh();
con3D.present();
}
}
}


package
{
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display3D.Context3D;
import flash.display3D.Context3DRenderMode;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.Rectangle;
import MonitorKit;
/**
* ...Flash 3D Framework
* @author Max
*/
public class Flash3D_Framework extends Sprite
{
private var sta3D:Stage3D;
private var con3D:Context3D;
public function Flash3D_Framework():void
{
addEventListener(Event.ADDED_TO_STAGE, onAddtoStage);
}
public function onAddtoStage(event:Event):void
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
sta3D = stage.stage3Ds[0];
sta3D.addEventListener(Event.CONTEXT3D_CREATE, onCreateContext3D);
sta3D.requestContext3D(Context3DRenderMode.AUTO);
// 設定FPS
var FPS:MonitorKit = new MonitorKit(MonitorKit.MKMODE_TL);
addChild(FPS);
}
public function onCreateContext3D(event:Event):void
{
con3D = sta3D.context3D;
con3D.enableErrorChecking = true;
addEventListener(Event.ENTER_FRAME, on3DRender);
stage.addEventListener(Event.RESIZE, onResizeStage);
onResizeStage();
}
public function onResizeStage(event:Event = null):void
{
// 設定背景緩衝
con3D.configureBackBuffer(stage.stageWidth, stage.stageHeight, 2, true);
// 讓成像大小等於stage的大小
sta3D.viewPort = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
on3DRender();
}
// 3D渲染
public function on3DRender(event:Event = null):void
{
// 設定3D背景色(rgba)
con3D.clear(0.0, 0.0, 0.5, 1.0);
// ...
// 要繪製3D的處理可以加在這...
// ...
con3D.present();
}
}
}