在绑定到“顶点数组对象”之后,我应该删除“顶点缓冲对象”吗?

14

我创建了一个VBO(顶点缓冲对象)和VAO(顶点数组对象),并进行了以下操作:

glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(...);
glVertexAttribPointer(...);
glEnableVertexAttribArray(0);
glBindVertexArray(0);

假设一切正常,我可以在使用vao绘图后删除vbo吗?

我知道缓冲区绑定到vao,所以我认为可以这样做。

问题是,如果我在我的电脑上(Intel显卡)删除缓冲区,它可以正常工作(所有内容都正确显示),但在我朋友的电脑上(AMD)没有任何东西显示。

可能的问题是什么?

(顺便说一句,如果我不删除缓冲区,程序在我的电脑和我朋友的电脑上都可以正常工作)

1个回答

10
根据OpenGL 4.5规范,在解绑定VAO后删除它是合法的。
“名称删除和对象删除”部分介绍了,如果正在使用GL上下文的对象被删除,则该名称会立即标记为未使用,并且某些类型的对象将自动从当前上下文中的绑定点解绑定,如 5.1.2节所述。然而,直到该对象不再使用为止,实际底层对象才会被删除。关于这种情况在5.1.3节中有更详细的讨论。
当缓冲区、纹理或渲染缓存对象被删除时,与当前上下文中绑定点绑定的对象��会从中解绑,并且从当前上下文中绑定到容器对象的任何附件也会被分离,如DeleteBuffers,DeleteTextures和DeleteRenderbuffers中所述。但是,未绑定到上下文的容器对象的附件(例如附加到未绑定到上下文的顶点数组对象的缓冲区的删除)不受影响,并且继续作为已删除对象的引用,如下一节所述。
当缓冲区、纹理、采样器、渲染缓存、查询或同步对象被删除时,其名称立即变为无效(例如,标记为未使用),但是只有在不再使用底层对象时,底层对象才会被删除。
因此,要么这是AMD驱动程序的错误,要么情况并非如您所述。

1
@JohnMiz:你是指在AMD上吗?这可能是一个AMD的bug,或者是你没有展示的代码bug。另外,我是根据OpenGL 4.5规范回答的,因为你没有说你使用的是哪个版本。在旧版本上,它可能会有不同的行为或未定义的情况。你可以自己检查规范,它们是免费提供的,而且非常易于阅读。 - Yakov Galka
1
@ybungalobill:你提到的行为(感谢纠正,我不知道),从3.3核心配置文件(D.1.2)开始就是一样的,因此实际使用的版本不应该有任何区别。 - BDL
1
@JohnMiz:需要注意的是,仅仅因为某件事情是“合法的”,并不意味着它是一个好主意。除非你已经完成了使用,否则不要删除对象。 - Nicol Bolas
1
@JohnMiz:这是代码风格和不同实现之间的可移植性问题,与VRAM无关。如果你要构建一个游戏引擎,那么你可能需要解决用户将使用的不同驱动程序中的错误,这种情况下,你不应该在删除VAO之前删除缓冲区,就像Nicol所说的那样。 - Yakov Galka
1
@ybungalobill:还有一点就是,如果你将来想转向Vulkan的话,就不能指望驱动程序在类似删除对象这样的操作时为你保存。在这种API中,删除意味着它立刻消失了。最好现在就训练自己承受这种“认知负担”,以免在需要时没有准备好。 - Nicol Bolas
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接