开发学院

您的位置:首页>教程>正文

教程正文

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
];

geometry.jpg

  同样,您可以为索引创建一个数组,上述三角指数的指数为[0, 1, 2] ,可定义为:

var indices = [ 0,1,2 ]

  为了更好地理解索引,请考虑更复杂的模型,如方形。我们可以将正方形表示为一组两个三角形。如果(0,3,1)和(3,1,2)是两个用于绘制正方形的三角形,则将索引定义为:

var indices = [0,3,1,3,1,2];

geometry_example.jpg

绘图原型,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

5Object createBuffer()
6void deleteBuffer(Object buffer)
7

any getBufferParameter(enum target, enum pname)

target − ARRAY_BUFFER, ELEMENT_ ARRAY_BUFFER

pname − BUFFER_SIZE, BUFFER_USAGE

8bool isBuffer(Object buffer)