5

Is it required that we should unbind a buffer object before deleting it? If I had bound it in a VAO and deleted it without unbinding (binding to 0), what will happen? Will the reference still exist?

public void dispose()
{
    glBindVertexArray(0);
    glDeleteVertexArrays(vaoID);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDeleteBuffers(vboVertID);
    glDeleteBuffers(vboColID);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glDeleteBuffers(eboID);
}

Is it a good or a bad practice to unbind before deletion?

4

2 回答 2

5

有必要吗?

  不。

这是个好主意吗?

  可能,但不在您当前的伪代码中。


唯一需要在删除之前手动取消绑定 GL 中的资源的情况是,如果您将其绑定在单独的上下文中。这是因为实际释放与 GL 资源关联的内存的标准之一是它的引用计数为0。仅在将对象放入要释放的对象队列之前从当前glDelete* (...)上下文中解除绑定。

如果您在当前未绑定的 VAO持有指向此缓冲区的指针时删除它,或者如果它绑定在与您调用的完全不同的 OpenGL 上下文中,则引用计数在完成之前glDelete* (...)不会达到0glDelete* (...)。因此,在您真正解除绑定或销毁所有持有引用的 VAO / 渲染上下文之前,不会释放内存。在处理完所有悬空引用之前,您将有效地泄漏内存。

简而言之,glDelete* (...)它将始终从当前上下文中取消绑定资源并回收任何名称以立即重用,但只有在取消绑定后引用计数为0时才会释放关联的内存。


在这种情况下,完全没有必要取消绑定,因为您是在调用的同一上下文中这样做的glDeleteBuffers (...)。此调用隐式取消绑定您正在删除的对象,因此您正在做一些多余的事情。更重要的是,您在调用之前已经删除了您的 VAO glDeleteBuffers (...)- 当该 VAO 被删除时,它放弃了所有指针,从而减少了对您的缓冲区的引用计数。

于 2014-05-09T18:21:21.370 回答
4

官方文档(https://www.opengl.org/sdk/docs/man/html/glDeleteBuffers.xhtml)说:

glDeleteBuffers 删除由数组缓冲区元素命名的 n 个缓冲区对象。缓冲区对象被删除后,它没有内容,并且它的名称可以免费重用(例如通过 glGenBuffers)。如果当前绑定的缓冲区对象被删除,则绑定恢复为 0(没有任何缓冲区对象)。

至于 VAO - https://www.opengl.org/registry/specs/ARB/vertex_array_object.txt

(2) What happens when a buffer object that is attached to a non-current
    VAO is deleted?

RESOLUTION: Nothing (though a reference count may be decremented). 
A buffer object that is deleted while attached to a non-current VAO
is treated just like a buffer object bound to another context (or to
a current VAO in another context).
于 2014-05-09T13:01:11.143 回答