By modern standards, the preferred way of rendering polygon meshes seems to involve the use of Vertex Buffer Objects in conjunction with index buffers (ultimately drawn by calls to glDrawElements()
), which is exactly why I'm trying to wrap my head around these concepts. Also, I insist on using glVertexAttribPointer()
instead of the deprecated glVertexPointer()
, glNormalPointer()
etc.
I'm using a custom, binary 3d file format (a Wavefront .OBJ derivative), the contents of which can be more or less directly memcpy()
'd to a vertex array. Here's how I've declared my vertex
structure:
typedef struct vertex_ {
float vx,vy,vz;
float nx,ny,nz;
float padding[2]; // align to 32 bytes
} vertex;
The loadBObj()
function returns an index buffer (implemented as a simple array of unsigned short int
s), and fills up the vertex array with the associated vertex/normal data (the models used all have been exported to have per-vertex-normals for a smoother shading result).
indices = loadBObj("pharaoh.bobj", false, &VBOid);
The loading code itself is verified to work appropriately.
Now, what's also being done in loadBObj()
is a new VBO is being created like so:
glGenBuffers(1, VBOid);
glBindBuffer(GL_ARRAY_BUFFER, *VBOid);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex)*vcount, &vertarray[0].vx, GL_STATIC_DRAW);
AfterloadBObj()
is called, an index buffer object (probably shouldn't be referred to as such though) is created as follows:
glGenBuffers(1, &IBOid);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBOid);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short int)*qfcount*4, indices, GL_STATIC_DRAW);
OK. When it comes to actually rendering the mesh, I've used the following code:
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
...
glBindBuffer(GL_ARRAY_BUFFER, VBOid);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), BUFFER_OFFSET(0));
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), BUFFER_OFFSET(3*sizeof(float)));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBOid);
glDrawElements(GL_QUADS, qfcount*4, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
which results in an absolutely correct geometry, but the shading is not quite right:
- Here's an image of the model, rendered in immediate mode:
img http://i44.tinypic.com/i36zcg.png
- here's one produced by the program described above:
Is there something funny going on in my VBO handling?
GL_QUADS
is deprecated and gone from the core profile. – Cat Plus Plus