我们首先熟悉一个函数的使用drawTriangles,drawTriangles字面理解,就是画三角形,当然adobe不会因为你需要画三角形才给你提供这个方法吧,其真正的作用是通过快速批量的画三角形来实现位图的扭曲。我们所有的图形都可以用三角片来表示,不管是平面和三维图形,通过三角片,可以模拟出任何图形,如下图:
drawTriangles是我们开发全景浏览器的基础,drawTriangles的定义如下:
public function drawTriangles(vertices:Vector.<Number>, indices:Vector.<int> = null, uvtData:Vector.<Number> = null, culling:String = "none"):void
vertices:Vector.<Number>
由数字构成的矢量,其中的每一对数字将被视为一个坐标位置(一个 x, y 对)。vertices
参数是必需的。
-
indices:Vector.<int>
(default =null
)
一个由整数或索引构成的矢量,其中每三个索引定义一个三角形。如果 indexes
参数为 null,则每三个顶点(vertices
矢量中的 6 对 x,y)定义一个三角形。否则,每个索引将引用一个顶点,即 vertices
矢量中的一对数字。例如,indexes[1]
引用 (vertices[2]
, vertices[3]
)。indexes
参数是可选的,但 indexes 通常会减少提交的数据量和计算的数据量。
由用于应用纹理映射的标准坐标构成的矢量。每个坐标引用用于填充的位图上的一个点。每个顶点必须具有一个 UV 或一个 UVT 坐标。对于 UV 坐标,(0,0) 是位图的左上角,(1,1) 是位图的右下角。
如果此矢量的长度是 vertices
矢量长度的两倍,则使用标准坐标而不进行透视校正。
如果此矢量的长度是 vertices
矢量长度的三倍,则将第三个坐标解释为“t”(即在视角空间中从视点到纹理的距离)。这有助于呈现引擎在三维中映射纹理时正确应用透视。
如果 uvtData
参数为 null,则将应用普通填充规则(和任何填充类型)。
-
culling:String
(default = "none
")
指定是否呈现面向指定方向的三角形。此参数可防止呈现在当前视图中看不见的三角形。此参数可设置为由 TriangleCulling 类定义的任何值。
1. vertices的使用
我们看看drawTriangles如何使用,看以下代码:
public function MiPanoTest() { var ver:Vector.<Number>=new Vector.<Number>(); ver.push(200,0); ver.push(0,200);//记录坐标x,y坐标点 ver.push(400,200); #效果1 //this.graphics.beginFill(0x00ccff); #效果2 //this.graphics.beginBitmapFill((new texture() as Bitmap).bitmapData) this.graphics.drawTriangles(ver); this.graphics.endFill(); }
其显示效果如下:
以上只是drawTriangles的小试牛刀,我们看看如何将图片放入三角片中,上面的案例,我们只指定了三个顶点,所以图形会以默认方式呈现,下面我们将顶点的数量增加到9个,切每个点的距离是50,且平均排列,代码如下:
public class MiPanoTest extends Sprite { [Embed(source="assets/img.jpg")] public var texture:Class; public function MiPanoTest() { var row:int=3; var cell:int=3; var step:int=50; var vertexs:Vector.<Number>=new Vector.<Number>(); //定义了一个50区间的9格方格 for(var i:int=0;i<row;i++){ for(var j:int=0;j<cell;j++){ vertexs.push(i*step,j*step); } } //下一步,我们计算三角片的组成 this.graphics.beginBitmapFill((new texture() as Bitmap).bitmapData) this.graphics.drawTriangles(vertexs); this.graphics.endFill(); } }
我们看到的结果是一片空白,什么都没有绘制,是什么原因呢?
2. indices的使用
原因是在前面的案例,我们只有三个顶点,所以drawTriangles通过三个顶点就可以构件一个面,而本案例有9个顶点,系统根本不知道那些点能组合成三角片,所以会出现一个三角片都没有,无法绘制出图形,那么这个就是第二个参数indices的,告诉系统如何组织三角片,我们上面添加了9个顶点,系统会按照两个一组,进行编号,然后把这些顶点划分三角片,如下图所示:
我们可以知道indices是记录顶点的索引位置那么,组合的三角形可以定义如下:
(0,1,3)
(1,3,4)
(1,2,4)
(2,4,5)
(3,4,6)
(4,6,7)
(4,5,7)
(5,7,8)
注意其排列循序,组成一个正方形网格的三角片0,1,3和1,3,4,结果上面的划分,我们定义代码如下:
public class MiPanoTest extends Sprite { [Embed(source="assets/img.jpg")] public var texture:Class; public function MiPanoTest() { var row:int=3; var cell:int=3; var step:int=100; var vertexs:Vector.<Number>=new Vector.<Number>(); var indices:Vector.<int>=new Vector.<int>(); //定义了一个50区间的9格方格 for(var i:int=0;i<row;i++){ for(var j:int=0;j<cell;j++){ vertexs.push(i*step,j*step); } } indices.push(0,1,3) indices.push(1,3,4) indices.push(1,2,4) indices.push(2,4,5) indices.push(3,4,6) indices.push(4,6,7) indices.push(4,5,7) indices.push(5,7,8) //下一步,我们计算三角片的组成 this.graphics.lineStyle(1,0x000000,1); this.graphics.beginBitmapFill((new texture() as Bitmap).bitmapData) this.graphics.drawTriangles(vertexs,indices); this.graphics.endFill(); } }
其显示效果如下:
我们赋值三角片的划分规则以后,图形终于显示出来了,图形是出来了,但是这个和正常的图片绘制有什么区别,区别就是我们改变一下坐标顶点的位置试试,我们将上面的图形编程一个梯形样式,代码如下:
public class MiPanoTest extends Sprite { [Embed(source="assets/img.jpg")] public var texture:Class; public function MiPanoTest() { var row:int=3; var cell:int=3; var step:int=100; var vertexs:Vector.<Number>=new Vector.<Number>(); var indices:Vector.<int>=new Vector.<int>(); //定义了一个50区间的9格方格 for(var i:int=0;i<row;i++){ for(var j:int=0;j<cell;j++){ var offset:Number=0; if(j==0){ offset=20*(row-i); }else if(j==1){ offset=0 }else{ offset=-20*(row-i); } vertexs.push(j*step+offset,i*step); } } indices.push(0,1,3) indices.push(1,3,4) indices.push(1,2,4) indices.push(2,4,5) indices.push(3,4,6) indices.push(4,6,7) indices.push(4,5,7) indices.push(5,7,8) //下一步,我们计算三角片的组成 this.graphics.lineStyle(1,0x000000,1); this.graphics.beginBitmapFill((new texture() as Bitmap).bitmapData) this.graphics.drawTriangles(vertexs,indices); this.graphics.endFill(); } }
我们看一下显示效果如下:
我们看到,虽然三角形的位置发生了变化,但是图形还是原来的图形,只是没有在三角形内部的部分,没有显示,这里,我们就要说明第三个参数uvtData
的含义,他记录的是每个顶点所占的贴图的比例,从0~1,如图:
我们要把一个完整的图形显示在当前的这个梯形内部,则我们要设置每个点的UV比例,由于每个顶点都有UV两个方向(T暂时放着)uvtData数组的长度应该是vertices的两倍
,所以,对以上的案例代码稍作修改如下:
public class MiPanoTest extends Sprite { [Embed(source="assets/img.jpg")] public var texture:Class; public function MiPanoTest() { var row:int=3; var cell:int=3; var step:int=100; var vertexs:Vector.<Number>=new Vector.<Number>(); var indices:Vector.<int>=new Vector.<int>(); var uvtData:Vector.<Number>=new Vector.<Number>(); //定义了一个50区间的9格方格 for(var i:int=0;i<row;i++){ for(var j:int=0;j<cell;j++){ var offset:Number=0; if(j==0){ offset=20*(row-i); }else if(j==1){ offset=0 }else{ offset=-20*(row-i); } vertexs.push(j*step+offset,i*step); } } indices.push(0,1,3) indices.push(1,3,4) indices.push(1,2,4) indices.push(2,4,5) indices.push(3,4,6) indices.push(4,6,7) indices.push(4,5,7) indices.push(5,7,8) uvtData.push(0,0,0.5,0,1,0,0,0.5,0.5,0.5,1,0.5,0,1,0.5,1,1,1); //下一步,我们计算三角片的组成 this.graphics.lineStyle(1,0x000000,1); this.graphics.beginBitmapFill((new texture() as Bitmap).bitmapData) this.graphics.drawTriangles(vertexs,indices,uvtData); this.graphics.endFill(); } }
显示效果如下:
我们把一个完整的图形在多个三角网格中显示出来了。