OpenGL顶点数组/缓冲区对象

5

问题1

如果在某个VAO下创建了顶点缓冲对象,那么一旦该VAO被删除,这些缓冲对象是否也会被删除?

例如:

glGenBuffers(1, &bufferObject);
glGenVertexArrays(1, &VAO);

glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, bufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(someVertices), someVertices, 
             GL_STATIC_DRAW);
glEnableVertexAttribArray(positionAttrib);
glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, NULL);

当之后调用glDeleteVertexArrays(1, &VAO);时,bufferObject是否也会被删除?
我问这个问题是因为我看到一些例子没有删除这些缓冲区对象。
问题2
我可以为缓冲区对象分配的最大内存量是多少?它必须是系统相关的,但我似乎找不到一个估计值。当视频内存不够大时会发生什么?我怎么知道呢?
2个回答

15

1:缓冲区对象并不是“在”VAO下创建的。缓冲区对象状态不是VAO状态的一部分。VAO可以引用缓冲区对象,但是这种关联只是通过调用glVertexAttribPointer(或其他*Pointer调用)来实现的。简单地将缓冲区绑定到GL_ARRAY_BUFFER 并没有将其放入VAO中。您可以将缓冲区绑定到该目标而不绑定VAO。以下是合法代码:

glGenBuffers(1, &bufferObject);
glBindBuffer(GL_ARRAY_BUFFER, bufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(someVertices), someVertices, 
             GL_STATIC_DRAW);  //Creates the buffer storage.

glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glEnableVertexAttribArray(positionAttrib);
glVertexAttribPointer(positionAttrib, 3, GL_FLOAT, GL_FALSE, 0, NULL); //Uses whatever is bound to GL_ARRAY_BUFFER
请注意,这不适用于GL_ELEMENT_ARRAY_BUFFER。该绑定直接是VAO状态的一部分。因此,在绑定到该目标之前,您需要绑定VAO。
然而,绑定目标并不等同于创建。您可以将缓冲区绑定到GL_TRANSFORM_FEEDBACK_BUFFER,使用glBufferData创建其存储,并在稍后绑定以供GL_ARRAY_BUFFER或作为GL_ELEMENT_ARRAY_BUFFER使用。
至于您问题的主要内容,答案是否定的。VAO的破坏不会摧毁它所引用的缓冲对象。
2:没有标准的OpenGL函数来检测可用资源的数量。如果您尝试创建存储空间而实现已经没有资源了,您将收到一个GL_OUT_OF_MEMORY​错误。

8

答案 1

这要看情况。如果你在删除VAO之前调用了glDeleteBuffers,那么VBO将会被删除。否则,它不会被删除。VAO持有对VBO的引用,同样在调用glGenBuffers后,你的应用程序也会持有对VBO的引用。在删除VBO之前,这两个引用都需要被释放。

答案 2

(据我所知)没有办法查询可分配的最大量。然而,根据参考文档,如果无法分配缓冲区,glBufferData将会发出GL_OUT_OF_MEMORY信号。


1
在删除VBOs和VAOs之前,它们需要被绑定吗? - Steven Lu
1
@StevenLu 不需要绑定,但可以绑定。从规范页面引用:如果正在绑定的缓冲区对象被删除,则绑定将恢复为 0 (https://www.opengl.org/sdk/docs/man/html/glDeleteBuffers.xhtml) - Chris

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