我正在尝试开发一个代码,在其中使用assimp加载3d模型,使用3d坐标和顶点法线进行处理,然后将纹理检索到CPU。
我尝试使用“ glReadPixels”来检索纹理,但是我的数据被夹在here中描述的[0 1]之间。
我使用的纹理示例:
glGenTextures(1, &pos3d);
glBindTexture(GL_TEXTURE_2D, pos3d);
glViewport(0, 0, width, height);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + gpos3dLayout, GL_TEXTURE_2D, pos3d, 0);
glBindTexture(GL_TEXTURE_2D, 0);
然后我用这个来检索:
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, pos3d);
glReadBuffer(GL_COLOR_ATTACHMENT0);
std::vector<GLfloat> positions3d(width * height * 4); // 4 because of RGBA * 1 float
glReadPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, &positions3d[0]);
正如我所说,我的值似乎限制在0到1之间。那么有没有办法禁用这种限制?
答案 0 :(得分:2)
数据被钳位,因为附加到帧缓冲区颜色平面的纹理的内部格式为GL_RGBA
(与GL_RGBA8
相同)。此格式是无符号归一化定点格式,并为每个颜色通道提供8位,其中0表示0.0,而所有8位设置(255)表示1.0。
这导致纹理的数据存储中的数据表示受到限制。 glReadPixels
从数据存储区读取数据,该数据存储区附加到frambuffer的颜色平面。
在通过glTexImage2D
指定二维纹理图像时,将纹理的内部格式更改为浮点格式(例如GL_RGBA16F
)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
从缓冲区中读取像素时,它们可能会被限制在[0.0,1.0]范围内。
这取决于glClampColor
的设置。
请参见OpenGL 4.6 API Core Profile Specification - 18.2.8 Final Conversion,第535页
读取颜色钳制是通过调用控制的
void ClampColor( enum target, enum clamp )
,目标设置为
CLAMP_READ_COLOR
。如果钳位为TRUE
,则启用读取色钳位;如果钳位为FALSE
,则禁用读取色钳位。 [...]
对于浮点RGBA颜色,如果类型为FLOAT
或HALF_FLOAT
,则在启用读取颜色钳位的情况下,每个分量都钳位到[0,1]。
注意,在OpenGL ES中,颜色在任何情况下都是固定的。
glGetTexImage
仅在桌面OpenGL中提供,不会钳制颜色。