WebGL 重新创建重叠三角形

WebGL Recreate Overlapping Triangles

我正在尝试创建一个没有 css 的程序,它在黑色背景上显示几个重叠的三角形。一旦我可以显示三角形(就像只附有不同颜色的图片),我需要实现一个 z 缓冲区或画家的算法;但首先,我无法弄清楚下面的代码有什么问题,它们根本没有显示。我认为这可能是我的着色器的问题?

<!doctype html>
<html>
   <body>
      <canvas width = "500" height = "500" id = "canvas"></canvas>

      <script>
         var canvas = document.getElementById('canvas');
         gl = canvas.getContext('webgl');

         var positions = [
                           0, 1, -1, -1, 1, -1,
                          -1, -1, -0, -1, -1, -0.5,
                           1, -1, 0, -1, 1, -0.5,
                           1, 1, 0, 1, 1, -1,
                          -1, 1, -1, 0, -0, 1
         ];

         var colors = [
                        1,0,1, 1,0,1, 1,0,1, 1,0,1,//purple
                        0,0,1, 0,0,1, 0,0,1, 0,0,1,//blue
                        1,1,0, 1,1,0, 1,1,0, 1,1,0,//yellow
                        1,0,0, 1,0,0, 1,0,0, 1,0,0,//red
                        0,1,0, 0,1,0, 0,1,0, 0,1,0, //green
         ];

         //vertex buffer
         var vbuffer = gl.createBuffer ();
         gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
         gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

         //color buffer
         var cbuffer = gl.createBuffer ();
         gl.bindBuffer(gl.ARRAY_BUFFER, cbuffer);
         gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);

        //shaders
         var vCode =
            `
            attribute vec2 a_Position;
            attribute vec3 a_Color;
            varying vec3 v_Color;

            void main()
             {
                 gl_Position = vec4(a_Position, 0.0, 1.0);
                 v_Color = a_Color;
             }`;
         var fragCode =
             `
             precision mediump float;
             varying vec3 v_Color;

             void main()
             {
                 gl_FragColor = vec4(v_Color, 1.0);
             }`;

                //vertex shader
         var vShader = gl.createShader(gl.VERTEX_SHADER);
         gl.shaderSource(vShader, vCode);
         gl.compileShader(vShader);

                 //fragment shader
         var fShader = gl.createShader(gl.FRAGMENT_SHADER);
         gl.shaderSource(fShader, fragCode);
         gl.compileShader(fShader);


         var shaders = gl.createProgram();
         gl.attachShader(shaders, vShader);
         gl.attachShader(shaders, fShader);
         gl.linkProgram(shaders);

                 //vertex buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
         var _position = gl.getAttribLocation(shaders, "position");
         gl.vertexAttribPointer(_position, 3, gl.FLOAT, false,0,0);
         gl.enableVertexAttribArray(_position);

                 //color buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, cbuffer);
         var _color = gl.getAttribLocation(shaders, "color");
         gl.vertexAttribPointer(_color, 3, gl.FLOAT, false,0,0) ;
         gl.enableVertexAttribArray(_color);
         gl.useProgram(shaders);

                    //depth testing
          gl.disable(gl.DEPTH_TEST);
          gl.enable(gl.BLEND);

          gl.depthMask(gl.FALSE);

                    //clears buffer
          gl.clearColor(0.5, 0.5, 0.5, 0.9);
          gl.clearDepth(1.0);
          gl.viewport(0.0, 0.0, canvas.width, canvas.height);
          gl.clear(gl.cbuffer_BIT | gl.DEPTH_BUFFER_BIT);

          gl.drawArrays(gl.TRIANGLES, 0, 15);
      </script>
   </body>
</html>

代码中有四个错误。我纠正了错误并添加了解释。这是工作代码:

