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?
1 Answer 1
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.
-
Legacy and the fact that OpenGL is a gigantic state machine.whatsisname– whatsisname11/17/2016 17:24:07Commented Nov 17, 2016 at 17:24
-
@whatsisname: "the fact that OpenGL is a gigantic state machine" I don't really know what you mean by that, but that fact hasn't stopped DSA from existing.Nicol Bolas– Nicol Bolas11/18/2016 04:13:01Commented Nov 18, 2016 at 4:13
-
@NicolBolas: I refer to how OpenGl draws depends a great deal on its global state, and the developer must pay close attention to maintaining order to those changes in state, as opposed to typical programming where global state is avoided as much as possible and carefully compartmentalized.whatsisname– whatsisname11/18/2016 04:28:19Commented Nov 18, 2016 at 4:28
-
1@whatsisname the actual question is why did opengl become a gigantic state machine.ratchet freak– ratchet freak11/18/2016 08:52:00Commented Nov 18, 2016 at 8:52
-
1@ratchetfreak that has already been discussed here stackoverflow.com/questions/15194002/…Caramiriel– Caramiriel11/19/2016 15:14:08Commented Nov 19, 2016 at 15:14
glBufferData
:glGenBuffers(1, &vbo); glBufferData(vbo, GL_ARRAY_BUFFER, verts.size(), verts.data(), GL_STATIC_DRAW);
GL_ARRAY_BUFFER
shouldn't even be there, it's a name for a bind point not a type.