在同一画布中绘制gl.POINTS和gl.TRIANGLES

时间:2015-10-12 16:54:10

标签: javascript canvas webgl

我试图弄清楚如何根据鼠标事件绘制三角形而不是点。代码就像休耕一样:

var gl;

var points = [];
var tpoints = [];

var index = 0;
var cIndex = 0;

var dTri = false;
var dPoint = true;

var count = 0;
var counter = 0;

function init() {
  var canvas = document.getElementById("gl-canvas");
  gl = WebGLUtils.setupWebGL(canvas);
  if (!gl) {
    alert("WebGL isn't available");
  }

  var colors = [
    vec4(0.3921, 0.5843, 0.9294, 1.0), //Default
    vec4(0.0, 0.0, 0.0, 1.0), // black
    vec4(1.0, 0.0, 0.0, 1.0), // red
    vec4(1.0, 1.0, 0.0, 1.0), // yellow
    vec4(0.0, 1.0, 0.0, 1.0), // green
    vec4(0.0, 0.0, 1.0, 1.0), // blue
    vec4(1.0, 0.0, 1.0, 1.0), // magenta
    vec4(0.0, 1.0, 1.0, 1.0) // cyan
  ];

  gl.viewport(0, 0, canvas.width, canvas.height);

  var m = document.getElementById("mymenu");

  m.addEventListener("click", function() {
    cIndex = m.selectedIndex;
  });
  var a = colors[cIndex][0];
  var b = colors[cIndex][1];
  var c = colors[cIndex][2];
  var d = colors[cIndex][3];
  gl.clearColor(a, b, c, d);

  //  Load shaders and initialize attribute buffers

  var program = initShaders(gl, "vertex-shader", "fragment-shader");
  gl.useProgram(program);

  var vbuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
  gl.bufferData(gl.ARRAY_BUFFER, 8 * 200, gl.STATIC_DRAW);

  var vPosition = gl.getAttribLocation(program, "vPosition");
  gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(vPosition);

  var cBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, 16 * 200, gl.STATIC_DRAW);

  var vColor = gl.getAttribLocation(program, "vColor");
  gl.vertexAttribPointer(vColor, 4, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(vColor);

  canvas.addEventListener("mousedown", function(event) {
    counter++;
    var i = index;

    x = 2 * (event.clientX - 12) / canvas.width - 1;
    y = 2 * (canvas.height - (event.clientY - 165)) / canvas.height - 1;
    var pts = [x, y];

    console.log(pts);
    if (dPoint || (dTri && counter % 3 != 0)) {

      points.push(pts);

    } else if (dTri) {
      index = index - 3;

      tpoints.push(pts);
      tpoints.push(points.pop());
      tpoints.push(points.pop());

      count++;
    }
    index++;

    gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
    gl.bufferSubData(gl.ARRAY_BUFFER, 8 * i, flatten(pts));

    t = vec4(colors[cIndex]);
    gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
    gl.bufferSubData(gl.ARRAY_BUFFER, 16 * i, flatten(t));

  });

  render();
};

function drawTriangles() {
  dTri = true;
  dPoint = false;
  counter = 0;
}

function drawPoints() {
  dTri = false;
  dPoint = true;
}

function render() {
  gl.clear(gl.COLOR_BUFFER_BIT);

  gl.drawArrays(gl.POINTS, 0, index);
  gl.drawArrays(gl.TRIANGLES, 0, count);

  window.requestAnimationFrame(render);
}

function clearC() {
  var oldcanv = document.getElementById('gl-canvas');
  document.body.removeChild(oldcanv);

  var canv = document.createElement('canvas');
  canv.id = 'gl-canvas';
  canv.width = 500;
  canv.height = 500;
  document.body.appendChild(canv);

  index = 0;
  count = 0;
  init();
}
<!DOCTYPE html>
<html>

