PDA

View Full Version : glReadPixels 0.0 ... 1.0



m.gnu.
09-10-2008, 01:04 AM
Does glReadPixels only return values between 0.0 and 1.0 even if I have a floating point buffer capable of storing higher values?

Y-tension
09-10-2008, 06:43 AM
http://www.opengl.org/sdk/docs/man/
glReadPixels returns no value...
What did you have in mind?

m.gnu.
09-10-2008, 06:56 AM
The seventh parameter, "GLvoid * data" returns pixel data from the frame buffer.

V-man
09-10-2008, 07:31 AM
If you created a floating point render target, then you can write any value you want and glReadPixels will return values with the full range, not just 0.0 to 1.0.
You are probably doing something wrong.

m.gnu.
09-10-2008, 09:31 AM
Yeah, I figured so too.. Here's a snippet:


Point2D minMax(1.0, 0.0);
GLuint imageBuffers[2];
glGenBuffers(2, imageBuffers);

glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, imageBuffers[0]);
glBufferData(GL_PIXEL_PACK_BUFFER_ARB, texSize_.x * texSize_.y / 2 * sizeof(float), NULL, GL_STREAM_READ);

glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, imageBuffers[1]);
glBufferData(GL_PIXEL_PACK_BUFFER_ARB, texSize_.x * texSize_.y / 2 * sizeof(float), NULL, GL_STREAM_READ);

// Draw stuff...
render();

int bf;
glGetIntegerv(GL_READ_BUFFER, &bf);
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);

glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, imageBuffers[0]);
glReadPixels(0, 0, texSize_.x, texSize_.y/2, GL_LUMINANCE, GL_FLOAT, 0);

glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, imageBuffers[1]);
glReadPixels(0, texSize_.y/2, texSize_.x, texSize_.y/2, GL_LUMINANCE, GL_FLOAT, 0);

GLfloat *pixels1, *pixels2;

glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, imageBuffers[0]);
pixels1 = (GLfloat*)glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
findMinMax_(pixels1, minMax);

glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, imageBuffers[1]);
pixels2 = (GLfloat*)glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
findMinMax_(pixels2, minMax);

glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, imageBuffers[0]);
glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, imageBuffers[1]);
glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
glReadBuffer(bf);
glDeleteBuffers(2, imageBuffers);


void MyClass::findMinMax_( GLfloat* pixels, Point2D & minMax )
{
float minVal = (float)minMax.x;
float maxVal = (float)minMax.y;
if( pixels != NULL )
{
for(int n = 0; n < texSize_.x * texSize_.y / 2; ++n)
{
minVal = min(minVal, pixels[n]);
maxVal = max(maxVal, pixels[n]);
}
}

minMax.x = minVal;
minMax.y = maxVal;
}

I'm rendering to a GL_LUMINANCE texture with the internal format GL_LUMINANCE32F_ARB. As strange as it may seem, there doesn't seem to be a problem getting negative values... but nothing higher than 1.0

V-man
09-10-2008, 10:55 AM
The above stuff is just for reading back using a PBO which is not relevant to your problem. You need to create a render target and make sure it succeeds. If you want, upload a small program and I can test.

Y-tension
09-10-2008, 11:07 AM
Oh...gross misunderstanding on my part...sorry!

Y-tension
09-10-2008, 11:16 AM
Did you disable color clamping?

m.gnu.
09-10-2008, 11:34 PM
Found the error myself. Reading back GL_LUMINANCE values is wrong (in my case), the definition of luminance is the sum of the red, green and blue component and being at most 1.0. I noticed that doing gl_FragColor.r = 0.2 in my shader i got 0.6 back from glReadPixels (i.e. the sum of the three components, the blue and green is copied from the red when using GL_LUMINANCE). So, changing the two calls
glReadPixels(0, 0, texSize.x, texSize.y/2, GL_LUMINANCE, GL_FLOAT, 0); into
glReadPixels(0, 0, texSize.x, texSize.y/2, GL_RED, GL_FLOAT, 0); was what I needed.

Thanks everyone anyway!