为什么glMapBuffer返回NULL

Why is glMapBuffer returning NULL?

本文关键字:NULL 返回 glMapBuffer 为什么      更新时间:2023-10-16

我不是在尝试流式传输或任何东西,我只是想通过将顶点和索引数据直接加载到 OpenGL 的缓冲区中来加快我的文件加载代码,而不必先将其放入中间缓冲区。下面是抓取指针的代码:

void* VertexArray::beginIndexLoad(GLenum indexFormat, unsigned int indexCount)
{
    if (vao == 0)
        return NULL;
    bindArray();
    glGenBuffers(1, &ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize(indexFormat) * indexCount, NULL, GL_STATIC_DRAW);
    iformat = indexFormat;
    icount = indexCount;
    GLenum err = glGetError();
    printf("%in", err);
    void* ptr = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
    err = glGetError();
    printf("%in", err);
    unbindArray();
    return ptr;
}

问题是,这返回 NULL。更糟糕的是,就在我用GL_ARRAY_BUFFER做类似的事情之前,我得到了一个完全有效的指针。为什么这失败了,而另一个成功了?

第一个glGetError返回 1280 (GL_INVALID_ENUM )。 第二个 glGetError 返回 1285( GL_OUT_OF_MEMORY )。 我知道它实际上并没有内存不足,因为通常通过glBufferData上传完全相同的数据可以正常工作。

也许我只是处理错了顶点数组?

(附言。我在游戏开发堆栈交换中问了这个问题,但一无所获。 在这里重新发布以尝试弄清楚)

首先,您的错误检查代码是错误的。您必须在循环中调用glGetError,直到它返回 GL_NO_ERROR

关于GL_OUT_OF_MEMORY错误代码:它也可能意味着地址空间不足,如果从操作系统请求大量连续的虚拟地址空间,但进程的地址空间非常碎片化,以至于没有可用的块大小(即使可用地址空间的总量就足够了)。

这已成为32位系统的祸根。一个简单的补救措施是使用 64 位系统。如果您坚持使用 32 位平台,则必须对地址空间进行碎片整理(这并非易事)。

如果我是你,我会尝试以下方法:

  • GL_STATIC_DRAW替换为GL_DYNAMIC_DRAW
  • 确保indexSize(indexFormat) * indexCount产生的尺寸符合您的预期
  • 尝试使用 glMapBufferRange 而不是 glMapBuffer ,类似于glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, yourBufferSize, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
  • 检查ibo是否属于 GLuint 类型

编辑:fwiw,我会得到一个gDEBugger,并在出现OpenGL错误时设置一个断点来中断。

我解决了这个问题。 我indexSize(header.indexFormat)传球,而我本应该在header.indexFormat中通过. 我现在觉得自己像个白痴,很抱歉浪费大家的时间。