<head>
  <title>CG - Part2</title>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">

  <script id="vertex-shader" type="x-shader/x-vertex">
    attribute vec4 vPosition; attribute vec4 vColor; varying vec4 fColor; void main() { gl_Position = vPosition; gl_PointSize = 10.0; fColor = vColor; }
  </script>

  <script id="fragment-shader" type="x-shader/x-fragment">
    precision mediump float; varying vec4 fColor; void main() { gl_FragColor = fColor; }
  </script>
  <script src="https://www.cs.unm.edu/~angel/WebGL/7E/Common/initShaders.js"></script>
  <script src="https://www.cs.unm.edu/~angel/WebGL/7E/Common/MV.js"></script>
  <script src="https://www.cs.unm.edu/~angel/WebGL/7E/Common/webgl-utils.js"></script>
  <script>
    window.onload = init;
  </script>
</head>

<body>
  <div style="margin-top: 10px; margin-bottom: 10px">
    <input type="button" onClick="clearC()" value="Clear">
    <input type="button" onClick="drawTriangles()" value="Draw Triangles">
    <input type="button" onClick="drawPoints()" value="Draw Points">
    <select id="mymenu" size="8">
      <option selected value="0">Default</option>
      <option value="1">Black</option>
      <option value="2">Red</option>
      <option value="3">Yellow</option>
      <option value="4">Green</option>
      <option value="5">Blue</option>
      <option value="6">Magenta</option>
      <option value="7">Cyan</option>
    </select>
  </div>
  <canvas id="gl-canvas" width="500" height="500">
    Oops ... your browser doesn't support the HTML5 canvas element
  </canvas>


</body>

</html>

如您所见,画布使用点数组而不是三角形点数组来绘制三角形。任何人都可以看到我出错的地方吗?

更新:

var gl, canvas, program, colors, menu;

var points = [];
var tpoints = [];
var cpoints = [];

var colorsP = [];
var tcolorsP = [];
var ccolorsP = [];

var pointIndex = 0;
var triangleIndex = 0;
var circleIndex = 0;
var colorIndex = 0;

var counter = 0;
var numTris = 100;
var degPerTri = (2 * Math.PI) / numTris;

var dTri = false;
var dPoint = true;
var dCircle = false;

var vbuffer;
var cBuffer;

function begin() {
    canvas = document.getElementById("gl-canvas");
    gl = WebGLUtils.setupWebGL(canvas);
    if (!gl) { alert("WebGL isn't available"); }

    gl.viewport(0, 0, canvas.width, canvas.height);

    program = initShaders(gl, "vertex-shader", "fragment-shader");
    gl.useProgram(program);

    colors = [
        vec4(0.3921, 0.5843, 0.9294, 1.0), //Default
        vec4(0.0, 0.0, 0.0, 1.0),  // black
        vec4(1.0, 0.0, 0.0, 1.0),  // red
        vec4(1.0, 1.0, 0.0, 1.0),  // yellow
        vec4(0.0, 1.0, 0.0, 1.0),  // green
        vec4(0.0, 0.0, 1.0, 1.0),  // blue
        vec4(1.0, 0.0, 1.0, 1.0),  // magenta
        vec4(0.0, 1.0, 1.0, 1.0)   // cyan
    ];

    r = colors[colorIndex][0];
    g = colors[colorIndex][1];
    b = colors[colorIndex][2];
    a = colors[colorIndex][3];

    gl.clearColor(r, g, b, a);

    menu = document.getElementById("mymenu");
}

