glTexImage2D: 读取位置XXX时发生访问冲突。

发布时间 2023-07-18 13:52:43作者: overxus

在跟着Learn OpenGL教程学习纹理部分时,你或许会加载一张自己喜欢的图片作为纹理,但加载某些图片时会报以下错误:

读取位置XXX时发生访问冲突。

这个错误通常出现在以下部分:

unsigned char* data = stbi_load("demo.jpg", &image_width, &image_height, &image_channel, 0);
if (data) {
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image_width, image_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);
}

IDE会在glGenerateMipmap(GL_TEXTURE_2D)处提示错误,这个错误一般是由glTexImage2D引发的。首先检查下是不是通道数搞错了:比如说加载的是jpg图片但在glTexImage2D中使用的是GL_RGBA.如果没有搞错的话,那么报错的原因很有可能是这个:

加载的图片为jpg, 但它的宽度不是4的倍数!!!关于这个错误的描述可以参考这里,跟GPU的数据对齐有关。(我还以为是std_image库的问题,de了一个小时的bug,饭都没吃?)

比较简单的解决方法是:把图片的宽度缩放到4的倍数;或者把jpg图片转为png, 加载png图片作为纹理(因为png图片的每个像素具有R,G,B,A这4个通道,无论png图片的大小如何,图片的总数据量image_width * image_height * 4一定是4的倍数). 

 

如果使用magick将jpg转为png, 直接执行以下命令:

magick convert demo.jpg demo.png

 得到的png图片还是3个通道,因为png图片也有24位深度的(参见此处)。使用如下命令:

magick convert demo.jpg png32:demo.png

就可以得到4通道的png图片了。