我什么时候应该调用glDeleteBuffers()? [英] When should I call glDeleteBuffers()?

查看:99
本文介绍了我什么时候应该调用glDeleteBuffers()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下工作代码,但是我不相信我在以安全的方式调用glDeleteBuffers.实际上,它正在运行(至少到目前为止),但是根据我一直在阅读的内容,我认为它不应该运行.

I have the following working code, however I'm not convinced that I'm calling glDeleteBuffers in a safe way. In practice it's working (for now at least) but from what I've been reading I don't think it should work.

GLuint vao_id;
glGenVertexArrays(1, &vao_id);
glBindVertexArray(vao_id);

GLuint VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glEnableVertexAttribArray(0);

    //Alternate position <<----

//Unbind the VAO
glBindVertexArray(0);

//Current position <<----
glDeleteBuffers(1, &VBO);

我目前在解除绑定VAO之后直接调用glDeleteBuffers.我尝试在设置了属性指针后立即在标记为替代的位置调用它.但是,这导致了崩溃-我的猜测是因为当我进行绘图调用时,没有数据要绘制,因为我已经删除了它.

I am currently calling glDeleteBuffers straight after unbinding the VAO. I have tried calling it in the alternative position marked - immediately after I have set the attribute pointer. This however caused a crash - my guess is this was because when I made the draw call there was no data to be drawn because I'd deleted it.

令我感到困惑的是,它的工作原理与我目前所拥有的一样.我担心a)我不太了解删除缓冲区时会发生什么,b)它只是偶然地工作并且可能会意外中断.

The thing that confuses me is that it works as I currently have it. I'm worried that a) I don't quite understand what happens when the buffer is delete and b) that it only works by chance and could unexpectedly break.

据我了解,调用glDeleteBuffers会删除数据,因此不应绘制任何数据-而是存在.因此,我的另一种想法是,当我重新绑定VAO时,将还原数据,尽管这对我来说并没有太大意义,因为我无法推断从何处还原数据.

As far as I understand calling glDeleteBuffers deletes the data so there shouldn't be any data to draw - but there is. So my other thought was that when I re-bind the VAO the data is restored, although that didn't make much sense to me because I can't reason where the data would be restored from.

有人可以让我知道我是否正确使用glDeleteBuffer吗?以及是否应该在何处调用(我猜想是一旦不再需要绘制数据了,很可能在程序结尾).

Can someone let me know if I am using glDeleteBuffer correctly? and if not where it should be called (I'm guessing once there is no need for the data to be drawn any more, probably at the end of the program).

推荐答案

您看到的是定义明确的行为.以下是与此规范相关的规范的关键部分(强调了内容).

What you're seeing is well defined behavior. The following are the key parts of the spec related to this (emphasis added).

在OpenGL 4.5规范中的"5.1.2自动取消绑定已删除对象"部分:

From section "5.1.2 Automatic Unbinding of Deleted Objects" in the OpenGL 4.5 spec:

删除缓冲区,纹理或渲染缓冲区对象后,该对象将从当前上下文中绑定到的所有绑定点取消绑定,并与容器对象的任何附件分离绑定到当前上下文,如DeleteBuffers,DeleteTextures和DeleteRenderbuffers所述.

When a buffer, texture, or renderbuffer object is deleted, it is unbound from any bind points it is bound to in the current context, and detached from any attachments of container objects that are bound to the current context, as described for DeleteBuffers, DeleteTextures, and DeleteRenderbuffers.

和"5.1.3删除的对象和对象名称的生存期":

and "5.1.3 Deleted Object and Object Name Lifetimes":

当删除缓冲区,纹理,采样器,渲染缓冲区,查询或同步对象时,其名称立即变为无效(例如,标记为未使用),但基础对象将不会删除,直到不再使用为止..

When a buffer, texture, sampler, renderbuffer, query, or sync object is deleted, its name immediately becomes invalid (e.g. is marked unused), but the underlying object will not be deleted until it is no longer in use.

如果满足以下任一条件,则正在使用缓冲区,纹理,采样器或渲染缓冲区对象:

A buffer, texture, sampler, or renderbuffer object is in use if any of the following conditions are satisfied:

该对象已附加到任何容器对象

the object is attached to any container object

...

在这种情况下,VAO被视为VBO的容器对象".因此,只要在VAO中引用了VBO,并且不删除VAO本身,VBO就会保持活动状态.这就是为什么您的代码版本末尾带有glDeleteBuffers()的原因.

The VAO is considered a "container object" for the VBO in this case. So as long as the VBO is referenced in a VAO, and the VAO itself is not deleted, the VBO stays alive. This is why your version of the code with the glDeleteBuffers() at the end works.

但是,如果当前绑定了VAO,并且您删除了VBO,则它会自动从VAO解除绑定.因此,VAO不再引用它,而是立即将其删除.这适用于在glVertexAttribPointer()之后立即调用glDeleteBuffers()的情况.

However, if the VAO is currently bound, and you delete the VBO, it is automatically unbound from the VAO. Therefore, it is not referenced by the VAO anymore, and deleted immediately. This applies to the case where you call glDeleteBuffers() immediately after glVertexAttribPointer().

在任何情况下,id(即名称)都会立即失效.因此,您将无法再次绑定它,例如修改数据.

In any case the id (aka name) becomes invalid immediately. So you would not be able to bind it again, and for example modify the data.

如果您更深入地研究规格,则有一些警告.例如,如果您删除一个缓冲区,并且由于VAO仍引用该缓冲区而使该缓冲区保持活动状态,则该缓冲区的名称可以用于新缓冲区.这意味着您基本上拥有两个具有相同名称的缓冲区,这可能会导致一些令人困惑的行为.

There are some caveats if you dig into the specs more deeply. For example, if you delete a buffer, and it stays alive because it is still referenced by a VAO, the name of the buffer could be used for a new buffer. This means that you basically have two buffers with the same name, which can result in some confusing behavior.

部分出于这个原因,我个人不会为您要继续使用的对象调用glDelete*().但是其他人喜欢尽快致电glDelete*().

Partly for that reason, I personally wouldn't call glDelete*() for objects that you want to keep using. But others like to call glDelete*() as soon as possible.

这篇关于我什么时候应该调用glDeleteBuffers()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