纹理显示不正确?

时间:2018-09-22 19:28:21

标签: opengl

我正在尝试使用OpenGL显示JPG纹理,但是我有一些问题。这是我的代码的重要部分:

unsigned char* data = stbi_load("resources/triangle.jpg", &width, &height, &nrChannels, 0);
if (data)
{
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);
}

我尝试加载的JPG文件可以下载here。它适用于某些JPG文件,但不适用于此JPG文件,因此显然是有关格式的内容-但为什么?为什么?

这是显示纹理的方式

1 个答案:

答案 0 :(得分:1)

  

它适用于某些JPG文件,但不适用于该JPG文件,因此显然是有关格式的内容-但是为什么?为什么?

默认情况下,OpenGL假定图像每行的大小对齐4个字节。

这是因为GL_UNPACK_ALIGNMENT参数默认为4。

由于图像具有3个颜色通道(由于其JPG),并且包装紧密,因此图像行的大小可能未对齐4个字节。请注意,如果图像的宽度加4,则它将对齐4个字节,因为4 * 3 = 12个字节。但是,如果宽度为5,则不会与4对齐,因为5 * 3 = 15个字节。

这导致图像的行似乎放错了位置。将GL_UNPACK_ALIGNMENT设置为1,可以解决您的问题:

glPixelStore( GL_UNPACK_ALIGNMENT, 1 );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);

另外,由于GL_RGB中的glTexImage2D格式参数,您假设图像具有3个颜色通道。在这种情况下,这是有效的,因为JPG文件格式。 stbi_load返回图像缓冲区(nrChannels)中包含的颜色通道数。
通过使用GL_RGBGL_RGBA作为format参数来尊重它,就像这样:

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
    nrChannels == 3 ? GL_RGB : GL_RGBA,
    GL_UNSIGNED_BYTE, data);