My problem is getting more than one texture accessible in a GLSL shader. Here's what I'm doing:
Shader:
uniform sampler2D sampler0;
uniform sampler2D sampler1;
uniform float blend;
void main( void )
{
vec2 coords = gl_TexCoord[0];
vec4 col = texture2D(sampler0, coords);
vec4 col2 = texture2D(sampler1, coords);
if (blend > 0.5){
gl_FragColor = col;
} else {
gl_FragColor = col2;
}
};
So, I simply choose between the two color values based on a uniform variable. Simple enough (this is a test), but instead of the expected behavior, I get all black when blend <= 0.5.
OpenGL code:
m_sampler0location = m_shader.FindUniform("sampler0");
m_sampler1location = m_shader.FindUniform("sampler1");
m_blendlocation = m_shader.FindUniform("blend");
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
m_extensions.glUniform1iARB(m_sampler0location, 0);
glBindTexture(GL_TEXTURE_2D, Texture0.Handle);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
m_extensions.glUniform1iARB(m_sampler1location, 1);
glBindTexture(GL_TEXTURE_2D, Texture1.Handle);
glBegin(GL_QUADS);
//lower left
glTexCoord2f(0, 0);
glVertex2f(-1.0, -1.0);
//upper left
glTexCoord2f(0, maxCoords0.t);
glVertex2f(-1.0, 1.0);
//upper right
glTexCoord2f(maxCoords0.s, maxCoords0.t);
glVertex2f(1.0, 1.0);
//lower right
glTexCoord2f(maxCoords0.s, 0);
glVertex2f(1.0, -1.0);
glEnd()
The shader is compiled and bound before all this. All the sanity checks in that process indicate that it goes ok.
As I said, the value of Fixed according to Bahbar's reply.col
in the shader program reflects fragments from a texture; the value of col2
is black. The texture that is displayed is the last active texture - if I change the last glBindTexture
to bind Texture0.Handle
, the texture changes.
As it is, the scene renders all black, even if I add something like gl_FragColor.r = blend;
as the last line of the shader. But, if I comment out the call glActiveTexture(GL_TEXTURE1);
, the shader works again, and the same texture appears in both sampler0 and sampler1.
What's going on? The line in question, glActiveTexture(GL_TEXTURE1);
, seems to work just fine, as evidenced by a subsequent glGetIntegerv(GL_ACTIVE_TEXTURE, &anint)
. Why does it break everything so horribly? I've already tried upgrading my display drivers.
When compiling your shader to test, I found two errors:
coords
should be assigned the st
portion of the 4-component gl_TexCoord
, e.g.
vec2 coords = gl_TexCoord[0].st;
The shader should not end with a semicolon.
Are you checking anywhere in your main program that shader compiles correctly? You may want to look at GL_COMPILE_STATUS
via glGetShader
and glGetShaderInfoLog
.
Just to help other people who might be interested in using multiple textures and will feel hopeless after days searching for an answer. I found that you need to call
glUseProgram(program);
GLuint t1Location = glGetUniformLocation(program, "tex1");
GLuint t2Location = glGetUniformLocation(program, "tex2");
glUniform1i(t1Location, 0);
glUniform1i(t2Location, 1);
In that order for it to work (glUseProgram is the last instruction for 99% of the sample code I've found online). Now it may be only the case for me and not affect anyone else on Earth, but just in case I thought I'd share.
Quite late reply, but for anybody encountering this - I encountered same problem and after short fiddling, I realized that calling glActiveTexture(GL_TEXTURE0)
fixes the issue.
It seems something down the line gets confused if active texture unit is not 'reset' to zero.
This could be system-dependent behavior; I'm running 64bit Archlinux with Mesa 8.0.4.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With