1
votes

While learning opengl, one bit of confusion is whether it is necessary to bind buffers like VAO or texture IDs multiple times without unbinding them?

With reference to the above link and the full source code , I have come across 2 scenerios a bit distinct from each other.

First, the author creates a VAO(outside the maindraw loop) and binds the VAO using the glBindVertexArray(VAO) then he doesn't unbind it using glBindVertexArray(0); , but he binds it again in the maindraw loop. My confusion, Is this really necessary? Isn't the currently bound VAO already ... bound? Why bind it when it is already the active VAO?

And,

Second, the author creates texture ID using:

glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);  
//some more code
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);

outside the main draw loop , but does this again *inside the main draw loop: *

 glActiveTexture(GL_TEXTURE0);
 glBindTexture(GL_TEXTURE_2D, texture1);
 glActiveTexture(GL_TEXTURE1);
 glBindTexture(GL_TEXTURE_2D, texture2);

Two things that I don't understand in what he does is:

  1. Why does he bind the texture ID again in the mainloop when he has done it outside of the mainloop?(This one is similar to VAO but I don't know yet if unbinding is possible in here)
  2. Why does he select the active texture unit (using glActiveTexture) inside the loop? Couldn't it be done outside the main draw loop?
1
"but he binds it again in the maindraw loop. My confusion, Is this really necessary?" Not it is not. But if the author would extend the code and use more than 1 VAO, then it would be necessary. - Rabbid76
texture2 is not bound to texture unit 1 when it is creates (bound the 1st time). This is done later. Of course it would also be possible to do that before. Again, if the author would extend his program and want to draw different objects different textures, then it would be necessary to bind them before the drawing the object. - Rabbid76
@Rabbid76 , which mean at this point the code is redundant and that glActiveTexture could also be done outside the loop? And what do you mean by: texture2 is not bound to texture unit 1 when it is creates (bound the 1st time). This is done later.? - juztcode
At glGenTextures(1, &texture2); glBindTexture(GL_TEXTURE_2D, texture2); the current texture unit is 0, so texture2 is bound to texture unit 0. - Rabbid76
glBindTexture binds a texture to specified target and in the current texture unit. If you bind 2 textures behind each other (2 calls to glBindTexture), without switching the texture unit in between (glActiveTexture), then just the 2nd texture is bound - Rabbid76

1 Answers

2
votes

glBindTexture binds a texture to specified target and the current texture unit. The current texture unit is set by glActiveTexture. The current texture unit is a global state, and glBindTexture considers that state.

That meas when you do

glBindTexture(GL_TEXTURE_2D, texture1);
glBindTexture(GL_TEXTURE_2D, texture2);
glActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE1); 

after that texture2 is bound to the current texture unit (GL_TEXTURE0 by default) and the current texture unit is GL_TEXTURE1. Note texture1
is just bound for a short moment, but the binding is lost, when texture2 is bound.

In compare, when you do

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1); 
glBindTexture(GL_TEXTURE_2D, texture2);

The current texture unit is explicitly set to GL_TEXTURE0 and texture1 is bound to texture texture unit 0. After that the current texture unit is switched to GL_TEXTURE1 and texture2 is bound to texture unit 1 (because it is current at this moment).


Note, with the use of Direct State Access and glBindTextureUnit (since OpenGL 4.5) a texture can be bound to a texture unit directly. e.g.:

glBindTextureUnit(GL_TEXTURE0, texture1);
glBindTextureUnit(GL_TEXTURE1, texture2);