OpenGL 顶点数组/缓冲区对象

Posted

技术标签:

【中文标题】OpenGL 顶点数组/缓冲区对象【英文标题】:OpenGL Vertex Array/Buffer Objects 【发布时间】:2012-11-12 10:52:36 【问题描述】:

问题 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

我可以为缓冲区对象分配的最大内存量是多少?当然,它必须取决于系统,但我似乎无法找到它的估计值。当显存不够大时会发生什么?我怎么知道?

【问题讨论】:

【参考方案1】:

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​ 错误。

【讨论】:

【参考方案2】:

回答 1

这取决于。如果您之前调用过glDeleteBuffers,则在您删除VAO 时它会被删除。如果没有,它不会。 VAO 持有对 VBO 的引用,您的应用程序在调用glGenBuffers 后也持有引用。这两个引用都需要在 VBO 被删除之前释放。

答案 2

(afaik)无法查询您可以分配的最大金额。但是,根据reference documentation,如果无法分配缓冲区,glBufferData 将发出GL_OUT_OF_MEMORY

【讨论】:

VBO和VAO是否需要绑定才能删除? @StevenLu 不,不需要绑定,但可以。来自规范页面的引用:如果当前绑定的缓冲区对象被删除,则绑定恢复为 0 (opengl.org/sdk/docs/man/html/glDeleteBuffers.xhtml)

以上是关于OpenGL 顶点数组/缓冲区对象的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL 顶点数组对象是存储顶点缓冲区名称和索引,还是只存储索引?

我的OpenGL学习进阶之旅介绍顶点缓冲区对象VBO和元素数组缓冲区对象EBO,并对比使用VBO和不使用VBO绘制三角形的效果

OpenGL复制顶点缓冲区对象

我的OpenGL学习进阶之旅介绍 顶点数组对象VAO并实战一下

在交错的 openGL 顶点缓冲区对象之间复制

我的OpenGL学习进阶之旅介绍一下 映射缓冲区对象和复制缓冲区对象