webgl绘制一个三角形的流程

76 阅读1分钟

大致步骤:

  1. 编写shader代码
  2. 由shader代码创建一个program
  3. linkProgram和useProgram
  4. 设置shader中的attribute和uniform从哪里取值
  5. 执行绘制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>simple draw</title>
  </head>
  <body>
    <canvas width="500" height="500"></canvas>

    <script type="x-shader/x-vertex" id="vc">
      attribute vec3 aPosition;
      void main() {
        gl_Position = vec4(aPosition, 1.0);
      }
    </script>
    <script type="x-shader/x-fragment" id="fc">
      precision mediump float;
      void main() {
        gl_FragColor = vec4(0.5, 0.5, 0.5, 1.0);
      }
    </script>
    <script>
      // 获取webgl上下文
      const canv = document.querySelector("canvas");
      const gl = canv.getContext("webgl");

      // 获取shader代码块
      const vertexShaderCode = document.querySelector("#vc").innerText;
      const fragmentShaderCode = document.querySelector("#fc").innerText;

      // 由shader代码块创建program
      const vertexShader = gl.createShader(gl.VERTEX_SHADER);
      const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
      gl.shaderSource(vertexShader, vertexShaderCode);
      gl.shaderSource(fragmentShader, fragmentShaderCode);
      gl.compileShader(vertexShader);
      gl.compileShader(fragmentShader);
      const program = gl.createProgram();
      gl.attachShader(program, vertexShader);
      gl.attachShader(program, fragmentShader);

      // https://registry.khronos.org/OpenGL-Refpages/es2.0/
      // program的准备和使用
      gl.linkProgram(program);
      gl.useProgram(program);

      const points = new Float32Array([0, 0, 0, 0, 1, 0, 1, 0, 0]);
      const positionBuffer = gl.createBuffer();
      // 参考 https://stackoverflow.com/questions/27148273/what-is-the-logic-of-binding-buffers-in-webgl
      // 此处可以理解成webgl中的有个跟ARRAY_BUFFER相关的全局变量指向了positionBuffer
      gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
      // 在全局变量指向的positionBuffer中写入
      gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);

      // shader中的属性从ARRAY_BUFFER相关全局变量指向的positionBuffer那取值,并设为可用
      const positionLocation = gl.getAttribLocation(program, "aPosition");
      gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);
      gl.enableVertexAttribArray(positionLocation);

      // 执行绘制
      gl.drawArrays(gl.TRIANGLES, 0, 9);
    </script>
  </body>
</html>