webgl2 方法解析: createBuffer()

0 阅读3分钟

在 WebGL2 中,createBuffer() 是一个用于创建缓冲区对象(Buffer Object)的方法。缓冲区对象用于存储顶点数据、索引数据或其他数据,这些数据可以被 GPU 使用来渲染图形。以下是关于 createBuffer() 的详细说明:

语法

WebGLBuffer createBuffer();
  • 返回值:返回一个 WebGLBuffer 对象,表示新创建的缓冲区对象。如果创建失败(例如,因为 WebGL 上下文已丢失),则返回 null

使用方法

  1. 创建缓冲区对象: 在 WebGL2 中,createBuffer() 方法用于创建一个新的缓冲区对象。创建后,需要使用 bindBuffer() 方法将缓冲区绑定到一个目标上,然后使用 bufferData()bufferSubData() 方法向缓冲区中填充数据。

  2. 绑定缓冲区对象: 使用 bindBuffer() 方法将缓冲区绑定到一个目标上。目标可以是以下几种类型:

    • gl.ARRAY_BUFFER:用于存储顶点数据。
    • gl.ELEMENT_ARRAY_BUFFER:用于存储索引数据。
    • gl.PIXEL_PACK_BUFFER:用于存储像素数据(例如,从纹理中读取数据)。
    • gl.PIXEL_UNPACK_BUFFER:用于存储像素数据(例如,用于纹理上传)。
    • gl.UNIFORM_BUFFER:用于存储统一变量数据(WebGL2 新增功能)。
    • gl.TRANSFORM_FEEDBACK_BUFFER:用于存储变换反馈数据(WebGL2 新增功能)。
  3. 填充缓冲区数据: 使用 bufferData()bufferSubData() 方法向缓冲区中填充数据。bufferData() 用于初始化整个缓冲区,而 bufferSubData() 用于更新缓冲区的子区域。

示例代码

以下是一个完整的示例,展示如何创建缓冲区对象并填充顶点数据:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>WebGL2 Uniform Buffer Example</title>
  <style>
    canvas {
      width: 800px;
      height: 600px;
    }
  </style>
</head>
<body>
  <canvas id="canvas"></canvas>
  <script>
    // 获取 WebGL2 上下文
    const canvas = document.getElementById('canvas');
    const gl = canvas.getContext('webgl2');
    if (!gl) {
      throw new Error('WebGL2 is not supported by your browser.');
    }
​
    // 顶点着色器代码
    const vertexShaderSource = `#version 300 es
      in vec4 a_position;
      void main() {
        gl_Position = a_position;
      }
    `;
​
    // 片段着色器代码
    const fragmentShaderSource = `#version 300 es
      precision highp float;
      out vec4 outColor;
      void main() {
        outColor = vec4(1.0, 0.0, 0.0, 1.0);
      }
    `;
​
    // 创建着色器
    function createShader(gl, type, source) {
      const shader = gl.createShader(type);
      gl.shaderSource(shader, source);
      gl.compileShader(shader);
      if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        console.error('Shader compile failed with:', gl.getShaderInfoLog(shader));
        gl.deleteShader(shader);
        return null;
      }
      return shader;
    }
​
    // 创建程序
    const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
    const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
    const program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
      throw new Error('link falsed! ');
    }
    gl.useProgram(program);
​
    // 创建顶点缓冲区
    const positionBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    const positions = new Float32Array([
      -0.5, -0.5, 0.0,
       0.5, -0.5, 0.0,
       0.0,  0.5, 0.0
    ]);
    gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
​
    // 设置顶点属性指针
    const positionLocation = gl.getAttribLocation(program, 'a_position');
    gl.enableVertexAttribArray(positionLocation);
    gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
​
    // 渲染循环
    function render() {
      gl.clearColor(0.0, 0.0, 0.0, 1.0);
      gl.clear(gl.COLOR_BUFFER_BIT);
​
      gl.drawArrays(gl.TRIANGLES, 0, 3);
​
      requestAnimationFrame(render);
    }
​
    render();
  </script>
</body>
</html>

注意事项

  1. 缓冲区绑定: 在使用缓冲区之前,必须先将其绑定到一个目标上。否则,bufferData()bufferSubData() 方法将无法正常工作。
  2. 数据类型bufferData()bufferSubData() 方法需要指定数据的类型(如 Float32ArrayUint16Array 等)。确保数据类型与顶点属性的类型一致。
  3. 缓冲区大小: 使用 bufferData() 方法时,需要指定缓冲区的大小。如果数据量较大,建议使用 gl.DYNAMIC_DRAWgl.STREAM_DRAW,以便动态更新缓冲区数据。
  4. WebGL2 新增功能: WebGL2 支持更多的缓冲区目标,如 gl.UNIFORM_BUFFERgl.TRANSFORM_FEEDBACK_BUFFER,这些功能在 WebGL1 中是不可用的。