在调用glDeleteBuffers之前,VBO应该被解除绑定吗?

时间:2014-05-09 12:41:38

标签: opengl buffer-objects

在删除缓冲区对象之前是否需要取消绑定?如果我将它绑定在VAO中并将其删除而不解除绑定(绑定到0),会发生什么?引用是否仍然存在?

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

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

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

在删除之前取消绑定是好的还是坏的做法?

2 个答案:

答案 0 :(得分:5)

是否有必要?

<强> 没有

这是个好主意吗?

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


在删除之前,您唯一想要手动取消绑定GL资源的时间是您在单独的上下文中绑定它。这是因为实际 释放 与GL资源相关联的内存的标准是它的引用计数 0 glDelete* (...)仅在 当前 上下文中取消绑定对象,然后才将其置于要释放的对象队列中。

如果在 当前未绑定 的VAO保存指向此缓冲区的指针时,或者如果它绑定在与该缓冲区完全不同的OpenGL上下文中,则将其删除您调用glDelete* (...),然后引用计数在glDelete* (...)完成之前未达到 0 。因此,在您实际取消绑定或销毁所有保留引用的VAO /渲染上下文之前,内存 将不会被释放 。在你处理所有悬空参考之前,你将有效地泄漏记忆。

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


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

答案 1 :(得分:3)

官方文档(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).