10

The specification for the glVertexAttribPointer is as follows:

void glVertexAttribPointer( GLuint index,
    GLint size,
    GLenum type,
    GLboolean normalized,
    GLsizei stride,
    const GLvoid * pointer);

Given that the last parameter is just a 4-byte integer offset, why does OpenGL expect it to be passed in as a void pointer?

Nathan Ridley
  • 33,766
  • 35
  • 123
  • 197

2 Answers2

14

Legacy.

That argument had a different meaning before VBOs: you'd keep the vertex data in client memory and pass the address of the array (see glEnableClientState and such).

Now the last parameter can have 2 meanings (offset for buffer objects, address for client state arrays). Khronos did not provide a separate version for gl*Pointer functions for buffer objects, so you need to do this awkward cast.

Kos
  • 70,399
  • 25
  • 169
  • 233
  • Ah, thanks. Begs the question though, why did they feel the need to reuse an old function instead of just making a new one? – Nathan Ridley Jan 21 '15 at 09:17
  • 1
    @NathanRidley: Lazyness on their side and to make transitioning of old code easier. If you feel uncomfortable using that function, OpenGL-4 introduces a set of new vertex attribute binding function you can use instead: glVertexArrayAttribBinding glVertexArrayAttribFormat – datenwolf Jan 21 '15 at 09:25
  • @datenwolf Thanks, I was using openglbook.com - any resources you recommend? – Nathan Ridley Jan 21 '15 at 09:29
  • IMHO http://arcsynthesis.org/gltut is one of the best tutorials there currently is. – datenwolf Jan 21 '15 at 09:55
  • @datenwolf I think you mean glVertexAttribBinding and glVertexAttribFormat? https://www.opengl.org/sdk/docs/man/html/glVertexAttribBinding.xhtml https://www.opengl.org/sdk/docs/man/html/glVertexAttribFormat.xhtml (Two links) – FreelanceConsultant Oct 13 '15 at 20:57
  • @user3728501: Indeed. Unfortunately when I realized my typo, the comment was already older than 5 minutes, so I left it there. Also if you Google those names you'll find the right references. Call me lazy ;-) – datenwolf Oct 13 '15 at 21:26
  • @datenwolf Okay - just checking! My second guess was the standard had been updated / modified. – FreelanceConsultant Oct 13 '15 at 21:27
3

One way of looking at it is that the last argument is always a pointer:

  • If no VBO is bound, it's a pointer relative to base address 0. Which is a regular memory address, just the way pointers are normally used in C/C++.
  • If a VBO bound, it's a pointer relative to the base address of the buffer.

At least that's the only logical explanation I could ever find.

Personally, I think that overloading the entry point this way was a very unfortunate decision, for a number of reasons:

  • It confuses people to no end.
  • It requires ugly type casts in C/C++.
  • It does not work at all in more type safe languages, like Java.

In languages like Java, you typically end up with overloaded versions of the function that accept different types. As a somewhat curious historical note, the overloaded version with an int argument was missing in the initial version of the GLES20 bindings in Android, which meant that you could not use VBOs from Java. So this has tripped up more that just the occasional casual OpenGL programmer.

Reto Koradi
  • 53,228
  • 8
  • 93
  • 133
  • Is the regular memory addrses version for when you map the VBO to user space memory? – RobC Jan 11 '17 at 06:23