Reputation: 3036
I try to access 2 textures in 1 fragment shader.
For this I have 2 textures that I set up with following code:
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vbuff);
glTexCoordPointer(2, GL_FLOAT, 0, tbuff);
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, texture0);
glEnable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, texture1);
glEnable(GL_TEXTURE_2D);
And I try to combine them with following fragment shader:
uniform sampler2D tex0;
uniform sampler2D tex1;
void main()
{
vec4 texval1 = texture2D(tex0, TextureCoordOut);
vec4 texval2 = texture2D(tex1, TextureCoordOut);
gl_FragColor = 0.5*(texval1 + texval2)
}
Somehow this doesn't work and it only displays the second texture.
PS: I am developing the shaders on Windows7 but want to use the C++ code and the shaders with the Android NDK on an Android Device.
EDIT: I got it working and I post the code here, so that others might benefit from it:
vertex shader
varying vec2 TextureCoordOut;
void main()
{
gl_Position = ftransform();
TextureCoordOut = vec2(gl_MultiTexCoord0);
}
fragment shader
varying mediump vec2 TextureCoordOut;
uniform sampler2D tex0;
uniform sampler2D tex1;
void main()
{
gl_FragColor = texture2D(tex0, TextureCoordOut) * texture2D(tex1, TextureCoordOut);
}
render
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vbuff); //2 dimensional vertex buffer
glTexCoordPointer(2, GL_FLOAT, 0, tbuff); // 2 dimensional textures
glColor4f(1, 1, 1, 1);
glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, mapid1);
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, mapid2);
glUseProgram(shader);
glUniform1i(glGetUniformLocation(gfx.prog, "tex0"), 0); //GL_TEXTURE0
glUniform1i(glGetUniformLocation(gfx.prog, "tex1"), 1); //GL_TEXTURE1
render....
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
Upvotes: 2
Views: 2463
Reputation: 45968
Just binding these textures to the respective units is not enough. You also need to tell the shaders where to take the textures for it's sampler2D
uniforms from. This is done by setting the corresponding integer uniform value to the texture unit you want to use:
//get uniform locations (either init code or render code)
int locTex0 = glGetUniformLocation(program, "tex0");
int locTex1 = glGetUniformLocation(program, "tex1");
...
//bind textures to texture units
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture0);
//bind program and specify texture units for each sampler2D uniform
glUseProgram(program);
glUniform1i(locTex0, 0); //use texture bound to GL_TEXTURE0
glUniform1i(locTex1, 1); //use texture bound to GL_TEXTURE1
...
draw
Of course this assumes that you know how to use shaders and specify uniform values.
Some additional remarks:
glEnable(GL_TEXTURE_2D)
, since the shader decides itself if it uses a texture or not.glVertexPointer
or glTexCoordPointer
), but that is a different question.Upvotes: 7