如何完全取消绑定GL_ELEMENT_ARRAY_BUFFER?(How to fully unbi

2019-10-19 01:46发布

我工作的一个多线程的应用程序,同时呈现几何多个宗教组织。 我遇到一个泄漏(如在描述这个问题 )。

我已经能够将它缩小一点 - 如果我做一个改变,它停止泄漏 - 但我想不出为什么。

在每4个线程(每个都有自己的共享上下文),我做了以下每个渲染周期:

// Upload

positionBuffer = getUnusedArrayBufferFromPool();
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*vertexCount, positions, GL_STREAM_DRAW);

{
    GLuint vertexArray;
    glGenVertexArrays(1, &vertexArray);
    glBindVertexArray(vertexArray);

    elementBuffer = getUnusedElementArrayBufferFromPool();
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*elementCount, elements, GL_STREAM_DRAW);

    glBindVertexArray(0);
    glDeleteVertexArrays(1, &vertexArray);
}

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);



// Render (possibly on a different context)

GLuint vertexArray;
glGenVertexArrays(1, &vertexArray);
glBindVertexArray(vertexArray);

glUseProgram(programName);
{
    GLint positionAttribute = glGetAttribLocation(programName, "position");
    glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
    glVertexAttribPointer((GLuint)positionAttribute, 4 /* XYZW */, GL_FLOAT, GL_FALSE, sizeof(float)*4, (void*)0);
    glEnableVertexAttribArray((GLuint)positionAttribute);

    {
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
        glDrawElements(GL_TRIANGLES, (GLsizei)elementCount, GL_UNSIGNED_INT, (void*)0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    }

    glDisableVertexAttribArray((GLuint)positionAttribute);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}
glUseProgram(0);

glBindVertexArray(0);
glDeleteVertexArrays(1, &vertexArray);



// Cleanup (possibly on a different context)

glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glBufferData(GL_ARRAY_BUFFER, 0, 0, GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
throwArrayBufferBackInPool(positionBuffer);

//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
//glBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, 0, GL_STREAM_DRAW);
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
//throwElementArrayBufferBackInPool(elementBuffer); // Why does this leak if we recycle it?
glDeleteBuffers(1, &elementBuffer);

如果我换了最后两行 - 如果我扔元素缓冲放回池中,而不是删除它的每个渲染周期 - OpenGL驱动程序监视器指示一个巨大的泄漏。

但我宁愿集中它,因为调用glDeleteBuffers()每帧实在是太慢了。

我在想什么? 我想,我不能拆散elementBuffer从东西-这东西是抱着一种对它的引用,引起泄漏的-但我想不出什么。


编辑:只是一个不同的系统(的Mac OS 10.6)上测试-在该系统上,如果我再利用缓冲区泄漏。

编辑:我修改了应用程序,以便GL_ARRAY_BUFFER从分别集中GL_ELEMENT_ARRAY_BUFFER ,并让elementBuffer始终势必GL_ELEMENT_ARRAY_BUFFER 。 但它仍然漏水,如果我throwElementArrayBufferBackInPool(elementBuffer);

编辑:澄清为什么我创建和上传过程中删除VAO并在渲染过程中-因为他们可能会在不同的共享GL上下文发生,VAOs不能上下文之间共享。

编辑:我修改我的应用程序抛出缓冲区回入池前提供零大小的缓冲区的数据,但它仍然只是泄漏一样迅速。

Answer 1:

您的缓冲池用于绑定GL_ARRAY_BUFFER以及GL_ELEMENT_ARRAY_BUFFER对象。 更糟的是,你第一次使用elementBuffer用于绑定GL_ARRAY_BUFFER ,但随后就使用它的携带GL_ELEMENT_ARRAY_BUFFER 。 我还没有完全包裹着我周围的头,但混合的命名空间和不一致的使用绑定之间的某处我把我的钱上。

我的建议:创建缓冲区名称的单独池GL_ELEMENT_ARRAY_BUFFER使用,并确保你使用它始终如一地为仅此而已。



文章来源: How to fully unbind a GL_ELEMENT_ARRAY_BUFFER?