Reputation: 195
i have a test situation where i write to a framebuffer with the following code
varying vec4 vertex_color;
void main(void)
{
gl_FragColor = vec4(129.0,129.0,129.0,256.0)/256.0;
}
and read it back later with a glReadPixels call
GLubyte data[4] = {0};
glReadPixels( pick.x, pick.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
Up to the value 128.0 i read back exactly what i wrote, beyond that in the value range 129-255 the values are lowered by one, eg
gl_FragColor r(1.0) -> data[0]=1;
...
gl_FragColor r(128.0) -> data[0]=128;
gl_FragColor r(129.0) -> data[0]=128;
...
gl_FragColor r(255.0) -> data[0]=254;
gl_FragColor r(256.0) -> data[0]=255;
Where does that offset may come from?
Upvotes: 0
Views: 230
Reputation: 473447
If your framebuffer uses normalized, unsigned bytes for color components (ie: is an RGBA8 framebuffer), then this is exactly the behavior you should get. Why?
Because you divided by 256. And there are 257 numbers on the closed range [0, 256]. And you cannot put 257 individual values in a byte, because a byte only holds 256 values. One of them gets lost; in your case, 256.
That's why you would normally divide by 255. That will map the closed range [0, 255] (the numbers a byte covers) to the floating-point range [0, 1].
Upvotes: 2