Texture sampling by pixel index

Hi,
I’m trying to write what I think should be a very simple shader that does the following:

I have an image file with the dimensions: w=256 h=1

I’d like to write a shader that allows the calling program to specify an index between 0 and 255 and the shader looks up the pixel at that index within the image file and returns its color through the frag shader.

I’ve been looking at texelFetch and a few other things, but can’t figure out how to make them work for this purpose. Can anyone help me out? Thanks.

What GLSL version you use?
The texelFetch command is what are you looking for. Simply use it in the following way (GLSL 1.40+):

uniform int texelIndex;
uniform sampler1D textureImage;

out vec4 fragColor;

void main(void) {
fragColor = fetchTexel(textureImage, texelIndex, 0);
}

Does this help?

Thanks. I’m on a mac, which seems to be GLSL 1.2?
Is there a way around this?

Quite unfortunate. This way you have to do it in the old way. This means you should set filtering to GL_NEAREST with no mipmaps, use the following shader:

uniform float texelNormIndex;
uniform sampler1D textureImage;

out vec4 fragColor;

void main(void) {
fragColor = texture1D(textureImage, texelNormIndex);
}

And be sure to calculate the uniform value texelNormIndex in your application as follows:

texelNormIndex = (texelIndex + 0.5f) / textureSize;

Here textureSize is 256. This is needed to get the normalized texture coordinates (i.e. between [0,1]).

Alternatively, maybe you can use texture rectangles. In that case no need for normalization but the filtering configuration should be GL_NEAREST.

texelFetch is exposed on the Mac via EXT_gpu_shader4. You need to enable that extension in your shader to use it.

The other way will work across more hardware, though.

Hey,
Thanks, that’s great. I’ve got it working in OpenGL Shader Builder. But I don’t seem to have the filtering part setup right in my program. Are these what I want:
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

Thanks again

That’s it You have the filtering set correctly for nearest.

Hmm. Something still isn’t working in my program.

In the setup function I have:

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_1D, myTexture.getTextureData().textureID);

glEnable(GL_TEXTURE_1D);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glActiveTexture(GL_TEXTURE0);

And in the draw loop I have:

mixShader.setUniformVariable1i(“textureImage”, 1);
mixShader.setUniformVariable1f(“texelNormIndex”, 0.4);

glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(0, 0);
glTexCoord2f(0, 0.5);
glVertex2f(0, mHeight);
glTexCoord2f(0.5, 0.5);
glVertex2f(mWidth, mHeight);
glTexCoord2f(0.5, 0);
glVertex2f(mWidth, 0);
glEnd();

Does anything stand out as wrong here?
Thanks.

Show us the call to glTexImage1D that actually defines the data.

And clarify “isn’t working”.

Hey,
Thanks everyone. I got it all working

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.