set the texture for by glUniform1i - opengl

I have a question about how to set the texture by glUniform1i. I have seen code like below.
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture0);
glUniform1i(_textureUniform, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture1);
glUniform1i(_textureUniform, 1);
Does it mean, if I use the number i in the glUniform1i, then I have to use glActiveTexture(GL_TEXTURE **i** )?

Yes, you are correct. The uniform value for a sampler refers to the texture unit, not the texture id.

Related

Is it bad practice to reuse GL_TEXTURE0 over again when binding different textures?

In many examples, some are reusing GL_TEXTURE0 over and over for different textures, and in other examples they increment the texture slot like so:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, woodTexture);
...
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, metalTexture);
...
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, plasticTexture);
as opposed to
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, woodTexture);
...
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, metalTexture);
...
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, plasticTexture);
Is one or the other bad practice, or even worse for efficiency, or does it not matter at all?
Multiple texture units are for one geometry who has multiple textures. For instance, some lighting shader requires two lighting maps for diffuse and specular. Then you need to provide two textures for two samplers. In this case, you have to active two textures. See the following structure:
struct Material {
sampler2D diffuse;
sampler2D specular;
float shininess;
};
If geometries only have 1 texture, it is ok to just use the GL_TEXTURE0. You don't need to active it multiple times, it will be automatically actived as the default texture

opengl - does glBindTexture overwrite contents of the active texture unit

I was finding the relationship between glActiveTexture(...) and glBindTexture(...) and I found an awesome answer here, the very top answer(the author/user Alfonse) gives us a pseudocode for how the both functions behave, and I understood most of it. But, in it he mentions in calls such as this:
glActiveTexture(GL_TEXTURE0 + 5);
glBindTexture(GL_TEXTURE_2D, object);
glTexImage2D(GL_TEXTURE_2D, ...);
but one often binds a texture to the context just to upload some data or to modify it. It doesn’t matter at that point which texture unit you bind it to, so there’s no need to set the current texture unit. glTexImage2D doesn’t care if the current active texture is 0, 1, 40, or whatever.
So my problem is:
when generating two texture we do something like this:
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
glTextureParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//some more code
//inside the render loop
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
glDrawElements(...); glSwapBuffers();
//end of render loop
Notice, in the code before the render loop, I have used two texture glBindTexture(...) without calling glActiveTexture(...). Since, the default active texture unit is: GL_TEXTURE0, does this mean the parameters set for texture1 is overwritten by texture2?
No, texture parameters (set by glTexParameter) are set for a specific texture (the one that's currently bound to the active texture unit), not for a texture unit (not for one of GL_TEXTUREi, that is).
Note that your use of glTextureParameteri incorrect. Rather than GL_TEXTURE_2D, it expects a handle of a texture, as returned by glGenTextures1. You're confusing it with glTexParameteri, which indeed can be called with GL_TEXTURE_2D.
1 As noted by #derhass, glGenTextures (unlike glCreateTextures) merely reserves the handle. A texture with this handle is created only when you pass it to glBindTexture. It doesn't matter if you use glTexParameter, but if you want to use glTextureParameteri and other functions that operate directly on texture handles, it might be important.

binding buffers multiple times in openGL

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:
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)
Why does he select the active texture unit (using glActiveTexture)
inside the loop? Couldn't it be done outside the main draw loop?
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);

What is the function of glActiveTexture and GL_TEXTURE0 in OpenGL?

I'm finding a way to understand why glActiveTexture is needed. I have the code below:
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
If I imagine that the GL_TEXTURE_2D is a picture's frame hanging on the wall and textureId is the real picture, the glBindTexture is the only command for assigning a real picture to the frame, so, what are GL_TEXTURE0 and glActiveTexture?
Will my code below work fine?
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glActiveTexture(GL_TEXTURE1);
glTexImage2D(GL_TEXTURE_2D, .....)
glTexParameteri(GL_TEXTURE_2D, ...)
I'm currently working with OpenGL2.1.
If I imagine that the GL_TEXTURE_2D is a picture's frame hangging on the wall and textureId is the real picture,
Actually a very good analogy :)
so, what GL_TEXTURE0 and glActiveTexture are?
Think about a wall with multiple picture frames, the first frame being labeled GL_TEXTURE0, the second GL_TEXTURE1 and so on.
OpenGL introduced multitexturing at some point (which is basically using more than one texture on one geometry pass); in order to keep older code working, they couldn't just add additional parameter to all the functions. That's why you have to explicitly specify which texture unit you are addressing.

OpenGL multi-texturing error: can't access every texture in samplers

I'm trying to send two textures to a fragment shader but it doesn't seem to work. Only one texture can be accessed from the sampler in the shader.
Here is what I'm doing in my code
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fbo_texture);
glUniform1i(glGetUniformLocation(p,"fbo_texture"), 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, tex_back);
glUniform1i(glGetUniformLocation(p,"back"), 1);
render stuff
However if I add glActiveTexture(GL_TEXTURE0); after the last uniform, it works. Also if I specify GL_TEXTURE1 then GL_TEXTURE0, in that order, it's also good. What am I missing?
Edit *
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, fbo_texture);
glUniform1i(glGetUniformLocation(p,"fbo_texture"), 2);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, tex_back);
glUniform1i(glGetUniformLocation(p,"back"), 3);
Works...
A problem with GL_TEXTURE0 apparntly
I see that you called one of your textures fbo_texture. I assume, that this is a render-to-texture color attachment of a FBO then.
In that case make sure that you bind the texture only after you unbound the FBO for rendering, and vice versa.