使用缓冲区以及GLSL变量 - webGL 学习手记 | webGL 教程 (三)

前两篇的文章我们介绍了如何使用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的学习。


快速链接

Write a response...
Mofei Zhu
publish
David
2017-03-22 11:18
博主快更新,前几篇写的不错,比很多教程更通俗易懂
0
 Replay
@David  
Replay
Mofei
2014-12-24 15:37
@ 先放出下次要说的DEMO吧,http://zmofei.github.io/yes-webgl/demo/cube/index.html,用WebGL画立方体。
0
 Replay
@Mofei  
Replay
Mofei
2014-12-24 15:22
@ 还在酝酿中。。。
0
 Replay
@Mofei  
Replay
匿名
2014-12-24 15:15
快更新呀,快更新呀
0
 Replay
@  
Replay