1
votes

This is my fragment shader:

precision mediump float;

varying vec4 vColor;

void main(void) {
    gl_FragColor = vColor;
}

This is my code that renders buffers associated with a circle (vertices and colors for each vertex):

gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexColorBuffer);
gl.vertexAttribPointer(shaderProgram.vertexColorAttribute, triangleVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0);
setMatrixUniforms();
gl.drawArrays(gl.TRIANGLE_FAN, 0, triangleVertexPositionBuffer.numItems);

Is it possible to somehow render multiple instances of the circle, specifying the color each time? Is it bad practice to do so? Should I resort to making multiple circles, each with a pre-assigned color?

1

1 Answers

1
votes

Why not just change your fragment shader to this?

precision mediump float;

uniform vec4 uColor;

void main(void) {
    gl_FragColor = uColor;
}

Then you can set the color to draw each circle with

gl.uniform4fv(program.uniforms['uColor'], colorOfCircleArrayOf4Floats);

Here's an example

var countElem = document.getElementById("t");
var canvas = document.getElementById("c");
var gl = canvas.getContext("webgl",
                           {preserveDrawingBuffer:true});
var program = twgl.createProgramFromScripts(
    gl, ["vshader", "fshader"], ["a_position"]);
gl.useProgram(program);

var colorLoc = gl.getUniformLocation(program, "u_color");
var matrixLoc = gl.getUniformLocation(program, "u_matrix");

// make circle triangles
var numDivisions = 36;
var verts = [];
for (var ii = 0; ii <= numDivisions; ++ii) {
    var a0 = (ii + 0) * Math.PI * 2 / numDivisions;
    var a1 = (ii + 1) * Math.PI * 2 / numDivisions;
    verts.push(Math.sin(a0), Math.cos(a0));
}

var vertBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);

// make matrix to scale our unit circle.
var aspect = canvas.width / canvas.height;
var scale = 0.25;
var mat = [
    scale, 0, 0, 0,
    0, aspect * scale, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1];
    
function draw() {
   // set translation
   mat[12] = Math.random() * 2 - 1;
   mat[13] = Math.random() * 2 - 1;
   gl.uniformMatrix4fv(matrixLoc, false, mat);
    
   // set color
   gl.uniform4f(colorLoc, Math.random(), Math.random(), Math.random(), 1);

   // draw circle
   gl.drawArrays(gl.TRIANGLE_FAN, 0, numDivisions + 1);
   requestAnimationFrame(draw);
}
draw();
<script src="https://twgljs.org/dist/3.x/twgl.min.js"></script>
<script id="vshader" type="whatever">
    attribute vec4 a_position;
    uniform mat4 u_matrix;
    void main() {
      gl_Position = u_matrix * a_position;
    }    
</script>
<script id="fshader" type="whatever">
precision mediump float;
uniform vec4 u_color;
void main() {
  gl_FragColor = u_color;
}
</script>
<canvas id="c"></canvas>

Note the same answer was given here.