Using Buffers and GLSL Variables - webGL Learning Handbook | webGL Tutorials (3)

Sorry, this article is not written in English and has not been translated into English yet .You can view this article in English with Google Translate, or please come back later.

前两篇的文章我们介绍了如何使用webGL进行简单的绘制,今天我们简单说一下如何使用缓冲区。

另外,我将学习过程中用到的一些资料放在了 Github 的 Yes-webGL https://github.com/zmofei/yes-webgl 项目上,如果大家有什么好的建议,或者愿意一同来写教程的欢迎来骚扰我。

何为缓冲区?

通过前面的例子,我们应该对webGl的渲染过程很熟悉了, 创建项目 -> 绑定shader -> 清除画布 -> 绘制画布 , 每次绘制钱我们都会去青春画布上的内容,然后进行新的绘制。但是,如果我们需要一次性绘制多个点或者多个图形怎么办呢?如果一个一个的去绘制的话,在性能上很有可能不尽人意,尤其是我们有千千万万个绘制点的时候。

这时候缓冲区就开始刷存在感了,我们可以先将我们的数据存入到缓冲去,然后再一次性的把缓冲区的数据绘制出来。

一些封装

这个DEMO中,我们将获取WebGL上下文绑定着色器等复杂的步骤进行了封装,如果想了解这两个步骤是如何工作的,请参考前两篇的文章。

缓冲区使用的步骤

现在步入正题,来看看我们DEMO中是如何处理这些细节的。

缓冲区使用非常简单,这里我们通过一下的步骤完成了缓冲区的创建、绑定、数据传入等工作

  1. 创建缓冲区
  2. 绑定缓冲区到WebGL对象
  3. 传入数据到缓冲区

1. createBuffer()

var vertexColorBuffer = gl.createBuffer();

创建缓冲区,这个很好理解,不用多说

2. bindBuffer()

gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer);

将创建出来的缓冲区绑定到webGL对向上,这里我们使用了2个参数,第一个是类型,因为我们使用的是数组的点数据,所以使用系统提供的gl.ARRAY_BUFFER变量。

第2个参数是我们需要绑定的Buffer对象,这里使用的就是我们第一步创建出来的Buffer对象。

3. bufferData()

var verticesColors = new Float32Array([
     0.5,  0.5,  0, 
    -0.5, -0.5,  0, 
    -0.5,  0.5,  0,    
     0.5, -0.5,  0]);
//...
gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);

这一步我们将我们的点位置数组传入到Buffer对象中 该方法接受的3个参数分别为

  • 数据类型,可以是gl.ARRAY_BUFFER,gl.ELEMENT_ARRAY_BUFFER,本例中使用的是gl.ARRAY_BUFFER
  • 数据
  • 缓冲类型,有这么几种可以供我们选择GL_STREAM_DRAW,GL_STATIC_DRAW,GL_DYNAMIC_DRAW

GLSL 变量的使用

在本例中,我们通过js向定点着色器中传入了一些顶点坐标,那么这些坐标是如何赋值的呢?

var VSHADER_SOURCE =
        'attribute vec4 a_Position;\n' +
        'void main() {\n' +
        '  gl_Position = a_Position;\n' +
        '  gl_PointSize = 10.0;\n' +
        '}\n';

首先看顶点着色器,我们声明了a_Position变量,接下来我们通过下面的方法进行赋值。

var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Position);

getAttribLocation(program, name)

在js中,我们首先通过getAttribLocation()获取到变量a_Position在渲染器中的地址。 该方法接收两个变量

  • program project对象
  • name 变量名称

接下来我们通过vertexAttribPointer()方法,指定了如何处理渲染器中的值。

vertexAttribPointer(index, size, type, normalized, stride, offset);

比较复杂的一个方法

  • index 绑定在gl.ARRAY_BUFFER中的目标索引,比较难理解,但是通常情况下我们可以通过getAttribLocation来获取这个值。
  • size 每个属性的长度 [1,2,3,4(default)]
  • type 类型 指定数据类型 我们有两个选择,[gl.FLOAT (default)|gl.FIXED]
  • normalized 是否初始化传入的数据 [gl.FALSE|gl.TRUE]
  • stride 每组数据的个数,[0-255]
  • offset 这一组中的数据起始位置(从0开始)

接下来启用 enableVertexAttribArray()

enableVertexAttribArray(index);

  • index 同 vertexAttribPointer中的index

##总结

OK,目前为止我们已经学会了WebGL的非常基本的知识,接下来,我们尝试真正的迈入3D的学习。


快速链接

74020
  • logo
    • HI, THERE!I AM MOFEI

      (C) 2010-2024 Code & Design by Mofei

      Powered by Dufing (2010-2020) & Express

      IPC证:沪ICP备2022019571号-1