I just don't manage to use texelFetch :-(


I am getting nuts trying to get a simple fragment shader to work. I am trying to use the texelFetch function, but no luck.

I am creating a 1D texture, min.filter = linear, mag.filter = linear.
I then call glTexImage1D:

glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA8UI, sizeInPixels, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, <data>);

I am making sure my data is populated with 0xFF byte values everywhere, eg.:

char *data = […];
data[0] = 255;
data[1] = 255;
data[2] = 255;
data[3] = 255;

Now my fragment shader.
The uniform is correctly bound as a usampler2D in my code.

#version 150 compatibility
#extension GL_EXT_gpu_shader4 : enable

uniform usampler1D tex;

void main(void)
uvec4 val = texelFetch(tex, 0, 0);
if (val.r == 255u)
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // red
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); // green

The result is always green!


Not sure, but here are somethings to try to find the problem via a process of elimination:

1)Set your filters to NEAREST
2)Change the 3rd and 6th parameter of TexImage to GL_R8UI and GL_RED_INTEGER, respectively. Adjust the size parameter as each pixel is now a byte.

If that doesn’t work, you are not binding the uniform correctly. Also, if you use GLSL version 130 or greater, you don’t need to enable GL_EXT_gpu_shader4.

Just to make sure that the texture is loaded, could u just output the fetched value to the fragcolor like this

uvec4 val = texelFetch(tex, 0, 0);

For all 255, you should get a white color. If black, your texture is not loaded.

If your texture is loaded then you can check to make sure that the min filter is not mipmapped. Either give nearest or linear and see if this helps.

If your texture is not loaded then make sure that you are binding the texture to the same texture unit that you pass to your shader. So assuming that you are passing 0 to your shader uniform as follows,

//At init, you get the tex location and then set the texture uniform
   GLuint texLoc = glGetUniformLocation(program,"tex");

Then bind the texture to the texture unit 0 (texture unit 0 is active by default so u dont need glActiveTexture(GL_TEXTURE0) call).

//before rendering your geometry bind the texture
glBindTexture(GL_TEXTURE_1D, texID);

See if this sorts out your problem.


Hi DarkGKnight, mobeen,

My problem was that my 1D texture was too large. I was creating a texture that was over 16384 pixels in size, which my driver (ATI Radeon HD) could not handle. The texture size was indeed 1, and the texelFetch call was always failing.
I was quite surprised to see the 2D limit is 16384x16384, and the 1D limit is “just” 16384 pixels, as well.
Your replies helped me find out my code was pretty much correct, and that my problem was something somehow unexpected.