这是我的代码:
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
时,我的窗口不再打开。 w
和h
都是由stbi_load
计算的,它是stb_image.h
库的一部分。我的错误在哪里?
最佳答案
jpg 图像由 3 个颜色 channel (GL_RGB
) 组成,stbi_load
返回一个紧凑的图像。图像缓冲区(img
)的字节数是w * h * 3
。
默认情况下,OpenGL 假设图像的每一行的开始对齐 4 个字节。这是因为 GL_UNPACK_ALIGNMENT
参数默认为 4。由于图像有 3 个颜色 channel ,并且排列紧密,行的开头可能未对齐。
因此图像缓冲区的大小被假定为 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
设置了一个全局状态,该状态会一直保持到再次更改为止。
关于c++ - glTexImage2D 崩溃程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58925604/