0

I am writing a bump mapping demo, so I need an image texture, and a normal texture which should be loaded into the fragment shader.


This is the texture part of my OpenGL code:

glActiveTexture(GL_TEXTURE0);
GLuint textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, brick);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GLint textureLocation = glGetUniformLocation(shader, "texture");
glUniform1i(textureLocation, 0);

glActiveTexture(GL_TEXTURE1);
GLuint normal_textureID;
glGenTextures(1, &normal_textureID);
glBindTexture(GL_TEXTURE_2D, normal_textureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, 
    brick_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GLint normalTextureLocation = glGetUniformLocation(shader, "normal_texture");
glUniform1i(normalTextureLocation, 1);

Here is the fragment shader:

uniform vec3 light;
uniform sampler2D texture;
uniform sampler2D normal_texture;

void main() {
    vec3 tex = texture2D(normal_texture, gl_TexCoord[0].st).rgb;
    gl_FragColor = vec4(tex, 1.0);
}

I am sure that the brick array contains the image texture, and the brick_texture array contains the normal texture; but it seems normal_texture and texture are both the image texture, not the normal texture. What am I doing wrong, in regards to multi-texture?

Yuheng Zou
  • 173
  • 1
  • 9
  • look at this for comparison [Normal mapping gone horribly wrong](http://stackoverflow.com/a/28541305/2521214) btw I do not see any `glEnable(GL_TEXTURE_2D);` for any of the units ... Also did you check [glGetInfoLog](http://stackoverflow.com/a/31913542/2521214) in case your shader has some bug and did not compile/link? – Spektre May 16 '17 at 07:39
  • @Spektre: `glEnable(GL_TEXTURE_2D);` isn't a per-unit state, and isn't needed with the programmable pipeline -- it's obsolete with OpenGL 3.1+. – Yakov Galka May 16 '17 at 09:10

1 Answers1

2

Since one of your uniform samplers is unreferenced, the other gets optimized out. This causes both textureLocation and normalTextureLocation to be equal and name the one sampler that is referenced. Therefore the latest you set, which is the image texture, take precedence over the normal texture. You can verify this by referencing both samplers:

void main() {
    vec3 tex0 = texture2D(texture, gl_TexCoord[0].st).rgb;
    vec3 tex1 = texture2D(normal_texture, gl_TexCoord[0].st).rgb;
    gl_FragColor = vec4(tex0.r, tex1.gb, 1.0);
}

You should see the red channel from the diffuse and green and blue channels from the normal.

In the future use Debug Output or check for errors to catch such bugs.

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220