Now, I want to apply a bump map to the teapot. My lecturer evidently doesn't brew his own tea, and so doesn't know they're supposed to be smooth. Anyway, I found a nice-looking tutorial on old-school bump mapping that includes a fragment shader that begins:
uniform sampler2D DecalTex; //The texture uniform sampler2D BumpTex; //The bump-map
What they don't mention is how to pass two textures to the shader in the first place.
//OpenGL cpp file glBindTexture(GL_TEXTURE_2D, textureHandle); //Vertex shader gl_TexCoord = gl_TextureMatrix * gl_MultiTexCoord0; //Fragment shader gl_FragColor = color * texture2D(DecalTex,gl_TexCoord.xy);
so now I
//OpenGL cpp file glBindTexture(GL_TEXTURE_2D, textureHandle); glBindTexture(GL_TEXTURE_2D, bumpHandle); //Vertex shader gl_TexCoord = gl_TextureMatrix * gl_MultiTexCoord0; gl_TexCoord = gl_TextureMatrix * gl_MultiTexCoord1; //Fragment shader gl_FragColor = color * texture2D(BumpTex,gl_TexCoord.xy); //no bump logic yet, just testing I can use texture 1 instead of texture 0
but this doesn't work. The texture disappears completely (effectively the teapot is white). I've tried GL_TEXTURE_2D_ARRAY, glActiveTexture and few other likely-seeming but fruitless options.
After sifting through the usual mixed bag of references to OpenGL and GLSL new and old, I've come to the conclusion that I probably need
glGetUniformLocation. How exactly do I use this in the OpenGL cpp file to pass the already-populated texture handles to the fragment shader?
(This is homework so please answer with minimal code fragments (if at all). Thanks!)
Failing that, does anyone have a tea cosy mesh?openglglsltexture-mappingtexture2dopengl-2.0
It is very simple, really. All you need is to bind the sampler to some texture unit with
glUniform1i. So for your code sample, assuming the two uniform samplers:
uniform sampler2D DecalTex; // The texture (we'll bind to texture unit 0) uniform sampler2D BumpTex; // The bump-map (we'll bind to texture unit 1)
In your initialization code:
// Get the uniform variables location. You've probably already done that before... decalTexLocation = glGetUniformLocation(shader_program, "DecalTex"); bumpTexLocation = glGetUniformLocation(shader_program, "BumpTex"); // Then bind the uniform samplers to texture units: glUseProgram(shader_program); glUniform1i(decalTexLocation, 0); glUniform1i(bumpTexLocation, 1);
glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0 glBindTexture(GL_TEXTURE_2D, decalTexHandle); glActiveTexture(GL_TEXTURE0 + 1); // Texture unit 1 glBindTexture(GL_TEXTURE_2D, bumpHandle); // Done! Now you render normally.
And in the shader, you will use the textures samplers just like you already do:
vec4 a = texture2D(DecalTex, tc); vec4 b = texture2D(BumpTex, tc);
Note: For techniques like bump-mapping, you only need one set of texture coordinates, since the textures are the same, only containing different data. So you should probably pass texture coordinates as a vertex attribute.
instead of using:
glUniform1i(decalTexLocation, 0); glUniform1i(bumpTexLocation, 1);
in your code, you can have:
layout(location=0) uniform sampler2D DecalTex; // The texture (we'll bind to texture unit 0) layout(location=1)uniform sampler2D BumpTex; // The bump-map (we'll bind to texture unit 1)
in your shader. That also mean you don't have to query for the location.