WebGL 几何图形
WebGL 几何图形
所有的原型(或对象模型)都应该有完整的几何细节.这些细节可以包括顶点、指数、颜色、纹理等。在WebGL中,几何细节存储在JavaScript数组中。图形对象是由运行在GPU上的着色程序创建的。几何细节被传递给使用缓冲对象的着色程序。
定义所需的几何图形
使用顶点绘制的2d或3d模型称为网格,网格中的每个面称为多边形,多边形是由3个或更多的顶点组成的。
要在WebGL渲染上下文中绘制模型,必须使用JavaScript数组定义顶点和索引。例如,如果我们要创建一个位于坐标{(5,5), (-5,5), (-5,-5)}的三角形,如图所示,则可以为顶点创建一个数组:
var vertices = [ 0.5,0.5, //Vertex 1 0.5,-0.5, //Vertex 2 -0.5,-0.5, //Vertex 3 ];
同样,您可以为索引创建一个数组,上述三角指数的指数为[0, 1, 2] ,可定义为:
var indices = [ 0,1,2 ]
为了更好地理解索引,请考虑更复杂的模型,如方形。我们可以将正方形表示为一组两个三角形。如果(0,3,1)和(3,1,2)是两个用于绘制正方形的三角形,则将索引定义为:
var indices = [0,3,1,3,1,2];
绘图原型,WebGL提供以下两种方法:
drawArrays():在使用此方法时,我们通过使用JavaScript数组传递原语的顶点。
drawElements():在使用此方法时,我们通过JavaScript数组传递基元的顶点和索引。
缓冲区对象
缓冲区对象是WebGL提供的机制,它指示系统中分配的内存区域。在这些缓冲区对象中,您可以存储要绘制的模型的数据,对应顶点、索引、颜色等。
使用这些缓冲对象,你可以通过一个属性变量将多个数据传递给着色程序(顶点着色器)。由于这些缓冲区对象驻留在GPU内存中,它们可以直接呈现,从而提高了性能。
为了处理几何图形,WebGL提供了两种类型的缓冲区对象,他们是:
顶点缓冲对象(VBO)−它保存将要呈现的图形模型的每个顶点数据。我们在webgl中使用顶点缓冲对象来存储和处理顶点坐标、法线、颜色和纹理坐标等顶点的数据。
索引缓冲对象(IBO)−它保存将要呈现的图形模型的索引(索引数据)。
在定义了所需的几何并将它们存储在JavaScript数组中之后,您需要将这些数组传递给缓冲区对象,从数据将传递到着色程序。要在缓冲区中存储数据,应遵循以下步骤。
1.创建一个空的缓冲区。
2.将适当的数组对象绑定到空缓冲区。
3.使用一个类型化数组将数据(顶点/索引)传递到缓冲区。
4.解除缓冲区(可选)。
注意:
WebGL提供一种特殊类型的数组称为类型化数组来传输数据元素,如索引顶点和纹理。这些类型化数组存储大量数据,并以本机二进制格式处理它们,从而提高性能。WebGL使用的类型化数组是Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, UInt32Array, Float32Array和Float64Array。
通常,对于存储顶点数据,我们使用Float32Array,存储索引数据,我们使用Uint16Array。
您可以使用新的关键字创建类型数组,就像JavaScript数组一样。
现在,让我们了解在缓冲区中存储数据的步骤.
创建缓冲区
为了创建一个空的缓冲区,WebGL提供了名为createBuffer()的方法,如果成功这个方法返回一个新创建的缓冲区对象,如果失败返回null.
WebGL作为状态机运行。一旦创建了缓冲区,任何后续的缓冲区操作将在当前缓冲区上执行,直到我们解除缓冲。使用以下代码创建缓冲区:
var vertex_buffer = gl.createBuffer();
绑定缓冲区
创建空缓冲区对象后,需要将适当的数组缓冲区(目标)绑定到它,WebGL提供了一种称为bindBuffer()的方法。
语法
bindBuffer()方法的语法如下−
void (枚举目标、对象缓冲区)-此方法接受两个参数,并在下面讨论。
target-第一个变量是表示我们要绑定到空缓冲区的缓冲区类型的枚举值。您有两个预定义的枚举值作为此参数的选项。他们是-
ARRAY_BUFFER-表示顶点数据。
ELEMENT_ARRAY_BUFFER-表示索引数据。
Object buffer-第二个缓冲区是引用变量到在上一步中创建的缓冲区对象,引用变量可以是顶点缓冲对象或索引缓冲区对象。
例子
以下代码片段显示如何使用bindBuffer()方法。
//vertex buffer var vertex_buffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer); //Index buffer var Index_Buffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
将数据传递到缓冲区中。
下一步是将数据(顶点/索引)传递到缓冲区。到现在,数据以数组的形式存在,在将其传递给缓冲区之前,我们需要将其封装在一个webgl类型数组中。为此, webgl提供了一个名为bufferdata ()的方法。
语法
bufferdata()方法的语法如下:
void bufferData(enum target, Object data, enum usage)
此方法接受三个参数,下文将讨论这些参数:
target-第一个参数是表示我们使用的数组缓冲区类型的枚举值。这可以是数组或埃莱门特。
data-第二个参数是包含要写入缓冲区对象的数据的对象值。在这里,我们必须使用类型化数组传递数据。
usage-此方法的第三个参数是枚举变量,它指定如何使用缓冲区对象数据(存储的数据)绘制形状。以下列出了此参数的三个选项。
gl.STATIC_DRAW-将指定一次并多次使用。
gl.STREAM_DRAW-将指定一次并使用几次数据。
gl.DYNAMIC_DRAW-将多次指定并多次使用。
例子
以下代码片段显示如何使用bufferdata()方法。假定顶点和索引分别是保持顶点和索引数据的数组。
//vertex buffer gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); //Index buffer gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
解除缓冲区的绑定
建议您在使用它们后解除缓冲区绑定。可以通过传递一个null值代替缓冲区对象,如下所示:
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
webgl提供以下方法来执行缓冲区操作:
No | 方法和说明 |
---|---|
1 | void bindBuffer (enum target, Object buffer) target − ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER |
2 | void bufferData(enum target, long size, enum usage) target − ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER usage − STATIC_DRAW, STREAM_DRAW, DYNAMIC_DRAW |
3 | void bufferData (enum target, Object data, enum usage) target and usage - 跟bufferData相同 |
4 | void bufferSubData(enum target, long offset, Object data) target − ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER |
5 | Object createBuffer() |
6 | void deleteBuffer(Object buffer) |
7 | any getBufferParameter(enum target, enum pname) target − ARRAY_BUFFER, ELEMENT_ ARRAY_BUFFER pname − BUFFER_SIZE, BUFFER_USAGE |
8 | bool isBuffer(Object buffer) |