Должен ли VBO быть свободным перед вызовом glDeleteBuffers?
Требуется ли, чтобы мы удалили буферный объект перед его удалением? Что произойдет, если я связал его в VAO и удалил без отмены привязки (привязка к 0)? Будет ли ссылка еще существовать?
public void dispose()
{
glBindVertexArray(0);
glDeleteVertexArrays(vaoID);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(vboVertID);
glDeleteBuffers(vboColID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDeleteBuffers(eboID);
}
Хорошая или плохая практика - отсоединять перед удалением?
2 ответа
Это необходимо?
Нет.
Это хорошая идея?
Возможно, но не в вашем текущем псевдокоде.
Единственный раз, когда вы захотите вручную отсоединить ресурс в GL перед удалением, это если вы привязали его в отдельном контексте. Это потому, что одним из критериев для фактического освобождения памяти, связанной с ресурсом GL, является то, что он имеет счетчик ссылок 0. glDelete* (...)
только освобождает объект от текущего контекста до помещения его в очередь объектов.
Если вы удалите его, когда VAO, который в данный момент не связан, содержит указатель на этот буфер, или если он связан в совершенно ином контексте OpenGL, чем тот, который вы вызываете glDelete* (...)
в, то счетчик ссылок не достигает 0 раньше glDelete* (...)
отделки. В результате память не будет освобождена до тех пор, пока вы фактически не отсоедините ее или не уничтожите все контексты VAO / render, содержащие ссылки. Вы будете эффективно пропускать память, пока не позаботитесь обо всех висячих ссылках.
Короче, glDelete* (...)
всегда отменяет привязку ресурсов из текущего контекста и возвращает любые имена для немедленного повторного использования, но освобождает связанную память только в том случае, если после отмены привязки счетчик ссылок равен 0.
В этом случае открепление совершенно не нужно, потому что вы делаете это в том же контексте, который вы называете glDeleteBuffers (...)
от. Этот вызов неявно освобождает объект, который вы удаляете, поэтому вы делаете что-то избыточное. Более того, вы уже удалили свой VAO перед звонком glDeleteBuffers (...)
- когда этот VAO был удален, он отказался от всех своих указателей и таким образом уменьшил счетчик ссылок на ваш буфер.
Официальная документация ( https://www.opengl.org/sdk/docs/man/html/glDeleteBuffers.xhtml) гласит:
glDeleteBuffers удаляет n объектов буфера, названных элементами буферов массива. После того, как буферный объект удален, у него нет содержимого, и его имя свободно для повторного использования (например, glGenBuffers). Если буферный объект, который в данный момент связан, удаляется, привязка возвращается к 0 (отсутствие какого-либо объекта буфера).
Что касается VAO - https://www.opengl.org/registry/specs/ARB/vertex_array_object.txt
(2) What happens when a buffer object that is attached to a non-current
VAO is deleted?
RESOLUTION: Nothing (though a reference count may be decremented).
A buffer object that is deleted while attached to a non-current VAO
is treated just like a buffer object bound to another context (or to
a current VAO in another context).