function init() {
    begin();

    vbuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
    gl.bufferData(gl.ARRAY_BUFFER, 8 * 200, gl.STATIC_DRAW);

    var vPosition = gl.getAttribLocation(program, "vPosition");
    gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(vPosition);

    cBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, 16 * 200, gl.STATIC_DRAW);

    var vColor = gl.getAttribLocation(program, "vColor");
    gl.vertexAttribPointer(vColor, 4, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(vColor);

    menu.addEventListener("click", function () {
        colorIndex = menu.selectedIndex;
    });

    canvas.addEventListener("mousedown", function (event) {
        var mousePos = getMousePos(canvas, event);
        x = 2 * (mousePos.x - 5) / canvas.width - 1;
        y = 2 * (canvas.height - (mousePos.y - 5)) / canvas.height - 1;
        var pts = [x, y];

        counter++;

        console.log('Punkt : ', pts);

        if (dPoint || (dTri && counter % 3 != 0) || (dCircle && counter % 2 != 0)) {
            points.push(pts);
            colorsP.push(vec4(colors[colorIndex]));
        } else if (dTri) {
            pointIndex = pointIndex - 3;

            tpoints.push(pts);
            tcolorsP.push(vec4(colors[colorIndex]));

            tpoints.push(points.pop());
            tcolorsP.push(colorsP.pop());

            tpoints.push(points.pop());
            tcolorsP.push(colorsP.pop());

            triangleIndex++;
        } else if (dCircle) {

            pointIndex = pointIndex - 2;

            cpoints.push(pts);
            ccolorsP.push(vec4(colors[colorIndex]));

            cpoints.push(points.pop());
            ccolorsP.push(colorsP.pop());

            var xs = cpoints[0][0] - cpoints[1][0];
            var ys = cpoints[0][1] - cpoints[1][1];

            console.log('Diff x:',xs, ' Diff y:',ys);

            var radius = Math.sqrt(Math.pow(xs, 2) + Math.pow(ys, 2));
            console.log(radius);

            cpoints = [
                 cpoints[0][0], cpoints[0][1],
                 cpoints[1][0], cpoints[1][1]
            ];

            console.log('Punkt nr: 0', 'X Koordinat:', cpoints[0], 'Y Koordinat:', cpoints[1]);
            console.log('Punkt nr: 1', 'X Koordinat:', cpoints[2], 'Y Koordinat:', cpoints[3]);
            for (var i = 0; i < numTris; i++) {
                var index = 2 * 2 + i * 2;
                var angle = degPerTri * (i+1);

                cpoints[index] = (Math.cos(angle) / 4);
                cpoints[index + 1] = (Math.sin(angle) / 4);

                console.log('Punkt nr:', index, 'X Koordinat:', cpoints[index], 'Y Koordinat:', cpoints[index+1]);
            }
            circleIndex++;
        }
        pointIndex++;
    });
    render();
};

function drawCircles() {
    dTri = false;
    dPoint = false;
    dCircle = true;
    counter = 0;
}

function drawTriangles() {
    dTri = true;
    dPoint = false;
    dCircle = false;
    counter = 0;
}

function drawPoints() {
    dTri = false;
    dPoint = true;
    dCircle = false;
}

function render() {
    gl.clear(gl.COLOR_BUFFER_BIT);

    gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
    gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(points));
    gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
    gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(colorsP));
    gl.drawArrays(gl.POINTS, 0, pointIndex);

    gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
    gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(tpoints));
    gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
    gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(tcolorsP));
    gl.drawArrays(gl.TRIANGLES, 0, triangleIndex * 3);

    gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
    gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(cpoints));
    gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
    gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(ccolorsP));
    gl.drawArrays(gl.TRIANGLE_FAN, 0, 52 * (circleIndex * 2));

    window.requestAnimationFrame(render);
}

function clearC() {
    var oldcanv = document.getElementById('gl-canvas');
    document.body.removeChild(oldcanv);

    var canv = document.createElement('canvas');
    canv.id = 'gl-canvas';
    canv.width = 500;
    canv.height = 500;
    document.body.appendChild(canv);

    pointIndex = 0;
    triangleIndex = 0;
    circleIndex = 0;
    counter = 0;

    points = [];
    colorsP = [];
    tpoints = [];
    tcolorsP = [];
    cpoints = [];
    ccolorsP = [];

    init();
}

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
        x: evt.clientX - rect.left,
        y: evt.clientY - rect.top
    };
}

1 个答案:

答案 0 :(得分:1)

对不起,我不是javascript大师,但这里的代码正在运行:

var gl;

var points = [];
var tpoints = [];

var colorsP = [];
var tcolorsP = [];

var index = 0;
var cIndex = 0;

var dTri = false;
var dPoint = true;

var vbuffer;
var cBuffer;

var count = 0;
var counter = 0;

