六、使用缓冲区对象 - 绘制多个点

141 阅读2分钟

什么是缓冲区对象

缓冲区对象是WebGL系统中的一块内存区域,可以一次性地向缓冲区对象中填充大量的顶点数据,然后将这些数据保存在其中,供顶点着色器使用

类型化数组

在 webgl中,需要处理大量的相同类型数据,所以引入类型化数组,这样程序就可以预知到数组中的数据类型,提高性能

类型化数组类型:

Int8Array: 8位整型

UInt8Array:8位无符号整型

Int16Array: 16位整型

UInt16Array:16位无符号整型

Int32Array:32位整型

UInt32Array:32位无符号整型

Float32Array:单精度32位浮点型

Float64Array:双精度64位浮点型

1、创建的缓冲区对象

const buffer = webgl.createBuffer();

2、把创建的缓冲区对象绑定到webgl

webgl.bindBuffer(target, buffer)

buffer:已经创建好的缓冲区对象

target:可以是如下两种

gl.ARRAY_BUFFER:表示缓冲区存储的是顶点的数据

gl.ELEMENT_ARRAY_BUFFER:表示缓冲区存储的是顶点的索引值

3、把创建的数据写入

webgl.bufferData(target, data, type)

target: 类型同 gl.bindBuffer 中的 target

data: 写入缓冲区的顶点数据,如程序中的 points

type: 表示如何使用缓冲区对象中的数据,分为以下几类

gl.STATIC_DRAW: 写入一次,多次绘制(数据只加载一次,在多次绘图中使用)

gl.STREAM_DRAW: 写入一次,绘制若干次(数据只加载一次,在几次绘图中使用)

gl.DYNAMIC_DRAW: 写入多次,绘制多次(数据只加载一次,在几次绘图中使用)

4、给变量赋值

webgl.vertexAttribPointer(location, size, type,normalized, stride, offset)

location: attribute 变量的存储位置

size:指定每个顶点所使用数据的个数

type:指定数据格式

  • gl.FLOAT:浮点型
  • gl.UNSIGNED_BYTE:无符号字节
  • gl.SHORT:短整型
  • gl.UNSIGNED_SHORT :无符号短整型
  • gl.INT:整型
  • gl.UNSIGNED_INT:无符号整型

normalized: 表示是否将数据归一化到 [0,1][-1,1] 这个区间

stride:两个相邻顶点之间的字节数

offset:数据偏移量

5、激活变量

webgl.enableVertexAttribArray(location)

location: attribute 变量的存储地址

gl.disableVertexAttribArray(aPosition);使用此方法禁用

总体代码

let webglDiv = document.getElementById('practice');
let webgl = webglDiv.getContext('webgl');

/*着色器*/
// 顶点着色器
const VERTEX_SHADER_SOURCE = `
        //  attribute 只能用于传递定点数据
       attribute vec4 aPosition;
       void main(){
          // 要绘制的点的坐标
          gl_Position = aPosition;
          // 点的大小
          gl_PointSize = 20.0;
        }
  `;
// 片元着色器
const FRAGMENT_SHADER_SOURCE = `
   //  设置默认精度
    precision mediump float;
    //  uniform 只能用于传递颜色
    uniform vec3 uColor;
    void main(){
     gl_FragColor = vec4(uColor.r, uColor.g, uColor.b,1.0);
    }
  `;

// 创建着色器并绑定程序对象
const program = initShader(webgl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE);

// 获取attribute变量
const aPosition = webgl.getAttribLocation(program, 'aPosition');

// 获取uniform 变量
const uColor = webgl.getUniformLocation(program, 'uColor');

// 创建类型化数组
const points = new Float32Array([-0.5,-0.5,0.5,-0.5,0.0, 0.5])
const buffer = webgl.createBuffer();
webgl.bindBuffer(webgl.ARRAY_BUFFER,buffer);
webgl.bufferData(webgl.ARRAY_BUFFER,points,webgl.STATIC_DRAW)
// uniform 变量赋值
webgl.uniform3f(uColor, 0.1, 1.0, 1.0);
webgl.vertexAttribPointer(aPosition,2, webgl.FLOAT, false,0,0);
webgl.enableVertexAttribArray(aPosition);
webgl.drawArrays(webgl.POINTS, 0, 3);

流程图

image.png