In OpenGL, most shader uniform variables are easy, a float or a vec3 or whatever is associated with a shader program. But samplers are different, we associate a texture unit to the shader program, and associate a texture with a texture unit.
To change a texture on a shader program, there are two approaches:
- reassign the texture unit, or
- use the same texture unit with a new texture.
Codewise:
glUseProgram(theProgram);
// way 1 setup
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, texture2);
// way 1 assign before each draw
glUniform1i(uniformLocation, 1);
...draw...
glUniform1i(uniformLocation, 2);
...draw...
or
// way 2 setup
glUniform1i(uniformLocation, 1);
// way 2 assign before each draw
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE2D, texture1);
...draw...
glBindTexture(GL_TEXTURE2D, texture2);
...draw...
I profiled both, and got inconclusive results. On desktop (mac pro), "Way 1" is much slower. On laptop (mac retina), they're about the same.
Both ways work, so neither is "wrong"... so perhaps this question is loose. Best would be to profile every video card, but I cannot.
Is there a recommended approach for managing textures & texture units?
(Or, at the risk of making the question even vaguer, is there some mental model I should have for how textures, texture units, and shader programs interact which makes it obvious why Way 2 might be faster on some platforms?)