Tied Together With Color

Use the new vertices along with the existing methods to draw the colored triangle.

156                 // Here we create and compile the vertex shader. This will compile to code for your specific
157                 // graphics card.
158                 var vertexShader = compileShader(gl, vertexShaderSource, gl.VERTEX_SHADER);
159 
160                 // And then compile the fragment shader too.
161                 var fragmentShader = compileShader(gl, fragmentShaderSource, gl.FRAGMENT_SHADER);
162 
163                 // As you might expect, we are going to run some code, so we need a program.
164                 var program = createProgram(gl, vertexShader, fragmentShader);
165 
166                 // Make this the currently active program
167                 gl.useProgram(program);
168 
169                 // This is a handle to what will be a buffer
170                 var vertexBuffer = createBuffer(vertices);
171 
172                 // Bind the buffer to the positon attribute
173                 bindBuffer(vertexBuffer, 'position', 3, gl.FLOAT, 28, 0);
174 
175                 // And to the color attribute
176                 bindBuffer(vertexBuffer, 'color', 4, gl.FLOAT, 28, 12);
177 
178                 // Finally run the program. Render, or draw, the data. Here we tell it to draw triangles starting
179                 // with element zero of the vertexBuffer, and that there are three vertices. So there is
180                 // one triangle.
181                 gl.drawArrays(gl.TRIANGLES, 0, 3);
(0,1) (-1,-1) (1,-1)

Notes

This is almost the same program as the original. Only the mapping of the array buffer to the shader attributes is altered.

Let's look at the difference between the original mapping of the vertex array to the position attribute and the one that includes color data.

167                 bindBuffer(vertexPositionBuffer, 'position', 3, gl.FLOAT, 12, 0);
173                 bindBuffer(vertexBuffer, 'position', 3, gl.FLOAT, 28, 0);

The difference is in the stride. The original version reads three floating point numbers, which occupy 12 bytes. So it reads the next set of three floating point numbers immediately.

The stride of 28 forces 16 bytes to be skipped (12 bytes of data + 16 bytes skipped = 28 bytes) between reading sets of position values. The skipped 16 bytes contain the four floating point color values.

Those four floating point values are mapped into the color attribute.

176                 bindBuffer(vertexBuffer, 'color', 4, gl.FLOAT, 28, 12);

Here we see an offset of 12, which skips the first 12 bytes in the buffer before reading the 16 bytes of color values. Another 12 bytes, the position data, are then skipped before reading another set of color values.