When should you call glDeleteBuffers ()?

I have the following working code, however I'm not sure if I call glDeleteBuffers in a safe way. In practice, this works (at the moment, at least), but from what I read, 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); 

I am currently calling glDeleteBuffers right after untying the VAO. I tried calling it at the alternate position labeled - right after I set the pointer to the attribute. This, however, caused a crash - I suppose it happened because when I made the call for the rally, there was no data because I deleted it.

What bothers me is that it works, the way I do it now. I am worried that: a) I do not quite understand what happens when the buffer is deleted, and b) it only works by accident and may break unexpectedly.

As I understand it, calling glDeleteBuffers deletes the data, so there shouldn't be any data to draw - but there is. My other thought was that when I reconnect VAO, the data is recovered, although it does not make much sense to me, because I cannot explain where the data will be recovered from.

Can someone tell me if I am using glDeleteBuffer correctly? and if not where it should be called (I assume that there is no need for the data to be done more, perhaps at the end of the program).

+6
source share
2 answers

What you see is clearly defined behavior. The following are the key parts of the specification associated with this (highlighted added).

From the section "5.1.2 Automatically Untying Remote Objects" in the OpenGL 4.5 specification:

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

and "5.1.3 Remote object and object names"

When a buffer, texture, sampler, rendering, query, or synchronization object is deleted, its name immediately becomes invalid (for example, marked is not used), but the base object will not be deleted until it is no longer used .

A buffer, texture, sampler, or renderbuffer object is used if one of the following conditions is true:

an object is bound to any container object

...

HLW in this case is considered a “container facility” for VBO. Thus, while the VBO is mentioned in the VAO, and the VAO itself is not deleted, the VBO remains alive. This is why your version of the code with glDeleteBuffers() at the end works.

However, if the VAO is currently connected and you delete the VBO, it is not automatically associated with the VAO. Therefore, it no longer refers to the VAO and is immediately deleted. This is the case when you call glDeleteBuffers() immediately after glVertexAttribPointer() .

In any case, id (aka name) immediately becomes invalid. Thus, you cannot link it again and, for example, change the data.

There are a few caveats if you delve deeper into the specification. For example, if you delete a buffer and it remains alive because it still refers to VAO, the buffer name can be used for the new buffer. This means that you basically have two buffers with the same name, which can lead to some confusing behavior.

Partly for this reason, I personally will not call glDelete*() for the objects you want to use. But others like to call glDelete*() as soon as possible.

+14
source

The position you mentioned is incorrect for calling glDeleteBuffer because until you rendered the object. I think it would be better if you called the function after rendering the object; after calling glDrawArray or glDrawIndex .

if you delete the buffer first and then call draw, you may have to deal with a crash problem. because the call of the call will try to access the buffer that you deleted earlier.

0
source

Source: https://habr.com/ru/post/980967/


All Articles