我试图了解GL_UNSIGNED_INT
值如何转换为GL_RGBA8_SNORM
并使用glTexImage2D
和glGetTexImage
往返返回。虽然具有GL_RGBA8
内部格式的类似代码按预期工作,但我似乎无法理解GL_RGBA8_SNORM
的错误。
这是测试代码:
#include <stdio.h>
#include <GL/gl.h>
#include <GL/glut.h>
void display()
{
GLuint texture;
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D,texture);
const GLuint value = 0x60000000;
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8_SNORM,1,1,0,GL_RED,GL_UNSIGNED_INT,&value);
GLuint error=glGetError();
if(error!=GL_NO_ERROR)
{
printf("TexImage2D failed: %u\n",error);
exit(1);
}
GLuint returned;
glGetTexImage(GL_TEXTURE_2D,0,GL_RED,GL_UNSIGNED_INT,&returned);
error=glGetError();
if(error!=GL_NO_ERROR)
{
printf("GetTexImage failed: %u\n",error);
exit(1);
}
printf("value: %x, returned: %x\n",value,returned);
exit(0);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutCreateWindow("Texture formats probe");
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
我得到了这个输出:
值:60000000,返回:61616180
我预计转换过程如下。 0x60000000的初始值除以UINT32_MAX
,得到GLfloat
值0.375。然后将此结果乘以127得到47.625,可以舍入为47或48(取决于硬件)。现在,其中一个舍入值存储在纹理中。在回读时,该值除以127得到0.370078743或0.377952754(取决于存储到纹理时我们如何舍入)。然后将此值乘以UINT32_MAX
,在回合后,我们最终可能会得到四个结果:
这四个中的任何一个都不等于我从glGetTexImage
得到的值。所以转换过程必须有所不同。
我使用专有驱动程序版本375.39在Linux 3.12.18 x86_64上使用GeForce GTX 750 Ti进行测试。
那么转换的实际过程是什么?