6

In OpenGL you have to bind an object to the context to be used in subsequent calls, instead of just using it as an argument in those calls.

For example, in OpenGL you write this

glGenBuffers( 1, &vbo );
glBindBuffer( GL_ARRAY_BUFFER, vbo );
glBufferData( GL_ARRAY_BUFFER, verts.size(), verts.data(), GL_STATIC_DRAW );

Instead of something like this:

glGenBuffers( GL_ARRAY_BUFFER, 1, &vbo );
glBufferData( vbo, verts.size(), verts.data(), GL_STATIC_DRAW );

I wonder, what was the reason behind that decision? Was there a technical reason for this?

Kilian Foth
  • 110,899
Hedede
  • 177

1 Answers1

7

Because legacy. Just about every feature in modern opengl started out as an (optional) extension which had to work nicely when it's there but not used. This means that a lot of the features are based around persistent state.

The oldest opengl versions which had glDrawArrays didn't even have buffers, instead the void* pointer in glVertexAttribPointer (back then they were actually glVertexPointer/glNormalPointer/...) always referred to user space memory instead of an offset into the buffer bound to GL_ARRAY_BUFFER. To make the buffers work with that they had to create the bind points to add the bound buffer as a hidden parameter to existing methods. From there it's logical to use that bind point for the new methods as well to maintain uniformity.

A lot of opengl is bind-to-edit, which Khronos acknowledges is a bad api design. This is why the DSA extensions came about and is now part of the core API since 4.5. These lets you do glNamedBufferData( vbo, verts.size() * sizeof(verts[0]), verts.data(), GL_STATIC_DRAW ); to create and upload your mesh.

ratchet freak
  • 25,986