OpenGL Vertex Array Object(VAO)にはどの状態が保存されますか?また、VAOを正しく使用するにはどうすればよいですか?


25

OpenGL VAOにはどの状態が保存されているのかと思っていました。VAOには、バッファリングされた頂点の頂点仕様に関連する状態(バッファ内の属性、バインドされているバッファなど)が含まれていることがわかりました。VAOの正しい使用法をよりよく理解するために、VAOがどの状態を保持しているかを正確に知りたいです。


VAOの使用をどのように想定するか

簡単な例から、VAOの正しい使用法は次のとおりであることがわかりました。

セットアップ

Generate VAO
BindVAO
---- Specify vertex attributes
---- Generate VBO's
---- BindVBO's
-------- Buffer vertex data in VBO's
---- Unbind VBO's
Unbind VAO

レンダリング

Bind VAO
---- Draw
Unbind VAO

このことから、少なくとも頂点バッファーバインディング頂点属性の仕様がVAOに格納されていると想定しています。ただし、この使用パターンが(複数の)テクスチャと(複数の)シェーダープログラムが作用する状況にどのように拡張されるかはわかりません。あるアクティブなシェーダプログラム VAOに保存されますか?また、テクスチャバインドサンプリング/ラッピング設定)もVAOに保存されますか?ユニフォームにも同じ?


したがって、私の質問は次のとおりです。

  • OpenGL VAOにはどのような正確な状態が保存されていますか?(VBOバインディング、属性仕様、アクティブシェーダープログラム、テクスチャバインディング、テクスチャサンプリング/ラッピング設定、ユニフォーム...?)
  • 関連するサンプリング/ラッピング設定を持つ(複数の)テクスチャ、(複数の)シェーダープログラム、ユニフォームが関係する、より複雑なレンダリング設定VAO正しく使用するどうすればよいですか?

1
VAOは、頂点属性の場所に関するデータを保存します。また、これらの属性が含まれるVBOのIDも保存します。何かを描画するときにVBOをバインドする必要はありません。VAOを作成するときにglVertexAttribPointer()を呼び出す前にVBOをバインドする必要があります。
HolyBlackCat

回答:


18

VAOは、頂点属性の場所に関するデータを保存します。(およびそれらに関連する他のデータもあります。)それ
"VBO bindings, active shader program, texture bindings, texture sampling/wrapping settings, uniforms"は完全に無関係です。

VBOバインディングを覚えていない理由を尋ねるかもしれません。VBOをバインドして何かを描画する必要がないためglVertexAttribPointer(...)、VAO を作成するときにバインドするだけです。を呼び出すと、VAOは現在VBOがバインドされているものを記憶します。また、VAOは、これらのVBOが現在バインドされていない場合でも、描画時にこれらのVBOから属性を取得します。


また、VAOとVBOは少し異なる方法で使用する必要があります。

これは機能しません

Generate VAO
BindVAO
---- Specify vertex attributes
---- Generate VBO's
---- BindVBO's
-------- Buffer vertex data in VBO's
---- Unbind VBO's
Unbind VAO

VBOをバインドして属性の場所を指定する必要があるためです。

そのため、次のようにする必要があります。

Generate VAO
BindVAO
Generate VBO's
BindVBO's
Specify vertex attributes

VBOのデータはいつでも変更できますが、事前にバインドする必要があります。

描画は次のようになります。

Bind VAO
Draw


お気づきかもしれませんがunbind、リストから通話を削除しました。それらはほとんど完全に役に立たず、プログラムを少し遅くするので、それらを呼び出す理由はありません。


9
「だから彼らに電話する理由はない」誤って変更しないようにします。特に、サードパーティのライブラリを使用する場合の問題。
ラチェットフリーク

すばらしい答えをありがとう!つまり、VAOは頂点属性の場所のみを保存します。VAOは属性を見つけるバッファを知っているため、VAOをバインドするときにVBOはリバウンドされません。他のすべての状態は、グローバルOpenGL状態に含まれます。
ジェレヴァンキャンペン

