1. ホーム
  2. opengl

[解決済み] 頂点配列オブジェクトとは?

2022-07-08 10:41:17

質問

このチュートリアルを見て、OpenGLを学び始めたところです。 http://openglbook.com/the-book/

第2章の三角形を描くところまで来て、VAOs(この頭文字でOK?)以外は理解できました。チュートリアルにはこのようなコードがあります。

glGenVertexArrays(1, &VaoId);
glBindVertexArray(VaoId);

このコードが必要であることは理解できますが、何をするものなのかが全くわかりません。VaoIdをこれ以降使用することはありませんが(破棄する場合を除く)、このコードはVaoIdなしでは機能しません。これは、バインドする必要があるからだと思いますが、なぜなのかわかりません。この正確なコードは、すべてのOpenGLプログラムの一部である必要があるだけなのでしょうか?チュートリアルでは、VAOを次のように説明しています。

頂点配列オブジェクト(またはVAO)は、頂点属性が頂点バッファオブジェクト(またはVBO)にどのように格納されるかを記述するオブジェクトです。つまり、VAOは頂点データを格納する実際のオブジェクトではなく、頂点データの記述子ということになります。頂点属性はglVertexAttribPointer関数とその姉妹関数であるglVertexAttribIPointerとglVertexAttribLPointerによって記述することができ、最初の関数については後ほど説明します。

VAOが頂点属性をどのように記述しているのか理解できないのですが。どのような方法でも記述していません。glVertexAttribPointerから情報を取得しているのでしょうか?これなんでしょうね。VAOは単にglVertexAttribPointerからの情報を受け取る先なのでしょうか?

余談ですが、私のやっているチュートリアルは問題ないでしょうか?何か注意すべき点や、もっと良いチュートリアルがあるのでしょうか?

どのように解決するのですか?

Vertex Array Object" は、OpenGL ARB Subcommittee for Silly Names によって提供されています。

ジオメトリ オブジェクトとして考えてください。(オブジェクトのインスタンス変数/メンバーは、頂点ポインタ、法線ポインタ、カラーポインタ、属性Nポインタ、...です。

VAO が最初にバインドされるとき、これらのメンバーを割り当てるには

glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer...;
glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer...;

といった具合になります。どの属性を有効にするか、また、供給したポインタはVAOに格納されます。

その後、VAOを再びバインドすると、それらの属性とポインタもすべて最新になります。そのため、1つの glBindVertexArray の呼び出しは、以前すべての属性を設定するために必要だったすべてのコードに相当します。これは、独自の構造体やオブジェクトを作成することなく、関数やメソッド間でジオメトリを渡すのに便利です。

(1 回のセットアップで複数回使用するのが VAO を使用する最も簡単な方法ですが、バインドして enable/pointer 呼び出しをさらに行うだけで属性を変更することも可能です。VAOは定数ではありません)

Patrick の質問に対するより多くの情報。

新しく作成された VAO のデフォルトは、空です (AFAIK) 。ジオメトリはまったくなく、頂点さえもないため、描画しようとすると OpenGL エラーが発生します。これは、"すべてをFalse/NULL/zeroに初期化する"のように、合理的にまともなことです。

必要なのは glEnableClientState を設定するだけです。VAOは各ポインタの有効/無効の状態を記憶しています。

はい、VAO は glEnableVertexAttribArrayglVertexAttrib . 旧来の頂点、法線、色、...の配列は属性配列と同じで、vertex == #0 などとなります。