Given we are using OpenGL 4.5 or have support for the GL_ARB_direct_state_access
extension, we have the new function glCreateBuffers
.
This function has an identical signature to glGenBuffers
, but specifies:
returns
n
previously unused buffer names inbuffers
, each representing a new buffer object initialized as if it had been bound to an unspecified target
glGenBuffers
has the following specification:
Buffer object names returned by a call to
glGenBuffers
are not returned by subsequent calls, unless they are first deleted withglDeleteBuffers
.
So any buffer name returned by glCreateBuffers
will never be used again by itself, but could be used by glGenBuffers
.
It seems that glCreateBuffers
will always create new buffer objects and return their names, and glGenBuffers
will only create new buffers if there are no previous buffers that have since been deleted.
What advantage does adding this function have?
When should I use glCreateBuffers
over glGenBuffers
?
P.S.
I think this stands for all glCreate*
functions added by GL_ARB_direct_state_access
What you are noticing here is basically tidying up the API for consistency against Shader and Program object creation. Those have always been generated and initialized in a single call and were the only part of the API that worked that way. Every other object was reserved first using glGen* (...)
and later initialized by binding the reserved name to a target.
In fact, prior to GL 3.0 it was permissible to skip glGen* (...)
altogether and create an object simply by binding a unique number somewhere.
In GL 4.5, every type of object was given a glCreate* (...)
function that generates and initializes them in a single call in GL 4.5. This methodology fits nicely with Direct State Access, where modifying (in this case creating) an object does not require altering (and potentially restoring) a binding state.
Many objects require a target (e.g. textures) when using the API this way, but buffer objects are for all intents and purposes typeless. That is why the API signature is identical. When you create a buffer object with this interface, it is "initialized as if it had been bound to an unspecified target." That would be complete nonsense for most types of objects in GL; they need a target to properly initialize them.
The primary consideration here is that you may want to create and setup state for an object in GL without affecting some other piece of code that expects the object bound to a certain target to remain unchanged. That is what Direct State Access was created for, and that is the primary reason these functions exist.
In theory, as dari points out, initializing a buffer object by binding it to a specific target potentially gives the driver hints about its intended usage. I would not put much stock in that though, that is as iffy as the actual usage flags when glBufferData (...)
is called; a hint at best.