Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference in glGenBuffers and glCreateBuffers

Tags:

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 in buffers, 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 with glDeleteBuffers.

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

like image 358
RamblingMad Avatar asked Aug 05 '15 19:08

RamblingMad


People also ask

What does it mean to bind a buffer?

Binding a buffer to a target is something like setting a global variable. Subsequent function calls then operate on that global data. In the case of OpenGL all the "global variables" together form a GL context. Virtually all GL functions read from that context or modify it in some way.

What is GL buffer?

Buffer Objects are OpenGL Objects that store an array of unformatted memory allocated by the OpenGL context (AKA the GPU). These can be used to store vertex data, pixel data retrieved from images or the framebuffer, and a variety of other things.

What does binding mean in OpenGL?

A Binding Point specifies the behavior of the OpenGL object. Binding Points, also known as Targets, allows OpenGL objects to be used for different purposes. The most common binding points are: GL_ARRAy_BUFFER.


2 Answers

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.

like image 171
Andon M. Coleman Avatar answered Sep 18 '22 23:09

Andon M. Coleman


OpenGL 4.5 Specification - 6.1 Creating and Binding Buffer Objects:

A buffer object is created by binding a name returned by GenBuffers to a buffer target. The binding is effected by calling

void BindBuffer( enum target, uint buffer );

target must be one of the targets listed in table 6.1. If the buffer object named buffer has not been previously bound, the GL creates a new state vector, initialized with a zero-sized memory buffer and comprising all the state and with the same initial values listed in table 6.2.

So the difference between glGenBuffers and glCreateBuffers is, that glGenBuffers only returns an unused name, while glCreateBuffers also creates and initializes the state vector described above.


Usage:

It is recommended to use glGenBuffers + glBindBuffer, because

the GL may make different choices about storage location and layout based on the initial binding.

Since in glCreateBuffers no initial binding is given this choice cannot be made.

like image 24
dari Avatar answered Sep 21 '22 23:09

dari