Some OpenGL functions, such as glDrawElements , accept a context-sensitive GLvoid * parameter. In older GLs, pre Vertex Buffers, the programmer passed an array of integer indices directly to glDrawElements , for example:
const GLuint indexes[] = { ... }; glDrawElements(GL_TRIANGLES, numIndexes, GL_UNSIGNED_INT, indexes);
This is called an immediate mode schedule.
When vertex and index buffers were introduced, the OpenGL architecture panel decided that they should reuse existing interfaces, thereby giving a new context-dependent meaning to this last pointer parameter void glDrawElements , glVertexAttribPointer and several other similar functions.
With index buffers, the rendering data is already on the GPU, so the void pointer parameter means an offset in the buffer. For example: the first index to render. Following the new use of glDrawElements :
size_t firstIndex = ... size_t indexDataSize = sizeof(GLuint); glDrawElements(GL_TRIANGLES, numIndexes, GL_UNSIGNED_INT, reinterpret_cast<const GLvoid *>(firstIndex * indexDataSize));
This applies to all old functions that have been repurposed on modern OpenGL, for example glDrawElementsInstanced , glDrawElementsBaseVertex , glDrawRangeElements , etc.
Now in the specific case of glVertexAttribPointer :
void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer);
The const GLvoid * pointer parameter represents the offset in bytes from the beginning of the vertex to this element. Again, this was saved like this because the function existed before Vertex / Index Buffers and was reassigned to work with them, whereas in the days of immediate mode you passed an array of vertices as a pointer parameter.
So, in the old days, glVertexAttribPointer will be used a little differently:
const vec3 positions[] = { ... }; glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, positions);
And in modern GL you should use:
struct Vert { vec3 position; vec3 normal; }; size_t offset; offset = offsetof(Vert, position); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, reinterpret_cast<const GLvoid *>(offset)); offset = offsetof(Vert, normal); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, reinterpret_cast<const GLvoid *>(offset));