@JellevanCampenうん、正しい。参考までに、属性のオフ/オン状態(gl{Enable|Disable}VertexAttribArray())、そのデフォルト値(glVertexAttrib*())、インスタンス化モード(glVertexAttribDivisor())、およびおそらく他の何かも保存します。
HolyBlackCat

@HolyBlackCatデフォルト状態(glVertexAttrib())がVAO状態の一部であると確信していますか?OpenGL wikiは、そうでないと主張しており、コンテキスト状態であると述べています。
rdb

@ndbいいえ、わかりません。それらがVAO状態の一部であると予想しましたが、チェックしませんでした。
HolyBlackCat

4

頂点バインディングとインデックスバッファーバインディングのみを格納します

これは、すべてのパラメーターにglVertexAttribPointer加えて、呼び出し時にVertex_Array_bufferにバインドされたバッファーglVertexAttribPointerと、バインドされたElement_Array_bufferになります。

制服は現在のプログラムの一部です。

それ以外はすべてグローバルな状態です。

疑わしい場合は、使用しているバージョンの仕様の状態テーブルを確認できます。


答えもありがとう!これは私のために物事をクリアします。
ジェレヴァンキャンペン

4

簡単ですが効果的な説明があります。基本的に、バッファオブジェクトには、生のデータの単なるビットとして解釈できる情報がありますが、それ自体では何の意味もありません。

i.e float vbo[]={1.0,2.0,34.0...}

OpenGLが機能するように設計された方法は、さまざまなシェーダーに渡すデータがシェーダーにどのように見えるかを定義する必要があるということです。

そのデータをどのように読み取るか、どの形式であるか、どのように処理するか、どのように使用するか、この情報のすべてをVAOに保存することも定義する必要があります。

たとえば、このような配列に格納されているデータを宣言できます float vbo = {11.0,2.0,3.0,4.0}

この時点で次に必要なのは、VAOのVBOからのデータをどのように解釈するかであり、その意味は次のとおりです。

VAOは、頂点ごとに2つの浮動小数点数を読み取るように設定できます(これにより、2次元x、yの2つのベクトルになります)。または、vaoに4次元の1つのベクトル、つまりx、y、z、w

ただし、そのデータの他の属性も定義され、データ形式などのVAOに格納されます(フロートの配列を宣言したにもかかわらず、整数として読み込むようにシェーダーに指示できます。もちろん、システムは生データをフロートから整数へのプロセスと、そのような状況で何をすべきか独自のルールのセットがあります)

基本的にVBOはデータであり、VAOはそのデータの解釈方法を格納します。シェーダーとOpenGLサーバーは非常にノスタルジーに設計されており、処理方法と処理方法と場所を決定する前にすべてを知る必要があるためですそれを置く

もちろん、実際にはノージーではなく、最も効率的かつ迅速な処理を得るために、データをグラフィックサーバーメモリに保存する必要があるため、実際には最も効率的であるように見えます(これを行う必要がないと判断しない限り)データはそのような方法で処理されず、頻繁にアクセスされない他の情報に使用されます)、したがって、データの処理方法と処理方法の詳細がVAOに格納される必要がある理由VAOはヘッダーのようなもので、VBOはヘッダーが使用および定義する純粋な生データのようなものです(この場合、シェーダー頂点属性に渡されます)たとえば、次のような多くのVAOに使用および再利用してバインドできます。

あなたができることは、1つのバッファオブジェクトをVAO1にバインドし、同じバッファオブジェクトをVAO2にバインドし、それぞれが異なる解釈をするので、シェーダがデータを処理する場所がバインドすると、同じ生データがframbuffer(ウィンドウにピクセルを描画)とは異なる方法で処理され、VAOでの使用の定義方法に基づいて同じデータの異なる表示が行われます


これがベストアンサーです!
-CodingMadeEasy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.