function init() {
  var canvas = document.getElementById("gl-canvas");
  gl = WebGLUtils.setupWebGL(canvas);
  if (!gl) {
    alert("WebGL isn't available");
  }

  colors = [
    vec4(0.3921, 0.5843, 0.9294, 1.0), //Default
    vec4(0.0, 0.0, 0.0, 1.0), // black
    vec4(1.0, 0.0, 0.0, 1.0), // red
    vec4(1.0, 1.0, 0.0, 1.0), // yellow
    vec4(0.0, 1.0, 0.0, 1.0), // green
    vec4(0.0, 0.0, 1.0, 1.0), // blue
    vec4(1.0, 0.0, 1.0, 1.0), // magenta
    vec4(0.0, 1.0, 1.0, 1.0) // cyan
  ];

  gl.viewport(0, 0, canvas.width, canvas.height);

  var m = document.getElementById("mymenu");

  m.addEventListener("click", function() {
    cIndex = m.selectedIndex;
  });
  var a = colors[cIndex][0];
  var b = colors[cIndex][1];
  var c = colors[cIndex][2];
  var d = colors[cIndex][3];
  gl.clearColor(a, b, c, d);

  //  Load shaders and initialize attribute buffers

  var program = initShaders(gl, "vertex-shader", "fragment-shader");
  gl.useProgram(program);

  vbuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
  gl.bufferData(gl.ARRAY_BUFFER, 8 * 200, gl.STATIC_DRAW);

  var vPosition = gl.getAttribLocation(program, "vPosition");
  gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(vPosition);

  cBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, 16 * 200, gl.STATIC_DRAW);

  var vColor = gl.getAttribLocation(program, "vColor");
  gl.vertexAttribPointer(vColor, 4, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(vColor);

  canvas.addEventListener("mousedown", function(event) {
    counter++;
    var i = index;

    x = 2 * (event.clientX - 12) / canvas.width - 1;
    y = 2 * (canvas.height - (event.clientY - 165)) / canvas.height - 1;
    var pts = [x, y];

    console.log(pts);
    if (dPoint || (dTri && counter % 3 != 0)) {
      points.push(pts);
      colorsP.push(vec4(colors[cIndex]));
    } else if (dTri) {
      index = index - 3;

      tpoints.push(pts);
      tcolorsP.push(vec4(colors[cIndex]));

      tpoints.push(points.pop());
      tcolorsP.push(colorsP.pop());

      tpoints.push(points.pop());
      tcolorsP.push(colorsP.pop());

      count++;
    }
    index++;
  });

  render();
};

function drawTriangles() {
  dTri = true;
  dPoint = false;
  counter = 0;
}

function drawPoints() {
  dTri = false;
  dPoint = true;
}

function render() {
  gl.clear(gl.COLOR_BUFFER_BIT);

  gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
  gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(points));
  gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
  gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(colorsP));
  gl.drawArrays(gl.POINTS, 0, index);

  gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
  gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(tpoints));
  gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
  gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(tcolorsP));
  gl.drawArrays(gl.TRIANGLES, 0, count*3);

  window.requestAnimationFrame(render);
}

function clearC() {
  var oldcanv = document.getElementById('gl-canvas');
  document.body.removeChild(oldcanv);

  var canv = document.createElement('canvas');
  canv.id = 'gl-canvas';
  canv.width = 500;
  canv.height = 500;
  document.body.appendChild(canv);

  index = 0;
  count = 0;
  init();
}

出了什么问题以及我做了什么:

gl.drawArrays(gl.TRIANGLES, 0, count); -> gl.drawArrays(gl.TRIANGLES, 0, count*3);

drawArrays需要点数,因此需要3 *个三角形。

我假设你想要三角形的单独点,所以你不能混合三角形顶点和点。每次点击鼠标后,您都会发送大约1点及其颜色的数据。永远不要更改以前的数据,以便gl.drawArrays(gl.POINTS, 0, index);正常工作。但是你想绘制三角形,所以你需要提供新的数据。您在tpoints中存储了三角形的顶点,但从未将其发送到GPU内存中。所以你需要在2个VAO中创建4个缓冲区(2个位置,2个颜色)或者(这更简单,我在上面显示)每帧复制数据两次 - 一次为点提供数据,为三角提供一次。

我希望它有所帮助,随时可以提出更多问题。

