测试一下代码
package
{
import com.adobe.utils.AGALMiniAssembler;
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display3D.Context3D;
import flash.display3D.Context3DProfile;
import flash.display3D.Context3DRenderMode;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.VertexBuffer3D;
import flash.events.ErrorEvent;
import flash.events.Event;
[SWF(width=800, height=600, frameRate=60)]
public class DrawTriangle extends Sprite
{
//3D 场景对象
private var _stage3D:Stage3D;
//3D 上下文渲染对象
private var _context3D:Context3D;
//顶点缓冲数据
private var _vertexBuffer:VertexBuffer3D;
//索引缓冲数据
private var _indexBuffer:IndexBuffer3D;
//着色器对象
private var _program3D:Program3D;
public function DrawTriangle()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function addedToStageHandler(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
//3D 场景存在, 一般存在 4 个 3D 场景对象
if(stage.stage3Ds.length > 0)
{
//使用最下层的 3D 场景
_stage3D = stage.stage3Ds[0];
//请求 3D 上下文渲染对象
_stage3D.addEventListener(ErrorEvent.ERROR, stage3DErrorHandler);
_stage3D.addEventListener(Event.CONTEXT3D_CREATE, context3DCreateHandler);
_stage3D.requestContext3D(Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
}
}
private function stage3DErrorHandler(event:ErrorEvent):void
{
trace("Context3D对象请求失败:", event.text);
}
private function context3DCreateHandler(event:Event):void
{
initContext3D();
initBuffer();
initProgram();
//每帧进行渲染
addEventListener(Event.ENTER_FRAME, render);
}
private function initContext3D():void
{
//获取 3D 渲染对象
_context3D = _stage3D.context3D;
//调整 3D 舞台位置
_stage3D.x = 50;
_stage3D.y = 50;
//设置后台缓冲区
_context3D.configureBackBuffer(700, 500, 2);
}
private function initBuffer():void
{
//顶点数据
var vertexData:Vector.<Number> = Vector.<Number>(
[
// x, y, z, r, g, b
0, 0, 0, 1, 0, 0,
1, 1, 0, 0, 1, 0,
1, 0, 0, 0, 0, 1
]);
//创建顶点缓冲对象, 参数设定存在几组数据和每组数据的个数
_vertexBuffer = _context3D.createVertexBuffer(vertexData.length / 6, 6);
//上传顶点数据到GPU, 参数设定从第几组数据开始上传和上传多少组数据
_vertexBuffer.uploadFromVector(vertexData, 0, vertexData.length / 6);
//索引数据
var indexData:Vector.<uint> = Vector.<uint>(
[
0, 1, 2
]);
//创建索引缓冲对象, 每个索引对应顶点数据中的相对应的一组数据,
//每3个索引组成一个会被绘制出来的三角形, 参数指定索引的长度
_indexBuffer = _context3D.createIndexBuffer(indexData.length);
//上传索引数据到GPU, 参数设定从第几个数据开始上传和上传多少个数据
_indexBuffer.uploadFromVector(indexData, 0, 3);
}
private function initProgram():void
{
//顶点着色器代码, 每个上传的顶点前都会执行一次该代码
var vertexArr:Array =
[
//op 代表位置输出寄存器, 无论对顶点进行多少次的运算最终都要将结果
//赋值给他, 这里我们不进行运行, 直接赋值
"mov op, va0",
//片段着色器需要用的数据要在这里通过 v0 中转一下, 因为片段着色器不
//能直接读取 va0 和 va1 的数据
"mov v0, va1"
];
//片段着色器代码, 每个可以显示的像素都会执行一次该代码
var fragmentArr:Array =
[
//oc 代表颜色输出寄存器, 每个顶点的颜色数据都要赋值给他
"mov oc, v0"
];
//使用 Adobe 自己提供的编译器编译代码为程序可使用的二进制数据
var assembler:AGALMiniAssembler = new AGALMiniAssembler();
_program3D = assembler.assemble2(_context3D, 1, vertexArr.join("\n"), fragmentArr.join("\n"));
}
private function render(event:Event):void
{
//清除已绘制过的 3D 图像
_context3D.clear(0, 0, 0);
//指定着色器代码的 va0 代表的数据段, 以一组顶点数据为基础来看
_context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_3);
//指定着色器代码的 va1 代表的数据段, 以一组顶点数据为基础来看
_context3D.setVertexBufferAt(1, _vertexBuffer, 3, Context3DVertexBufferFormat.FLOAT_3);
//指定当前使用的着色器对象
_context3D.setProgram(_program3D);
//通过顶点索引数据绘制所有的三角形
_context3D.drawTriangles(_indexBuffer);
//将后台缓冲的图像显示到屏幕
_context3D.present();
}
}
}

浙公网安备 33010602011771号