使用glTexImage2D上传图像数据失败

Rob*_*n92 0 windows opengl segmentation-fault glfw

我正在开发一个 OpenGL 应用程序,在Linux (x86_32 和 x86_64)下一切正常,但在将应用程序移植到Windows期间我遇到了困难。我的应用程序使用非常基本的OpenGL 1.0、很棒的glfw 2.7.6libpng 1.5.7。在移植整个程序之前,我尝试编写尽可能简单的代码来测试这些库是否在 Windows 下正常工作,并且一切似乎都工作得很好,直到我开始使用纹理!

在我的程序中使用纹理glTexImage2D(..)会出​​现访问冲突,并出现以下错误:

First-chance exception at 0x69E8F858 (atioglxx.dll) in sidescroll.exe: 0xC0000005: Access violation reading location 0x007C1000.
Unhandled exception at 0x69E8F858 (atioglxx.dll) in sidescroll.exe: 0xC0000005: Access violation reading location 0x007C1000.
Run Code Online (Sandbox Code Playgroud)

我做了一些研究,发现这可能是 GPU 驱动程序错误。遗憾的是,我有一台配备AMD Radeon HD5650的东芝 L650-1NU笔记本电脑,没有提供任何驱动程序,而是由供应商分发的过时驱动程序。给定帖子的作者建议使用,但由于我使用OpenGL 1.0,我无法访问此方法。 glBindBuffer

您是否知道如何在不使用较新的 OpenGL 的情况下绕过此问题?不过,如果这是唯一的解决方案,可以向我提供有关如何将OpenGL 2.1glfw一起使用的教程或代码片段吗?

这是我的代码片段,它导致了错误:

img = img_loadPNG(BACKGROUND);
if (img) {
    printf("%p %d %d %d %d", img->p_ubaData, img->uiWidth, img->uiHeight, img->usiBpp, img->iGlFormat);

    glGenTextures(1, &textures[0]);
    glBindTexture(GL_TEXTURE_2D, textures[0]);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img->uiWidth, img->uiHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, img->p_ubaData); //SEGFAULT HERE ON WINDOWS!
    //img_free(img); //it may cause errors on windows
} else printf("Error: loading texture '%s' failed!\n", BACKGROUND);
Run Code Online (Sandbox Code Playgroud)

dat*_*olf 5

您遇到的错误是因为您传递给 glTexImage2D 的缓冲区比 glTexImage2D 尝试从参数推导出来的缓冲区短。这在 Windows 下会崩溃,但在 Linux 下不会,因为在 Linux 下,内存分配往往比您请求的要大一些,而在 Windows 下,您会受到非常严格的限制。

PNG 很可能读取为 RGB。然而,您告诉 glTexImage2D 您传递了 GL_RGBA,这当然会访问越界。

我看到img您收到的结构有一个 element iGlFormat。我敢打赌这正是传递给 glTexImage2D 的格式。所以试试这个:

glTexImage2D(
    GL_TEXTURE_2D, 0,
    img->iGlFormat, // This is not ideal, OpenGL will chose whatever suits
    img->uiWidth, img->uiHeight, 0,
    img->iGlFormat, GL_UNSIGNED_BYTE,
    img->p_ubaData )
Run Code Online (Sandbox Code Playgroud)