私はVAOに依存すると考えている問題に直面していますが、よくわかりません。
GL初期化は簡単でしたが、VAOの正しい使い方についてはわかりません。
glGenVertexArrays(1,&vao)
続いて
glBindVertexArray(vao)
その後、描画パイプラインでglBindBuffer()、glVertexAttribPointer()、glEnableVertexAttribArray()などを呼び出しました。最初にバインドされたVAOを気にせずに
これは正しい習慣ですか?
VAOは、バインド方法に関して、VBOおよびテクスチャと同様に機能します。プログラムの全長に対して単一のVAOをバインドしても、VAOをまったく使用せずにレンダリングするだけで済むため、パフォーマンス上の利点はありません。実際、頂点属性の設定が描画されるときに実装がどのようにインターセプトするかに応じて、処理が遅くなる場合があります。
VAOのポイントは、初期化中にオブジェクトを1回描画するために必要なすべてのメソッドを実行し、メインループ中に余分なメソッド呼び出しのオーバーヘッドをすべてカットすることです。ポイントは、複数のVAOを用意し、描画時にそれらを切り替えることです。
ベストプラクティスの観点から、コードを整理する方法は次のとおりです。
initialization:
for each batch
generate, store, and bind a VAO
bind all the buffers needed for a draw call
unbind the VAO
main loop/whenever you render:
for each batch
bind VAO
glDrawArrays(...); or glDrawElements(...); etc.
unbind VAO
これにより、バッファーのバインド/バインド解除の混乱を回避し、各頂点属性のすべての設定を渡し、VAOをバインドする単一のメソッド呼び出しで置き換えます。
いいえ、VAOの使い方ではありません。 VBO、テクスチャ、またはシェーダーの使用方法と同じ方法でVAOを使用する必要があります。最初に設定します。また、レンダリング中は、変更せずにバインドするだけです。
VAOを使用すると、次のことができます。
void Setup() {
glGenVertexArrays(..);
glBindVertexArray(..);
// now setup all your VertexAttribPointers that will be bound to this VAO
glBindBuffer(..);
glVertexAttribPointer(..);
glEnableVertexAttribArray(..);
}
void Render() {
glBindVertexArray(vao);
// that's it, now call one of glDraw... functions
// no need to set up vertex attrib pointers and buffers!
glDrawXYZ(..)
}
次のリンクも参照してください。
これは正しい習慣ですか?
はい、これは完全に合法かつ有効です。いいですか?まあ...
この種のことについては、いくつかの 非公式のパフォーマンステスト がありました。そして、少なくともこれがテストされたNVIDIAハードウェアでは、VAOの「適切な」使用(つまり、他の全員が提唱したもの)は実際にはslower多くの場合。これは、VAOを変更してもバインドされるバッファーが変更されない場合に特に当てはまります。
私の知る限り、AMDハードウェアで同様のパフォーマンステストは行われていません。一般に、何か変更されない限り、これはVAOの許容される使用方法です。
上記のロバートの答えは、試してみたときにうまくいきました。ここで価値があるのは、Goで複数の頂点属性オブジェクトを使用するコードです。
// VAO 1
vao1 := gl.GenVertexArray()
vao1.Bind()
vbo1 := gl.GenBuffer()
vbo1.Bind(gl.ARRAY_BUFFER)
verticies1 := []float32{0, 0, 0, 0, 1, 0, 1, 1, 0}
gl.BufferData(gl.ARRAY_BUFFER, len(verticies1)*4, verticies1, gl.STATIC_DRAW)
pa1 := program.GetAttribLocation("position")
pa1.AttribPointer(3, gl.FLOAT, false, 0, nil)
pa1.EnableArray()
defer pa1.DisableArray()
vao1.Unbind()
// VAO 2
vao2 := gl.GenVertexArray()
vao2.Bind()
vbo2 := gl.GenBuffer()
vbo2.Bind(gl.ARRAY_BUFFER)
verticies2 := []float32{-1, -1, 0, -1, 0, 0, 0, 0, 0}
gl.BufferData(gl.ARRAY_BUFFER, len(verticies2)*4, verticies2, gl.STATIC_DRAW)
pa2 := program.GetAttribLocation("position")
pa2.AttribPointer(3, gl.FLOAT, false, 0, nil)
pa2.EnableArray()
defer pa2.DisableArray()
vao2.Unbind()
次に、メインループで次のように使用できます。
for !window.ShouldClose() {
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
vao1.Bind()
gl.DrawArrays(gl.TRIANGLES, 0, 3)
vao1.Unbind()
vao2.Bind()
gl.DrawArrays(gl.TRIANGLES, 0, 3)
vao2.Unbind()
window.SwapBuffers()
glfw.PollEvents()
if window.GetKey(glfw.KeyEscape) == glfw.Press {
window.SetShouldClose(true)
}
}
完全なソースを表示する場合は、Gistとして入手でき、go-glの例から派生しています。
https://Gist.github.com/mdmarek/0f73890ae2547cdba3a7
元々の回答に感謝します。ECrownofFireと同じ質問がありました。