5. OpenGL 4 Vertex Buffer Objects (VBOs) for Color
If you remember back to the last tutorial, I mentioned that because we no longer have the fixed function pipeline, we no longer have calls for creating primitives such as glBegin(GL_TRIANGLES). Well this also holds for the glColor calls as they were a part of the fixed function pipeline. So how do we change the colour of our shapes and vertices? Well just like we created a Vertex Buffer Object (VBO) to store our vertices, we can do exactly the same thing with our colours and then place this new VBO inside of the Vertex Array Object (VAO) with the vertices.
Is this difficult? Definitely not, all we have to do, is exactly the same thing as we did for the vertices. Also, because when we set up our shaders back in one of the first couple of tutorials, we specified permanent variables for passing vertices and colours to our shader, so our second VBO will automatically be interpreted as the colour portion of our VAO.
An important thing to note is that for every per-vertex attribute you have, you can store it all inside of the same Vertex Array Object, each in its own Vertex Buffer Object and link the VBO to the shader by binding the attribute locations, the same way we bound in_Position and in_Color.
To start off, I am going to open up opengl_3.h and you might remember we created an array to hold our VBO’s. Well this array had a length of 1, so we are going to give that a bump up to 2 like so:
unsigned int vboID; // Our Vertex Buffer Object
Now switch over to opengl_3.cpp and we are going to start setting up our colour VBO. Go ahead, and just under where we created the variable for the vertices array, do a copy and paste, but call this variable colors. You will get something like this:
float *vertices = new float; // Vertices for our square float *colors = new float; // Colors for our vertices
As a vertex takes up 3 values for x, y and z. We are going to use 3 values for our colour, being r, g and b. You can also jump this up to r, g, b and a, you just need to add an extra float value for each vertex you have and also change the VBO to use 4 variables per vertex instead of 3.
But for simplicity we are going to stick with no alpha value, and hence no alpha blending. So just as we created our vertices, do the exact same thing, but using the colour variable. I am using the colours white for bottom left, red for top left, green for top right and blue for bottom right.
vertices = -0.5; vertices = -0.5; vertices = 0.0; // Bottom left corner colors = 1.0; colors = 1.0; colors = 1.0; // Bottom left corner vertices = -0.5; vertices = 0.5; vertices = 0.0; // Top left corner colors = 1.0; colors = 0.0; colors = 0.0; // Top left corner vertices = 0.5; vertices = 0.5; vertices = 0.0; // Top Right corner colors = 0.0; colors = 1.0; colors = 0.0; // Top Right corner vertices = 0.5; vertices = -0.5; vertices = 0.0; // Bottom right corner colors = 0.0; colors = 0.0; colors = 1.0; // Bottom right corner vertices = -0.5; vertices = -0.5; vertices = 0.0; // Bottom left corner colors = 1.0; colors = 1.0; colors = 1.0; // Bottom left corner vertices = 0.5; vertices = 0.5; vertices = 0.0; // Top Right corner colors = 0.0; colors = 1.0; colors = 0.0; // Top Right corner
That should all be looking pretty straight forward. Now we need to go jump down a couple of lines to where we call glGenBuffers(1, &vboID); Bump this also up to 2, so that we are generating 2 vertex buffer objects.
glGenBuffers(2, &vboID); // Generate our two Vertex Buffer Object
And then virtually do a copy and paste of the lines from glBindBuffer to glEnableVertexAttrribArray. Then inside of this big paste block, we want to change our glBindBuffer go the second vboID, so vboID and change the variable vertices from the line glBufferData to the variable colors. Finally we need to change the value from glEnableVertexAttribArray from 0 to 1. So we get this:
glBindBuffer(GL_ARRAY_BUFFER, vboID); // Bind our second Vertex Buffer Object glBufferData(GL_ARRAY_BUFFER, 18 * sizeof(GLfloat), colors, GL_STATIC_DRAW); // Set the size and data of our VBO and set it to STATIC_DRAW glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, 0); // Set up our vertex attributes pointer glEnableVertexAttribArray(1); // Enable the second vertex attribute array
And last but not least, make a call to delete the colors array before we finish our method:
delete  colors; // Delete our vertices from memory
All you have to do now is give this modified code a compile and run it. You should now see a square which instead of red, black (or any other color as it is undefined in the previous tutorial), is now a blend of colours.
If you have any questions you can comment below or email me at firstname.lastname@example.org