c++ - 使用 STBI_Image OpenGL 加载图像时在 0x69ABF340 抛出异常

标签 c++ opengl textures

我试图加载一个 .jpg 图像作为背景,我用 stbi_load 加载它但是当我尝试绘制纹理时我得到以下错误: 在 0x69ABF340 (nvoglv32.dll) 抛出异常 0xC0000005:访问冲突读取位置 0x0C933000。发生

我尝试在加载图像时更改 channel ,也许图像不是 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 个颜色 channel 的纹理。这导致图像缓冲区 (image) 由每个像素 3 个字节组成。

但是当你通过glTexImage2D指定二维纹理图像时那么指定的格式是 GL_RGBA,它建议 4 个 channel ,因此每个像素 4 个字节。
这导致数据缓冲区被越界读取。将格式参数更改为 GL_RGB,即可解决该问题。

进一步注意,默认情况下,OpenGL 假定图像的每一行的开头对齐 4 个字节。这是因为 GL_UNPACK_ALIGNMENT参数默认为 4。由于图像具有 3 个颜色 channel ,并且排列紧凑,行的开头可能未对齐。
更改 GL_UNPACK_ALIGNMENT参数为 1,在指定二维纹理图像 (glTexImage2D) 之前。

此外,纹理不(mipmap)完整。 GL_TEXTURE_MIN_FILTER 的初始值为 GL_NEAREST_MIPMAP_LINEAR。如果您不更改它并且不创建 mipmap,则纹理不“完整”并且不会“显示”。参见 glTexParameter .
将缩小过滤器设置为 GL_NEARESTGL_LINEAR

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

或通过 glGenerateMipmap(GL_TEXTURE_2D) 生成 mipmaps解决问题。

例如:

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);

关于c++ - 使用 STBI_Image OpenGL 加载图像时在 0x69ABF340 抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58249534/

相关文章:

C++ - std::thread 在执行时崩溃

java - 将 glArrayElement 与 LWJGL 结合使用

java - LWJGL:从具有多个纹理的 .png 中获取纹理

graphics - 两个网格,相同的纹理,不同的偏移量?

滚动视差背景,在 libgdx 中无限重复

c++ - 未找到 'vtkPolyDataMapper' 的覆盖

c++ - 管理嵌套类

具有可变参数 (...) 的 C++ 方法报告不正确的 arg 值

c++ - 无需指针(包括智能指针)或拷贝的高效工厂函数?

opengl - (如何)将标量转换为另一个标量,而无需在GLSL中进行转换?