用stage3D API绘制四边形

网上介绍stage3D基本API的文章基本都是以画三角形为案例。对于了解3D图形学的人来说很清楚怎么用这些API绘制一个四边形,但对于刚入门的人来说,虽然只是多了一个点,但如果运气不好可能要费很大的劲。

我们知道stage3D API能绘制的最基本的图形元素是三角形,任何复杂的图形都要首先转化成若干个三角形才能用这些API来绘制。那么对于一个四边形,很显然,我们可以将它分解成两个三角形,如下图所示:

1------2

|     /   |

0------3

四边形的四个顶点为0,1,2,3。这四个数字只是用来标记他们(顶点索引)并不具有实际的几何意义,为了绘制他们,还需要给他们定位,即给他们各自指定一个坐标,可以指定任意的值,但是要在保证这四个点在空间的基本关系不变,即顺时针的顺序。

为了简便起见,同时也不失一般性,我们将这四个点放置在z平面上,他们之间构成一个矩形:

1 vertexBuffer = context3D.createVertexBuffer(4,6);
2 
3 vertexBuffer.uploadFromVector(Vector.<Number>([
4                 -1,-1,1,1,0,0,
5                 1,-1,1,0,1,0,
6                 1,1,1,0,0,1,
7                 -1,1,1,0,1,1
8             ]),0,4);

 

上面两段代码中,第一行的意思是创建一个4个点,每个点有6个数据的顶点缓冲,这6个数据分别为:前三个顶点坐标,后三个顶点颜色。后面一段代码是将数据上传到顶点缓冲。

紧接着,我们将他们绑定到属性寄存器上:

1 context3D.setVertexBufferAt(0,vertexBuffer,0,Context3DVertexBufferFormat.FLOAT_3);
2 context3D.setVertexBufferAt(1,vertexBuffer,3,Context3DVertexBufferFormat.FLOAT_3);

这样我们就可以通过属性寄存器va0,va1分别访问到顶点位置和颜色数据。

至此四个顶点的数据就处理完毕了,接下来需要指定以怎样的顺序绘制他们,这就是索引寄存器的作用了:

1 indexBuffer = context3D.createIndexBuffer(6);
2 indexBuffer.uploadFromVector(Vector.<uint>([
3                 0,1,2,2,3,0
4             ]),0,6);

以上两段代码的第一行创建一个大小为6的索引缓冲,后面的代码将一组数据上传到这个缓冲里,需要注意:这些数据没三个一组,每一组构成一个三角形,并且每一组的顶点顺序是一致的,即要么都为顺时针 要么都为逆时针,因为我们将问题简化为一个平面所以比较简单,在复杂的曲面图形中需要解释的就多一些,这些以后遇到再说。

以上就是绘制一个四边形的核心内容了,至于接下来的内容,基本上同绘制三角形一样:

指定透视投影矩阵:

1 var pm:PerspectiveMatrix3D = new PerspectiveMatrix3D();
2 
3 //pm.perspectiveLH(5,5,1,10000);
4 pm.perspectiveFieldOfViewLH(1,stage.stageWidth/stage.stageHeight,1,10000);
5 context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX,0,pm,true);

编写着色器:

var vertexAssembler:AGALMiniAssembler = new AGALMiniAssembler();
var fragmentAssembler:AGALMiniAssembler = new AGALMiniAssembler();
var vertexSrc:String = "m44 op,va0,vc0 \n" +
                "mov v0,va1";
var fragmentSrc:String = "mov oc,v0";
            vertexAssembler.assemble(Context3DProgramType.VERTEX,vertexSrc);
            fragmentAssembler.assemble(Context3DProgramType.FRAGMENT,fragmentSrc);

创建程序,绘制:

var program:Program3D = context3D.createProgram();    
program.upload(vertexAssembler.agalcode,fragmentAssembler.agalcode); context3D.setProgram(program); context3D.drawTriangles(indexBuffer); context3D.present();

结束!

源码

 

posted @ 2012-11-18 13:29  Joe Physwf  阅读(1009)  评论(4编辑  收藏  举报