Должен ли 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).
Другие вопросы по тегам