glTexImage2D 崩溃程序

glTexImage2D crashing program

这是我的代码:

int h, w, c;
unsigned char* img = stbi_load("bricks.jpg", &w, &h, &c, 0);
if (img == NULL) {
    printf("Error in loading the image\n");
}
printf("Image loaded with width of %d, height of %d, and %d channels", w, h, c);

GLuint txtr = 0;
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &txtr);
glBindTexture(GL_TEXTURE_2D, txtr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, img);

出于某种原因,当我取消评论 glTexImage2D 时,我的 window 不再打开。 wh 都是由 stbi_load 计算的,它是 stb_image.h 库的一部分。我的错误在哪里?

好吧,问题显然出在 GL_RGBA 上。我改成GL_RGB,程序不再崩溃;不过,我确实想知道为什么它一开始就崩溃了。

我想你的问题的根源是 stbi_load 方法加载的像素图中的通道数与你作为第 7 个参数传递给 [=] 的原始图像格式的通道数不匹配11=] 方法。 基本上,glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, WIDTH, HEIGHT, 0, SOURCE_FORMAT, SOURCE_TYPE, SOURCE_PIXMAP_DATA) 导致 OpenGL 创建一个 2D 纹理,其具有 INTERNAL_FORMAT 的内部像素表示,从源像素图 SOURCE_PIXMAP_DATASOURCE_FORMATSOURCE_TYPE.

中编码的像素序列组成

我认为 stbi_load 从文件中读取一个 3 通道、每像素 24 字节的图像(GL_RGBGL_BYTE),但是您告诉 OpenGL 将源像素图视为 4通道,每像素 32 字节 (GL_RGBA, GL_BYTE) 图像。这是不正确的。

您应该在指定源像素图格式之前检查 c 变量,或者请求 stbi_load 通过将 4 分配给它的第 4 个参数来加载 4 色通道图像(该死的,这里有很多 4)。

jpg 图像由 3 个颜色通道 (GL_RGB) 和 stbi_load returns 紧凑的图像组成。图片缓冲区(img)的字节数为w * h * 3.

默认情况下,OpenGL 假定图像的每一行的开头对齐 4 个字节。这是因为默认情况下 GL_UNPACK_ALIGNMENT 参数为 4。由于图像具有 3 个颜色通道,并且排列紧密,行的开头可能未对齐。
因此图像缓冲区的大小假定为 aligne(w*3, 4) * h

导致崩溃,因为glTexImage2D。越界访问缓冲区。

GL_UNPACK_ALIGNMENT参数改为1,在指定二维纹理图像之前(glTexImage2D):

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, img);

注意,glPixelStorei 设置了一个全局状态,该状态会一直保持到再次更改。