我正在尝试使用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文件,因此显然是有关格式的内容-但为什么?为什么?
答案 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_RGB
或GL_RGBA
作为format参数来尊重它,就像这样:
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
nrChannels == 3 ? GL_RGB : GL_RGBA,
GL_UNSIGNED_BYTE, data);