<!doctype html>
<html>
   <body>
      <canvas width = "500" height = "500" id = "canvas"></canvas>

      <script>
         var canvas = document.getElementById('canvas');
         gl = canvas.getContext('webgl');

         var positions = [
                           0, 1, -1, -1, 1, -1,
                          -1, -1, -0, -1, -1, -0.5,
                           1, -1, 0, -1, 1, -0.5,
                           1, 1, 0, 1, 1, -1,
                          -1, 1, -1, 0, -0, 1
         ];

         /*var colors = [
                        1,0,1, 1,0,1, 1,0,1, 1,0,1,//purple
                        0,0,1, 0,0,1, 0,0,1, 0,0,1,//blue
                        1,1,0, 1,1,0, 1,1,0, 1,1,0,//yellow
                        1,0,0, 1,0,0, 1,0,0, 1,0,0,//red
                        0,1,0, 0,1,0, 0,1,0, 0,1,0, //green
         ]; 
         BUG 1: Color array should be 3 values per vertex. This code assumes 4 values are used
         */
         var colors = [
                        1,0,1, 1,0,1, 1,0,1, //purple
                        0,0,1, 0,0,1, 0,0,1, //blue
                        1,1,0, 1,1,0, 1,1,0, //yellow
                        1,0,0, 1,0,0, 1,0,0, //red
                        0,1,0, 0,1,0, 0,1,0  //green
         ];

         //vertex buffer
         var vbuffer = gl.createBuffer ();
         gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
         gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

         //color buffer
         var cbuffer = gl.createBuffer ();
         gl.bindBuffer(gl.ARRAY_BUFFER, cbuffer);
         gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);

        //shaders
         var vCode =
            `
            attribute vec2 a_Position;
            attribute vec3 a_Color;
            varying vec3 v_Color;

            void main()
             {
                 gl_Position = vec4(a_Position, 0.0, 1.0);
                 v_Color = a_Color;
             }`;
         var fragCode =
             `
             precision mediump float;
             varying vec3 v_Color;

             void main()
             {
                 gl_FragColor = vec4(v_Color, 1.0);
             }`;

                //vertex shader
         var vShader = gl.createShader(gl.VERTEX_SHADER);
         gl.shaderSource(vShader, vCode);
         gl.compileShader(vShader);

                 //fragment shader
         var fShader = gl.createShader(gl.FRAGMENT_SHADER);
         gl.shaderSource(fShader, fragCode);
         gl.compileShader(fShader);


         var shaders = gl.createProgram();
         gl.attachShader(shaders, vShader);
         gl.attachShader(shaders, fShader);
         gl.linkProgram(shaders);

                 //vertex buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
         //var _position = gl.getAttribLocation(shaders, "position"); BUG 2: attribute name is "a_Position"
         var _position = gl.getAttribLocation(shaders, "a_Position"); 
         //gl.vertexAttribPointer(_position, 3, gl.FLOAT, false,0,0); BUG 3: a_Position is a vec2. It only accepts 2 values.
         gl.vertexAttribPointer(_position, 2, gl.FLOAT, false,0,0);
         gl.enableVertexAttribArray(_position);

                 //color buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, cbuffer);
         //var _color = gl.getAttribLocation(shaders, "color"); BUG 4: attribute name is "a_Color"
         var _color = gl.getAttribLocation(shaders, "a_Color");
         gl.vertexAttribPointer(_color, 3, gl.FLOAT, false,0,0) ;
         gl.enableVertexAttribArray(_color);
         gl.useProgram(shaders);

                    //depth testing
          gl.disable(gl.DEPTH_TEST);
          gl.enable(gl.BLEND);

          gl.depthMask(gl.FALSE);

                    //clears buffer
          gl.clearColor(0.5, 0.5, 0.5, 0.9);
          gl.clearDepth(1.0);
          gl.viewport(0.0, 0.0, canvas.width, canvas.height);
          gl.clear(gl.cbuffer_BIT | gl.DEPTH_BUFFER_BIT);

          gl.drawArrays(gl.TRIANGLES, 0, 15);
      </script>
   </body>
</html>