c++ - 使用 STBI_Image OpenGL 加载图像时在 0x69ABF340 引发异常
问题描述
我正在尝试加载 .jpg 图像作为背景,我使用 stbi_load 加载它但是当我尝试绘制纹理时出现以下错误:在 0x69ABF340 (nvoglv32.dll) 0xC0000005 处引发异常:访问冲突读取位置 0x0C933000。发生了
我尝试在加载图像时更改通道,也许图像不是 rgb 而是 rgba,但没有成功。
int width = 1280;
int height = 720;
int channels = 3;
GLuint t;
stbi_set_flip_vertically_on_load(true);
unsigned char *image = stbi_load("bg.jpg",
&width,
&height,
&channels,
STBI_rgb);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &t);
glBindTexture(GL_TEXTURE_2D, t);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glBindTexture(GL_TEXTURE_2D, 0);
该窗口应包含指定的纹理,而不是我得到一个带有异常的白色窗口。
解决方案
该参数STBI_rgb
指示加载生成具有 3 个颜色通道的纹理。这导致图像缓冲区 ( image
) 由每个像素 3 个字节组成。
但是,当您指定二维纹理图像时,glTexImage2D
指定的格式是GL_RGBA
,这意味着 4 个通道,因此每个像素 4 个字节。
这会导致数据缓冲区被读取越界。将格式参数更改为GL_RGB
, 以解决该问题。
进一步注意,默认情况下,OpenGL 假定图像每行的开头对齐 4 个字节。这是因为该GL_UNPACK_ALIGNMENT
参数默认为 4。由于图像有 3 个颜色通道,并且紧密排列,因此行的开头可能未对齐。在指定二维纹理图像 ( ) 之前,
将参数更改为 1 。GL_UNPACK_ALIGNMENT
glTexImage2D
此外,纹理不是(mipmap)完整的。GL_TEXTURE_MIN_FILTER
的初始值为GL_NEAREST_MIPMAP_LINEAR
。如果您不更改它并且不创建 mipmap,则纹理不是“完整的”并且不会“显示”。见glTexParameter
。
将缩小过滤器设置为GL_NEAREST
或GL_LINEAR
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
或通过生成 mipmapglGenerateMipmap(GL_TEXTURE_2D)
来解决问题。
例如:
glBindTexture(GL_TEXTURE_2D, t);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
推荐阅读
- android - 如何替换 apk 的清单
- kendo-ui - Kendo-ui JQuery 不会自动启动与 microsoft botframework 的对话
- excel - 根据百分比值设置甘图的颜色 (Excel)
- kotlin - Kotlin 错误消息提供了哪些信息?
- javascript - 填充不适用于带有文本覆盖的图像
- azure - Azure SQL 外部表替代品
- vb.net - 无法为 SSL/TLS 安全通道建立信任关系 - SOAP 服务
- gremlin - 如何编写一个 gremlin 查询来查找其他顶点之间的公共顶点并按重叠计数排序返回?
- firebase - FirebaseAppDelegateProxyEnabled 有什么作用?
- mysql - 具有左连接和求和的 MySQL - NULL 值与无结果