Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why must you use both glBindBuffer and glBindBufferRange to create a uniform buffer in OpenGL?

Tags:

c++

opengl

To create a uniform buffer object in OpenGL, why must I call both glBindBuffer and glBindBufferRange? According to documentation,

Think of glBindBufferRange as binding the buffer to two places: the particular index and the target​. glBindBuffer only binds to the target​, not the index.

So then glBindBuffer seems superfluous to me if you are already binding a buffer to that same target using glBindBufferRange.

I am reading Learning Modern 3D Graphics Programming and chapter 7 shows how to make uniform buffer objects. The code used in the book:

glGenBuffers(1, &g_GlobalMatricesUBO);
glBindBuffer(GL_UNIFORM_BUFFER, g_GlobalMatricesUBO);
glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::mat4) * 2, NULL, GL_STREAM_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);

glBindBufferRange(GL_UNIFORM_BUFFER, g_iGlobalMatricesBindingIndex, g_GlobalMatricesUBO, 0, sizeof(glm::mat4) * 2);

This code works until I comment out the call to glBufferData, in which case I get a black screen. This is surprising to me because afterwards we are binding g_GlobalMatricesUBO to the GL_UNIFORM_BUFFER binding target anyways. The documentation linked to earlier also says:

Do note that this does not replace standard buffer binding with glBindBuffer. It does in fact bind the buffer to the target​ parameter, thus unbinding whatever was bound to that target. But usually when you use glBindBufferRange, you are serious about wanting to use the buffer rather than just modify it.

Which seems to touch on what I'm confused about, but I do not understand this explanation. It says it unbinds whatever was previously bound to the target, which seems to reinforce my (wrong) idea that binding a buffer to the target beforehand is unnecessary.

like image 686
David DiGioia Avatar asked Oct 19 '25 11:10

David DiGioia


1 Answers

glBufferData does not only initialize the buffer, it creates the buffer object's data store with the specified size. You can think about it like memory allocation in c++.
glBufferData creates a data store for the buffer object which is currently bound to the specified target. In this case it creates a data store for the named buffer object g_GlobalMatricesUBO, because it is bound to the specified target GL_UNIFORM_BUFFER.

glBindBufferRange doesn't create any data store, it use the data store which has to exist. The buffer object with the data store is specified by the 3rd parameter.

like image 200
Rabbid76 Avatar answered Oct 21 '25 00:10

Rabbid76



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!