5

バッファ オブジェクトを削除する前にバインドを解除する必要がありますか? 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);
}

削除する前にアンバインドするのは良い習慣ですか、それとも悪い習慣ですか?

4

2 に答える 2

5

それは必要ですか?

  いいえ。

それは良い考えですか?

  おそらくですが、現在の疑似コードにはありません。


GL でリソースを削除する前に手動でアンバインドしたいのは、それを別のコンテキストでバインドしている場合だけです。これは、GL リソースに関連付けられたメモリを実際に解放するための基準の 1 つは、参照カウントが0であることだからです。解放するオブジェクトのキューに入れる前に、オブジェクトを現在のglDelete* (...)コンテキストからバインド解除するだけです。

現在バインドされていないVAO がこのバッファーへのポインターを保持しているときにそれを削除した場合、または呼び出したものとはまったく異なる OpenGL コンテキストでバインドされている場合、参照カウントは終了する前に0glDelete* (...)に達しません。その結果、参照を保持しているすべての VAO / レンダー コンテキストから実際にバインドを解除するか破棄するまで、メモリは解放されません。すべてのぶら下がっている参照を処理するまで、効果的にメモリ リークが発生します。glDelete* (...)

つまり、glDelete* (...)常に現在のコンテキストからリソースをバインド解除し、すぐに再利用できるように名前を再利用しますが、バインド解除後に参照カウントが0である場合にのみ、関連するメモリを解放します。


この場合、呼び出し元と同じコンテキストで実行しているため、バインド解除はまったく不要ですglDeleteBuffers (...)。この呼び出しは、削除するオブジェクトのバインドを暗黙的に解除するため、冗長なことを行っています。さらに、呼び出す前にすでに VAO を削除しています。glDeleteBuffers (...)その VAO が削除されると、すべてのポインターが放棄され、バッファーへの参照カウントが減少します。

于 2014-05-09T18:21:21.370 に答える
4

公式ドキュメント ( https://www.opengl.org/sdk/docs/man/html/glDeleteBuffers.xhtml ) は次のように述べています。

glDeleteBuffers は、配列 buffer の要素によって指定された n 個の buffer オブジェクトを削除します。バッファ オブジェクトが削除されると、その内容はなくなり、その名前は自由に再利用できます (たとえば、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).
于 2014-05-09T13:01:11.143 に答える