编辑:

var gl, canvas, program, colors, menu;

  var points = [];
  var tpoints = [];
  var cpoints = [];

  var colorsP = [];
  var tcolorsP = [];
  var ccolorsP = [];

  var pointIndex = 0;
  var triangleIndex = 0;
  var circleIndex = 0;
  var colorIndex = 0;

  var counter = 0;
  var numTris = 20;
  var degPerTri = (2 * Math.PI) / numTris;

  var dTri = false;
  var dPoint = true;
  var dCircle = false;

  var vbuffer;
  var cBuffer;

  function begin() {
      canvas = document.getElementById("gl-canvas");
      gl = WebGLUtils.setupWebGL(canvas);
      if (!gl) { alert("WebGL isn't available"); }

      gl.viewport(0, 0, canvas.width, canvas.height);

      program = initShaders(gl, "vertex-shader", "fragment-shader");
      gl.useProgram(program);

      colors = [
          vec4(0.3921, 0.5843, 0.9294, 1.0), //Default
          vec4(0.0, 0.0, 0.0, 1.0),  // black
          vec4(1.0, 0.0, 0.0, 1.0),  // red
          vec4(1.0, 1.0, 0.0, 1.0),  // yellow
          vec4(0.0, 1.0, 0.0, 1.0),  // green
          vec4(0.0, 0.0, 1.0, 1.0),  // blue
          vec4(1.0, 0.0, 1.0, 1.0),  // magenta
          vec4(0.0, 1.0, 1.0, 1.0)   // cyan
      ];

      r = colors[colorIndex][0];
      g = colors[colorIndex][1];
      b = colors[colorIndex][2];
      a = colors[colorIndex][3];

      gl.clearColor(r, g, b, a);

      menu = document.getElementById("mymenu");
  }

  function init() {
      begin();

      vbuffer = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
      gl.bufferData(gl.ARRAY_BUFFER, 8 * 200, gl.STATIC_DRAW);

      var vPosition = gl.getAttribLocation(program, "vPosition");
      gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
      gl.enableVertexAttribArray(vPosition);

      cBuffer = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
      gl.bufferData(gl.ARRAY_BUFFER, 16 * 200, gl.STATIC_DRAW);

      var vColor = gl.getAttribLocation(program, "vColor");
      gl.vertexAttribPointer(vColor, 4, gl.FLOAT, false, 0, 0);
      gl.enableVertexAttribArray(vColor);

      menu.addEventListener("click", function () {
          colorIndex = menu.selectedIndex;
      });

      canvas.addEventListener("mousedown", function (event) {
          var mousePos = getMousePos(canvas, event);
          x = 2 * (mousePos.x - 5) / canvas.width - 1;
          y = 2 * (canvas.height - (mousePos.y - 5)) / canvas.height - 1;
          var pts = [x, y];

          counter++;

          console.log('Punkt : ', pts);

          if (dPoint || (dTri && counter % 3 != 0) || (dCircle && counter % 2 != 0)) {
              points.push(pts);
              colorsP.push(vec4(colors[colorIndex]));
          } else if (dTri) {
              pointIndex = pointIndex - 3;

              tpoints.push(pts);
              tcolorsP.push(vec4(colors[colorIndex]));

              tpoints.push(points.pop());
              tcolorsP.push(colorsP.pop());

              tpoints.push(points.pop());
              tcolorsP.push(colorsP.pop());

              triangleIndex++;
          } else if (dCircle) {

              pointIndex = pointIndex - 2;

              var p2 = pts;
              var p1 = points.pop();

              var c2 = vec4(colors[colorIndex]);
              var c1 = colorsP.pop();

              var xs = p1[0] - p2[0];
              var ys = p1[1] - p2[1];

              console.log('Diff x:',xs, ' Diff y:',ys);

              var radius = Math.sqrt(Math.pow(xs, 2) + Math.pow(ys, 2));
              console.log(radius);

              console.log('Punkt nr: 0', 'X Koordinat:', p1, 'Y Koordinat:', cpoints[1]);
              console.log('Punkt nr: 1', 'X Koordinat:', cpoints[2], 'Y Koordinat:', cpoints[3]);
              for (var i = 0; i < numTris; i++) {
                var angle1 = degPerTri * (i);
                var angle2 = degPerTri * (i+1);
                var pt2 = vec2(Math.cos(angle1)*radius, Math.sin(angle1)*radius);
                var pt3 = vec2(Math.cos(angle2)*radius, Math.sin(angle2)*radius);
                var p2 = vec2(p1[0]+pt2[0], p1[1]+pt2[1]);
                var p3 = vec2(p1[0]+pt3[0], p1[1]+pt3[1]);
                cpoints.push(p1);
                cpoints.push(p2);
                cpoints.push(p3);

                ccolorsP.push(c1);
                ccolorsP.push(c2);
                ccolorsP.push(c2);

              }
              console.log(cpoints);
              circleIndex++;
          }
          pointIndex++;
      });
      render();
  };

  function drawCircles() {
      dTri = false;
      dPoint = false;
      dCircle = true;
      counter = 0;
  }

  function drawTriangles() {
      dTri = true;
      dPoint = false;
      dCircle = false;
      counter = 0;
  }

  function drawPoints() {
      dTri = false;
      dPoint = true;
      dCircle = false;
  }

  function render() {
      gl.clear(gl.COLOR_BUFFER_BIT);

      gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
      gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(points));
      gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
      gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(colorsP));
      gl.drawArrays(gl.POINTS, 0, pointIndex);

      gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
      gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(tpoints));
      gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
      gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(tcolorsP));
      gl.drawArrays(gl.TRIANGLES, 0, triangleIndex * 3);

      gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
      gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(cpoints));
      gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
      gl.bufferSubData(gl.ARRAY_BUFFER, 0, flatten(ccolorsP));
      gl.drawArrays(gl.TRIANGLES, 0, 3*circleIndex*numTris);

      window.requestAnimationFrame(render);
  }

  function clearC() {
      var oldcanv = document.getElementById('gl-canvas');
      document.body.removeChild(oldcanv);

      var canv = document.createElement('canvas');
      canv.id = 'gl-canvas';
      canv.width = 500;
      canv.height = 500;
      document.body.appendChild(canv);

      pointIndex = 0;
      triangleIndex = 0;
      circleIndex = 0;
      counter = 0;

      points = [];
      colorsP = [];
      tpoints = [];
      tcolorsP = [];
      cpoints = [];
      ccolorsP = [];

      init();
  }

  function getMousePos(canvas, evt) {
      var rect = canvas.getBoundingClientRect();
      return {
          x: evt.clientX - rect.left,
          y: evt.clientY - rect.top
      };
  }

