在glTexImage2D-glGetTexImage往返中,通过RGBA8_SNORM对uint的转换是什么?

时间:2018-05-05 22:54:41

标签: c opengl textures

我试图了解GL_UNSIGNED_INT值如何转换为GL_RGBA8_SNORM并使用glTexImage2DglGetTexImage往返返回。虽然具有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,在回合后,我们最终可能会得到四个结果:

  • 0x5ebd7af5,
  • 0x5ebd7af6,
  • 0x60c18306,
  • 0x60c18305。

这四个中的任何一个都不等于我从glGetTexImage得到的值。所以转换过程必须有所不同。

我使用专有驱动程序版本375.39在Linux 3.12.18 x86_64上使用GeForce GTX 750 Ti进行测试。

那么转换的实际过程是什么?

0 个答案:

没有答案