我叫AGAL,来自Adobe 【Part2】

来源:互联网 发布:淘宝qq空间推广 编辑:程序博客网 时间:2024/04/30 11:22

在本系列的part1中,我讨论了一些AGAL主要概念。
AGAL现在还是有点神秘…文档很少,但它确实很强大。
在flash发布之初,即使是释放出这种脚本语言全部的能力,它还是不尽如人意,这就是flash,它可以说是一个运行很慢的东西。但AGAL能运算到GPU有多快,它就有多快。

问题是,它是一个汇编语言。所以它很难掌握,而且也不能像使用我们熟悉的actionscript那样直观。

可能初一看起来,AGAL像一条条象形文字。希望这个问题在part1已经有所解决。如果你通过了,你应该知道有关的操作码和寄存器,并感觉更熟悉它。

但是试想一下,如果你正在处理外星文明的语言…有着不同的文化…你还缺少什么才能与他们沟通?

对…还缺少与他们沟通的门户…你的星际之门。

你的语言是ActionScript。他们的语言AGAL,星际之门正是MoleHill API。

欢迎来到跨星系编码!

着色器的Actionscript端编程

在Molehill中,所有的渲染都需要着色器来完成,没有着色器,就无法渲染。而Molehill API都是用来让着色器运行的,这说明AGAL与着色器在MoleHill中处于多么核心的位置。

在part1中的超简单着色器:

//vertex shaderm44 op, va0, vc0 // pos to clipspacemov v0, va1 // copy uv//pixel shadertex ft1, v0, fs0 <2d,linear,nomip>mov oc, ft1

现在我们希望从ActionScript运行它…。

第一件事情,你需要通过顶点集描述一个几何形。

假设你要显示一个由四个顶点组成的正方形。

var vertices:Vector. = Vector.([-0.5,-0.5,0, 0, 0, // x, y, z, u, v-0.5, 0.5, 0, 0, 1,0.5, 0.5, 0, 1, 1,0.5, -0.5, 0, 1, 0]);

每个顶点由X,Y,Z轴位置,和U,V纹理坐标构成。

这些顶点存储到一个VertexBuffer3D

// 4 vertices, of 5 Numbers eachvar vertexbuffer:VertexBuffer3D = context3D.createVertexBuffer(4, 5);

通过context3D被上传到GPU。

vertexbuffer.uploadFromVector(vertices, 0, 4);

然后,您需要定义三角形,我们通过索引缓冲区来实现。

// total of 6 indices. 2 triangles by 3 vertices eachvar indexbuffer:IndexBuffer3D = context3D.createIndexBuffer(6);

此索引缓冲区基本上定义了2个三角形。第一个是顶点0,1,2。第二个是顶点2,3和0。

跟顶点缓冲区一样,我们上传索引缓冲区到GPU之后,我们才可以使用它。

// offset 0, count 6indexbuffer.uploadFromVector (Vector.<uint>([0, 1, 2, 2, 3, 0]), 0, 6);

您还需要一个可以发送到GPU的纹理。这仅仅是一个嵌入到你的SWF的jpg(或外部加载的图像):

var bitmap:Bitmap = new TextureBitmap();var texture:Texture = context3D.createTexture(bitmap.bitmapData.width,bitmap.bitmapData.height, Context3DTextureFormat.BGRA, false);texture.uploadFromBitmapData(bitmap.bitmapData);

最终,你首先需要使用AGALMiniAssembler编译AGAL着色程序。

var vertexShaderAssembler : AGALMiniAssembler = new AGALMiniAssembler();vertexShaderAssembler.assemble( Context3DProgramType.VERTEX,"m44 op, va0, vc0\n" + // pos to clipspace"mov v0, va1" // copy uv);var fragmentShaderAssembler : AGALMiniAssembler= new AGALMiniAssembler();fragmentShaderAssembler.assemble( Context3DProgramType.FRAGMENT,"tex ft1, v0, fs0 <2d,linear, nomip>;\n" +"mov oc, ft1");

然后上传两个顶点和像素着色器程序到GPU:

var program:Program3D = context3D.createProgram();program.upload( vertexShaderAssembler.agalcode, fragmentShaderAssembler.agalcode);

足够啦!我现在就想渲染!

ok,一切都已经上传并准备就绪,你现在可以渲染了…yay!

第一件事,清除你的视窗的一些背景颜色:

context3D.clear ( 1, 1, 1, 1 );

然后指定顶点缓冲,索引缓冲,纹理和着色程序

// vertex position to attribute register 0context3D.setVertexBufferAt (0, vertexbuffer, 0, Context3DVertexBufferFormat.FLOAT_3);// uv coordinates to attribute register 1context3D.setVertexBufferAt(1, vertexbuffer, 3, Context3DVertexBufferFormat.FLOAT_2);// assign texture to texture sampler 0context3D.setTextureAt( 0, texture );// assign shader programcontext3D.setProgram( program );

请注意两个顶点缓冲流,顶点位置和UV坐标,如何分配给两个不同的属性寄存器。纹理被分配到一个特定的纹理采样。

然后,你需要传递您的转换矩阵给着色器。我不会做任何花哨的3D投影。只是一个基本的变换矩阵。

var m:Matrix3D = new Matrix3D();m.appendRotation(getTimer()/50, Vector3D.Z_AXIS);context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, m, true);

矩阵在这里获取存储到常量寄存器0,供顶点着色器使用。

要渲染只需调用drawTriangles,传参索引缓冲。

context3D.drawTriangles( indexBuffer);

你可以在帧上调用额外的drawTriangle,来绘制其它的几何形。在这些结束后,只需要执行present(),来实际渲染这帧。

context3D.present();

它真的运行了吗?

你自己看看吧,下面就是刚刚建好的应用示例。

这里是源代码:

在里下载这个简单的demo:下载

酷!现在,这下我可以写一个着色器了吧?

对,你可以了!这只是一个简单的demo,但它足以让您尝试不同的着色器,只要改变着色器代码,看看AGAL给你带来什么。

相关阅读第一部分:我叫AGAL,来自Adobe – Part1

翻译:xncat
转载注明来源:http://www.wefdc.com/?p=198
英文原文:http://iflash3d.com/shaders/my-name-is-agal-i-come-from-adobe-2/

原创粉丝点击