I'm in GLSL texture hell: I load 4 different textures of the same size in uniform sampler2D variables in my fragment shader and try to access them with different texture coordinates:
uniform sampler2D image0, image1, image2, image3;
varying highp vec2 texCoord;
void main()
{
highp vec2 tc = vec2(texCoord.x, mod(1.0-texCoord.y, 0.2) + 0.2);
lowp vec4 color0 = texture2D(image0, tc);
lowp vec4 color1 = texture2D(image1, tc);
lowp vec4 color2 = texture2D(image2, tc);
lowp vec4 color3 = texture2D(image3, tc);
if (texCoord.y < 0.2) { gl_FragColor = color0; }
else if (texCoord.y < 0.4) { gl_FragColor = color1; }
else if (texCoord.y < 0.6) { gl_FragColor = color2; }
else if (texCoord.y < 0.8) { gl_FragColor = color3; }
else { gl_FragColor = vec4(0.0); }
}
The texCoord comes from the vertex shader of course:
uniform lowp float ratio;
attribute highp vec4 vertex;
varying highp vec2 texCoord;
void main()
{
gl_Position = vertex;
texCoord.x = ((vertex.x * 0.5) + 0.5) * ratio;
texCoord.y = (vertex.y * 0.5) + 0.5;
}
I get 5 separate slices, from image0, image2 (!! not image1), image3, image3 (again!), and black (this would hold a merge of the various texture, not important in this context, my problem being getting the right textures first). I checked the image loading code multiple times, I do load 4 different images:
- (void)linkTexture:(GLenum)tex image:(Image *)image varName:(const char *)varName
{
GLint texLocation;
texLocation = glGetUniformLocation(program, varName);
glUniform1i(texLocation, tex-GL_TEXTURE0);
glActiveTexture(tex);
glBindTexture(GL_TEXTURE_2D, image->texID);
}
and further down:
loadTexture("new_york_0.jpg", &image0, &renderer);
[self linkTexture:GL_TEXTURE0 image:&image0 varName:"image0"];
loadTexture("new_york_1.jpg", &image1, &renderer);
[self linkTexture:GL_TEXTURE1 image:&image1 varName:"image1"];
loadTexture("new_york_2.jpg", &image2, &renderer);
[self linkTexture:GL_TEXTURE2 image:&image2 varName:"image2"];
loadTexture("new_york_3.jpg", &image3, &renderer);
[self linkTexture:GL_TEXTURE3 image:&image3 varName:"image3"];
There must be something very wrong in the way I expect the GPU to lookup textures but I have no clue what it is.
Can someone shine a light?