Problem with 1dTexture as lookup table

Hello there,

i would like to draw the grayscale color 255 as red and i would like to do this with a FragementShader, but it dosen’t work.

I define a lookup texture like this:

	glGenTextures(1, &m_tex[0]);
	glBindTexture(GL_TEXTURE_1D, m_tex[0]);
	// setup texture
	glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);


	float colors[256][3];
	for (int i = 0; i < 256; i++)
	{
	if (i == 255)
		{
			colors[i][0] = i / 255.;
			colors[i][1] = 0.;
			colors[i][2] = 0.;
		}
		else
		{

			colors[i][0] = i / 255.;
			colors[i][1] = i / 255.;
			colors[i][2] = i / 255.;

		}
	}

	glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 256, 0 , GL_RGB, GL_FLOAT, colors);

After this i create my 2D image grayscale texture:

		// texture erstellen
		glGenTextures(1, &m_tex[1]);
		glBindTexture(GL_TEXTURE_2D, m_tex[1]);

		// setup texture
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

		// copy image pixel to texture
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_gray.width(), m_gray.height(), 0,
				GL_LUMINANCE, GL_UNSIGNED_BYTE, m_gray.bits());

Then i define the shaders Fragment and Vertex:

const char *vsrc =
	         "void main(void)
"
	         "{
"
	         "    gl_Position = ftransform();
"
	         "gl_TexCoord[0] = gl_MultiTexCoord0;
"
	         "}
";


const char *fsrc =
		"uniform sampler2D sample;
"
		"uniform sampler1D lookup;
"
		"void main(void)
"
		"{
"
		"	gl_FragColor = texture1D(lookup, texture2D(sample,gl_TexCoord[0].st).r);
"
		"}
";


Now i use the Qt QGLWidget to draw the texture. I compile now the
code and bind it to the card.

m_program = new QGLShaderProgram(this);
	m_program->addShader(vshader);
	m_program->addShader(fshader);
	m_program->link();
	m_program->setUniformValue("lookup", m_tex[0]);
	m_program->setUniformValue("sample", m_tex[1]);
	m_program->bind();

And this is my draw function:

paintGL()
{

	glEnable(GL_TEXTURE_2D);
	glBegin(GL_QUADS);
		// clockwise
		glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, 1.0f); 	// oben links
		glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, 1.0f); 	// oben rechts
		glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, -1.0f);	// unten rechts
		glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, -1.0f);	// unten links
	glEnd();
	glDisable(GL_TEXTURE_2D);

}

Can anyone help me what did i wrong? I see only the 1D lookup texture in my Widget and the color which should be red is black.

Best regards,

Treehouse

How about a picture? It’s not obvious from your description what you are seeing. Just that you “aren’t” seeing the all white color show up red.

Could be you’re using CLAMP rather than CLAMP_TO_EDGE, so you’re getting the texture border mixed in. To fix:


glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S    , GL_CLAMP_TO_EDGE ) ;
glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T    , GL_CLAMP_TO_EDGE ) ;

And of course, for a 1D texture, omit the 2nd line and change 2D to 1D.

Hello Dark Photon,

if i don’t bind the shader i see my grayscale image, normal with no problems.

When i change the draw function in this way also with unbind shader:

glEnable(GL_TEXTURE_1D);
	glBegin(GL_QUADS);
		// clockwise
		glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, 1.0f); 	// oben links
		glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, 1.0f); 	// oben rechts
		glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, -1.0f);	// unten rechts
		glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, -1.0f);	// unten links
	glEnd();
	glDisable(GL_TEXTURE_1D);

Then i see my 1D Texture with the grayscales from black to white and the last line of pixels are red.

And when bind the shader and i use my 2D draw function. I don’t see my grayscale image instead i see the 1D texture from black to white but the last line that must be red is black.

Best regards,

Treehouse

You need to pass the active texture where the texture is bound and not the tex id that your texture stores when u pass the uniform to the shader.
Change this line


m_program->setUniformValue("lookup", m_tex[0]);
m_program->setUniformValue("sample", m_tex[1]);

to this


m_program->setUniformValue("lookup", 0);
m_program->setUniformValue("sample", 1);

And then when passing the texture make sure that the texture is bound to the appropriate active texture target.


glGenTextures(1, &m_tex[0]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_1D, m_tex[0]);
// setup texture
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
...

and the same steps for the other texture


// texture erstellen
glGenTextures(1, &m_tex[1]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, m_tex[1]);

// setup texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

...

See if this helps.

Hello mobeen,

you made my day. It works thank you very much for this advice.

Best regards,

Treehouse

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