如何使用glReadPixels读取浮点数据

时间:2013-06-01 15:54:31

标签: c++ opengl graphics glsl shader

我一直在尝试使用glReadPixels读取浮动数据几天。

我的cpp代码:

//expanded to whole screen quad via vertex shader
glDrawArrays( GL_TRIANGLES, 0, 3 );

int size = width * height;
GLfloat* pixels = new GLfloat[ size ];
glReadPixels( 0, 0, width, height, GL_RED,  GL_FLOAT, pixels );

pixelVector.resize( size );
for ( int i = 0; i < size; i++ ) {
    pixelVector[i] =  (float) pixels[i];
}

和我的着色器代码:

out float data;

void main()
{  
  data = 0.02;
}

奇怪的是我输出0.0196078。但是当数据为0.2时,一切都很好。如果数据为0.002则全部为0。什么可能导致这种情况?

1 个答案:

答案 0 :(得分:3)

这是由于您将浮点值存储在规范化的整数中,然后将其读回并将其转换为浮点值。

除非你使用的是framebuffer object,否则你当前的帧缓冲就是你从OpenGL上下文得到的几率非常好。可能使用GL_RGBA8作为image format。这是每通道8位,无符号和标准化,存储为整数。因此,您写入的浮点值将被限制在[0,1]范围内,然后通过乘以255转换为整数并进行舍入,然后存储。

当你把它作为一个浮点数读回来时,转换是反过来的:整数值被转换成一个浮点值,除以255,然后返回。

0.02 * 255 = 5.1 ~= 5

5 / 255 = 0.0196

这就是你得到的东西。

如果要从片段着色器中写入浮点值,并且实际上从读回的内容中获得超过2-3位的精度,则需要渲染到包含具有合理图像的图像的FBO格式。例如浮点图像(GL_R16FGL_R32F,因为您只编写一个数据通道。)