re-glBufferData() 'ingはglVertexAttribPointerとどのように相互作用しますか?
基本的なシーケンスを理解しています。glGenBuffers()は「バッファオブジェクト名」を作成し、glBindBuffer()は実際のバッファオブジェクトを作成し(名前をバインドします)、glBufferData()は「バッファオブジェクトのデータストアを作成して初期化します」、そしてglVertexAttribPointer ()は、バッファデータの形式を設定し、バッファオブジェクトのバインドを頂点属性配列の状態の一部として保存します。
私が確信していないトリッキーなことは、「バッファオブジェクトデータストア」(バッファオブジェクト自体ではない)がglBufferData()の新しい呼び出しによって吹き飛ばされた場合に、glVertexAttribPointer()のものが有効なままであるかどうかです。これは通常は良い考えではないことを私は知っています-バッファを書き換えるだけの場合はglBufferSubData()を使用します-しかし、サイズを変更する必要がある場合はglBufferData()が唯一のオプションのようです。さらに、私はただ興味があります。
リファレンスページでは、どちらの方向にも進む可能性があるように聞こえます-特に(https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glVertexAttribPointer.xhtml):
ポインタがNULLでない場合、ゼロ以外の名前付きバッファオブジェクトをGL_ARRAY_BUFFERターゲットにバインドする必要があります(glBindBufferを参照)。そうでない場合、エラーが生成されます。ポインタは、バッファオブジェクトのデータストアへのバイトオフセットとして扱われます。バッファオブジェクトバインディング(GL_ARRAY_BUFFER_BINDING)は、インデックスインデックスの汎用頂点属性配列状態(GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)として保存されます。
ジェネリック頂点属性配列が指定されている場合、現在の頂点配列バッファーオブジェクトバインディングに加えて、サイズ、タイプ、正規化、ストライド、およびポインターが頂点配列状態として保存されます。
データストアが別のものに置き換えられた場合でも、バイトオフセットとバッファオブジェクトバインディングの両方が有効なままである可能性があるようです。ただし、呼び出し時に、バインディングが特定のポインターをデータストアにキャプチャし、データストアが置き換えられると無効になるように実装されていることもわかりました。どちらの方法も、言葉遣いによって排除されているようには見えません。
回答
その後glBufferData()を呼び出した後でも、glVertexAttribPointer()バインディングは有効なままであるようです。私はそれを試してみてこれを決定しましたが、これは100%の証拠ではありません-この実装(私の場合はNVidiaドライバー)でのみ機能する可能性があります。
ただし、エラーメッセージのコールバックとデバッグモードをオンにすると、glBufferData()の2回目の呼び出しで次のメッセージが表示されます。これは、この状況が予想される/設計されていることを強く示唆しています。
[LWJGL] OpenGLデバッグメッセージ ID:0x20071 出典:API タイプ:その他 重大度:通知 メッセージ:バッファの詳細情報:バッファオブジェクト1(GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB(0)、GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB(1)、およびGL_ARRAY_BUFFER_ARBにバインドされています。バッファメモリのソースとしての操作のヒントです。
最初の2つのバインディングは、glVertexAttribPointer()への2回の呼び出しを表しており、glBufferData()を最初に呼び出したときにログに記録されるメッセージには含まれていません。