我改变了什么:

var numTris = 20;

使用gl.bufferData在GPU上分配一些内存并复制一些数据(或不复制)。使用gl.bufferSubData,您只需复制数据而不分配任何内存。如果您的数据大于分配的内存,您将遇到大麻烦。

gl.drawArrays(gl.TRIANGLES, 0, 3*circleIndex*numTris);

使用gl.TRIANGLE_FAN,您将无法绘制多个圆圈,因为风扇中的三角形已连接。我也删除了魔法常数。

for (var i = 0; i < numTris; i++) {
  var angle1 = degPerTri * (i);
  var angle2 = degPerTri * (i+1);
  var pt2 = vec2(Math.cos(angle1)*radius, Math.sin(angle1)*radius);
  var pt3 = vec2(Math.cos(angle2)*radius, Math.sin(angle2)*radius);
  var p2 = vec2(p1[0]+pt2[0], p1[1]+pt2[1]);
  var p3 = vec2(p1[0]+pt3[0], p1[1]+pt3[1]);
  cpoints.push(p1);
  cpoints.push(p2);
  cpoints.push(p3);

  ccolorsP.push(c1);
  ccolorsP.push(c2);
  ccolorsP.push(c2);
}

你在这里做了一些疯狂的事情,给cpoints分配一些值而不是改变它,一团糟。在这里,我为圆圈中的每个三角形推出3个位置和3种颜色。抱歉有额外的作业,但javascript字符串连接而不是添加让我发疯;)p1也是圈子的中心