I need to use two textures in my shader, one in the vertex shader, another in the fragment shader. In both cases they are referenced in the shaders like uniform sampler2D tex1;
or uniform sampler2D tex2;
However I'm not really sure on how to use the related GL calls properly.
Initialization
First of all, how do I create the two textures? Do I need to use multiple texture units like so
GLuint texIdx[2] = {0, 1};
GLuint texName[2];
GLint texUniformID[2];
// Initialize first texture
glActiveTexture (GL_TEXTURE0 + texIdx[0]);
glGenTextures (1, &texName[0]);
glBindTexture (GL_TEXTURE_2D, texName[0]);
glTexImage2D (GL_TEXTURE_2D, 0, GL_R32F, xDim0, yDim0, 0, GL_RED, GL_FLOAT, someTextureData);
// Initialize second texture
glActiveTexture (GL_TEXTURE0 + texIdx[1]);
glGenTextures (1, &texName[1]);
glBindTexture (GL_TEXTURE_2D, texName[1]);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, xDim1, yDim1, 0, GL_RGB, GL_FLOAT, someOther1TextureData);
// Set the uniforms to refer to the textures
texUniformID[0] = glGetUniformLocation (myShaderProgram, "tex1");
texUniformID[1] = glGetUniformLocation (myShaderProgram, "tex2");
glUniform1i (texUniformID[0], texIdx[0]);
glUniform1i (texUniformID[1], texIdx[1]);
Or can I use a single texture unit, as glGenTextures
allows me to create multiple textures, somewhat like that:
GLuint texName[2];
GLint texUniformID[2];
// Activate some texture unit
glActiveTexture (GL_TEXTURE0);
// Generate two textures
glGenTextures (2, texName);
// Initialize first texture
glBindTexture (GL_TEXTURE_2D, texName[0]);
glTexImage2D (GL_TEXTURE_2D, 0, GL_R32F, xDim0, yDim0, 0, GL_RED, GL_FLOAT, someTextureData);
// Initialize second texture
glBindTexture (GL_TEXTURE_2D, texName[1]);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, xDim1, yDim1, 0, GL_RGB, GL_FLOAT, someOther1TextureData);
// Set the uniforms to refer to the textures
texUniformID[0] = glGetUniformLocation (myShaderProgram, "tex1");
texUniformID[1] = glGetUniformLocation (myShaderProgram, "tex2");
glUniform1i (texUniformID[0], /* what parameter here? */);
glUniform1i (texUniformID[1], /* what parameter here? */);
So to summarize, I don't understand what's the point on having multiple texture units on the one hand and the ability to create multiple textures with a call to glGenTextures
on the other hand and what is the right way to go if I need multiple textures in a shader program.
Usage during rendering
As a follow up question, If I have initialized my multiple textures with the correct way, what is the right order of calls to activate both textures to become active during a call to glDrawElements
and what is the right order of calls to successfully update a texture at runtime glTexSubImage2D
?
Follow up question
Now one step further, if I use multiple different shader programs in a render call and all of them use textures, how should that be handled? Should each texture for each shader program use a unique texture unit?