Ok, this is when things start getting a little technical.
This is hard to understand just by reading text, so you may want to look at this modified BasicRenderer class as we're going along: Download source (same as link down the page.)
Basically there are four modes of rendering in OpenGL; we're only going to be using 2 of them, one of them you've already met when you did "Basic block rendering" (Immediate mode).
If you guessed that we'll be using Vertex buffer objects, you guessed right :D
I've decided to split up creating and rendering VBOs into 3 parts to make it easier to explain; I'll then cover how to implement this in our code.
Before we can actually do anything we first have to enable a few OpenGL modes like so (this normal is done at initialisation and doesn't effect our game loop):
Now that's out the way with we need two integers which will store data for the colour of each vertex and the position of each vertex. Why are they stored as ints? I don't honestly know; but I'd imagine it's because integers take up less memory than an array, essentially it stores the data in a compressed format I believe.
After declaring the integers we'll need to format them into a format OpenGL understands by using glGenBuffers (I think this is what happens anyway, unclear from reference) like so:
I generally declare the integers as a private variable inside the class, then use glGenBuffers when creating the VBOs so I can access them in the render method too.
At First we'll be using something called a FloatBuffer to store information about our vertices. FloatBuffer is essentially a one dimensional array of floats (numbers) that OpenGL can interpret. As it is one dimensional, if I wanted to store one vertex with a x,y,z position I'd need to have an array length of at least 3.
This is created using this code:
(sorry for the downsize, I feel it's easier to read on one line)
For now lets just create two FloatBuffers, one for storing colors and one for storing the actual positions of the points (note: each point must have a color). You can use only one buffer and then refer to which parts are color data and which parts are position data (known as interleaving), but for now just use two.
We can then enter data into our FloatBuffers like so:
Pretty self-explanatory, basically data into our floatbuffer; .put can be used as many times as you want to add data onto the end of the buffer so to speak, until you rewind or flip it.
Flip/Rewind: As we've just entered the data in by tagging it on to the end we need to reverse the order of the FloatBuffer so when we send it off to wherever it needs to go it can be read from start to end (in the right order).
To do this we simply use .Flip or .Rewind as so:
The last thing we need to do is tell OpenGL which buffer we are writing to and then write in the float data into our int buffer:
Note: When we use glBindBuffer the second argument is the buffer we want to bind to, so using 0 just means we're not writing to any buffer anymore (unbinding).
This part is actually pretty simple, and we'll want to use this in our game loop to render our VBOs.
First of we need to use glPushMatrix(), this creates a new copy of the matrix we were altering before (modelview, where we store all the vertex information) for us to edit.
We then rebind our buffers in order and tell OpenGL that it can find different vertex information in those buffers using Pointers. E.g.
We can then Draw all the information stored in the buffers by using:
Where parameter 1 is the type of shape to draw, 2 is the starting index of data in out buffers, 3 is the amount of points(vertexes) to render. Note: if there is not enough points to make up the shape it will not be drawn; e.g. putting 3 will not draw a Quad or even a triangle(half a quad)(unless you are drawing a triangle).
And then we need to delete our copy of the matrix we created at the start by using:
This prevents problems like the effects translatef and rotatef being carried on into the next gameloop recursively.
"That's all well and good but how do I set this up with the BasicRenderer class?!"
I decided the explanation would take to long to write out; if you think you're smart enough here's two methods to get you started. Alternatively (and because setting up gluPerspective correctly is a bitch) you can download and study a modified BasicRenderer (now called Game) class I made to test out drawing a cube with VBO using the methods described above.
SOURCE DOWNLOAD: here
Example of creating VBOs
Next stop: using this to render chunks
For those who like pictures here's something I did for COMP4 which uses VBO for color, position and lighting. This pic was generated using a 2D integer array: