package
{
import com.adobe.pixelBender3D.AGALProgramPair;
import com.adobe.pixelBender3D.PBASMCompiler;
import com.adobe.pixelBender3D.PBASMProgram;
import com.adobe.pixelBender3D.RegisterMap;
import com.adobe.pixelBender3D.utils.VertexBufferHelper;
import com.adobe.pixelBender3D.utils.ProgramConstantsHelper;
import com.adobe.pixelBender3D.VertexRegisterInfo;
import com.adobe.utils.PerspectiveMatrix3D;
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display3D.Context3D;
import flash.display3D.Context3DCompareMode;
import flash.display3D.Context3DTriangleFace;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.VertexBuffer3D;
import flash.display3D.Context3DRenderMode;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DBlendFactor;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.geom.Vector3D;
import flash.geom.Matrix3D;
import flash.utils.getTimer;
import flash.utils.Timer;
import ExampleUtils;
public class Main extends Sprite
{
[Embed (source="./vp_triangle.pbasm", mimeType="application/octet-stream")]
protected static const VertexPositionProgram : Class;
[Embed (source="./mv_triangle.pbasm", mimeType="application/octet-stream")]
protected static const VertexMaterialProgram : Class;
[Embed (source="./mf_triangle.pbasm", mimeType="application/octet-stream")]
protected static const FragmentMaterialProgram : Class;
public static const WIDTH:int = 400;
public static const HEIGHT:int = 400;
// molehill-related variables
private var context3D_ : Context3D;
private var indexBuffer_ : IndexBuffer3D;
private var rendertimer_ : Timer;
private var shaderProgram_ : Program3D;
private var vertexBuffer_ : VertexBuffer3D;
private var _stage3D:Stage3D;
// PB3D-related variables
private var vertexRegisterMap_ : RegisterMap;
private var fragmentRegisterMap_ : RegisterMap;
private var vertexBufferMap_ : VertexBufferHelper;
public var parameterBufferHelper_ : ProgramConstantsHelper;
private var _matProjection:PerspectiveMatrix3D;
private var _camera:Camera;
public function Main()
{
_stage3D = stage.stage3Ds[0];
_stage3D.addEventListener( Event.CONTEXT3D_CREATE, Context3DCreateHandler );
_stage3D.requestContext3D( Context3DRenderMode.AUTO );
}
private function Context3DCreateHandler(e:Event) : void
{
context3D_ = _stage3D.context3D;
init();
}
public function init():void
{
context3D_ = _stage3D.context3D;
context3D_.enableErrorChecking = true;
context3D_.configureBackBuffer( WIDTH, HEIGHT, 4, true );
context3D_.setCulling(Context3DTriangleFace.BACK);
context3D_.setBlendFactors(Context3DBlendFactor.SOURCE_ALPHA, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA );
context3D_.setDepthTest(false, Context3DCompareMode.ALWAYS);
setupShadingPrograms();
setupGeometry();
InitCamera();
InitProjection();
vertexBufferMap_ = new VertexBufferHelper(context3D_,
vertexRegisterMap_.inputVertexRegisters,
vertexBuffer_
);
// at this point, our Triangle object has sufficient information to do
// its job when the render calls start coming in, so let's get them
// going
rendertimer_ = new Timer(1);
rendertimer_.addEventListener(TimerEvent.TIMER, frameEventHandler);
rendertimer_.start();
}
private function frameEventHandler(event : Event) : void
{
render(getTimer());
}
private var cnt:int = 0;
public function render(time : Number) : void
{
context3D_.clear(0, 0, 0, 0);
var mat:Matrix3D = new Matrix3D();
mat.appendRotation(cnt++, new Vector3D(0, 1, 0)); // ワールド座標変換
mat.append( _camera.matrix ); // ビュー座標変換
mat.append( _matProjection ); // プロジェクション座標変換
parameterBufferHelper_.setMatrixParameterByName(
Context3DProgramType.VERTEX,
"objectToClipSpaceTransform",
mat,
true
);
parameterBufferHelper_.update();
context3D_.setProgram(shaderProgram_);
vertexBufferMap_.setVertexBuffers();
context3D_.drawTriangles(indexBuffer_, 0, 1);
context3D_.present();
}
private function setupGeometry() : void
{
indexBuffer_ = context3D_.createIndexBuffer(3);
indexBuffer_.uploadFromVector(Vector.([0, 1, 2]), 0, 3);
vertexBuffer_ = context3D_.createVertexBuffer(3, 8); // 3 vertices, XYZW, RGBA
var size:Number = 0.5;
vertexBuffer_.uploadFromVector(Vector.([ -1 * size, -1 * size, 0 * size, 1, 1, 0, 0, 1,
0 * size, 1 * size, 0 * size, 1, 0, 1, 0, 1,
1 * size, -1 * size, 0 * size, 1, 0, 0, 1, 1]), 0, 3
);
}
private function setupShadingPrograms() : void
{
var vertexPositionProgram : PBASMProgram;
var vertexMaterialProgram : PBASMProgram;
var fragmentMaterialProgram : PBASMProgram;
vertexPositionProgram = ExampleUtils.resourceToPBASMProgram(VertexPositionProgram);
vertexMaterialProgram = ExampleUtils.resourceToPBASMProgram(VertexMaterialProgram);
fragmentMaterialProgram = ExampleUtils.resourceToPBASMProgram(FragmentMaterialProgram);
var translatedPrograms : AGALProgramPair;
translatedPrograms = PBASMCompiler.compile(vertexPositionProgram,
vertexMaterialProgram,
fragmentMaterialProgram);
// we'll need these in order to set variables without resorting to low
// level molehill calls. A later example will show PB3D use
// without use of RegisterMap objects.
vertexRegisterMap_ = translatedPrograms.vertexProgram.registers;
fragmentRegisterMap_ = translatedPrograms.fragmentProgram.registers;
// we've now translated everything to AGAL, the binary format that
// molehill accepts, so let's create a Molehill shader program and upload
// our binaries
parameterBufferHelper_ = new ProgramConstantsHelper( context3D_, vertexRegisterMap_, fragmentRegisterMap_ );
shaderProgram_ = context3D_.createProgram();
shaderProgram_.upload(translatedPrograms.vertexProgram.byteCode,
translatedPrograms.fragmentProgram.byteCode);
}
private function InitProjection() : void
{
_matProjection = new PerspectiveMatrix3D();
_matProjection.perspectiveFieldOfViewLH( 45 * Math.PI / 180, WIDTH / HEIGHT, 0.1, 3000 );
}
/**
* カメラの初期化を行う
*/
private function InitCamera() : void
{
_camera = new Camera();
// カメラ位置、注視点
_camera.InitView( new Vector3D(0, 0, -3), new Vector3D(0, 0, 0), new Vector3D(0, 1, 0) );
}
}
}
import flash.display.BitmapData;
import flash.display.Shape;
import flash.display3D.Context3D;
import flash.display3D.textures.Texture;
import flash.display3D.IndexBuffer3D;
import flash.display3D.VertexBuffer3D;
import flash.display3D.Context3DTextureFormat;
import flash.geom.Matrix;
import flash.geom.Matrix3D;
import flash.geom.Vector3D;
class Camera
{
private var _view:Matrix3D;
private var _from:Vector3D;
private var _at:Vector3D;
private var _up:Vector3D;
public function Camera()
{
_view = new Matrix3D();
}
/**
* ビュー行列の設定を行う
*/
public function InitView( from:Vector3D, at:Vector3D, up:Vector3D ) : void
{
var vz:Vector3D = at.subtract( from );
vz.normalize();
var vx:Vector3D = up.crossProduct( vz );
vx.normalize();
var vy:Vector3D = vz.crossProduct( vx );
vy.normalize();
var vtx:Number = vx.dotProduct( from ) * -1;
var vty:Number = vy.dotProduct( from ) * -1;
var vtz:Number = vz.dotProduct( from ) * -1;
_view.identity();
_view.rawData = Vector.([
vx.x, vy.x, vz.x, 0,
vx.y, vy.y, vz.y, 0,
vx.z, vy.z, vz.z, 0,
vtx, vty, vtz, 1,
]);
_from = from;
_at = at;
_up = up;
}
public function get matrix():Matrix3D
{
return _view;
}
public function get from() : Vector3D
{
return _from;
}
public function get at() : Vector3D
{
return _at;
}
}