为什么glMapBuffer返回NULL?

时间:2014-03-03 20:42:01

标签: c++ opengl

我不想尝试流或任何东西,我只是想通过将顶点和索引数据直接加载到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("%i\n", err);

    void* ptr = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);

    err = glGetError();
    printf("%i\n", err);

    unbindArray();

    return ptr;
}

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

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

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

(ps。我在gamedev堆栈交换中询问了这一点并没有得到任何结果。重新发布此处以试图弄明白)

3 个答案:

答案 0 :(得分:0)

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

关于GL_OUT_OF_MEMORY错误代码:它还可能意味着超出地址空间,如果从操作系统请求大的连续虚拟地址空间区域,则很容易发生这种情况,但是进程的地址空间是如此碎片化,以至于没有可用大小的块(即使可用地址空间的总量就足够了)。

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

答案 1 :(得分:0)

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

  • GL_STATIC_DRAW替换为GL_DYNAMIC_DRAW
  • 确保indexSize(indexFormat) * indexCount生成您期望的尺寸
  • 尝试使用glMapBufferRange代替glMapBufferglMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, yourBufferSize, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
  • 检查iboGLuint
  • 类型

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

答案 2 :(得分:0)

我解决了这个问题。当我应该在indexSize(header.indexFormat)过世时,我正在传递header.indexFormat。我现在觉得自己像个白痴,我很抱歉浪费每个人的时间。