6

サンプルコード:

1. glGenBuffers(1, &VboId);
2. glBindBuffer(GL_ARRAY_BUFFER, VboId);
3. glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
4. glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

そのため、一般的な VBO ハンドルを生成し、「GL_ARRAY_BUFFER」を使用してバインドします。バインディングには2つの目的があるようです:

  1. 経由で GPU にデータをコピーする前に、バッファをバインドする必要があります。glBufferData
  2. 属性を追加する前に、バッファをバインドする必要があります。glVertexAttribPointer

そして、VBOをバインドする必要があるのは2回だけだと思います。私の質問は、ターゲット (GL_ARRAY_BUFFER、GL_ELEMENT_ARRAY_BUFFER、GL_PIXEL_PACK_BUFFER、または GL_PIXEL_UNPACK_BUFFER) が 2 行目と 3 行目で異なるシナリオはありますか? それとも、4 行目の前に別のターゲットに再バインドしますか?

複数のバッファ ターゲットを 1 つの VBO にバインドできますか?

4

1 に答える 1

11

ターゲットをバッファオブジェクトにバインドしません。ターゲットは、(バッファオブジェクトなどの)ものをバインドできるOpenGLコンテキスト内の場所です。したがって、バッファオブジェクトをターゲットにバインドしますが、その逆ではありません。

バッファオブジェクト(VBOのようなものはありません。単にバッファオブジェクトがあります)は、OpenGLドライバが所有するフォーマットされていない線形のメモリ配列です。GL_ARRAY_BUFFERバッファを関数の1つにバインドして呼び出すことにより、頂点配列データのソースとして使用できますgl*Pointer。これらの関数は、現在にバインドされているバッファでのみGL_ARRAY_BUFFER機能します。GL_ELEMENT_ARRAY_BUFFERそれらを関数の1つにバインドして呼び出すことにより、インデックスデータのソースとして使用できますglDrawElements

バッファオブジェクトの内容(、、、など)を変更するために使用される関数はglBufferDataすべてglMapBufferglBufferSubData操作の対象となるターゲットを具体的に取得します。そのため、現在バインドglBufferData(GL_ARRAY_BUFFER, ...)されているバッファも同様GL_ARRAY_BUFFERです。

したがって、バッファオブジェクトに影響を与える関数には、コンテンツを変更する関数と、操作でそれらを使用する関数の2種類があります。後者はソースに固有です。glVertexAttribPointer 常に現在バインドされているバッファを使用しGL_ARRAY_BUFFERます。別のターゲットを使用させることはできません。同様に、glReadPixels常ににバインドされたバッファを使用しGL_PIXEL_PACK_BUFFERます。などなど。関数がバッファオブジェクトを処理するが、ターゲットをパラメータとして受け取らない場合、そのドキュメントには、バッファを検索するターゲットが記載されています。

注:頂点配列はちょっと奇妙です。頂点属性とバッファオブジェクトの間の関連付けは、を呼び出すことによって行われglVertexAttribPointerます。この関数は、現在GL_ARRAY_BUFFERにバインドされているバッファーオブジェクトを使用して、その属性に適切なデータを設定します。「現在バインドされている」とは、この関数が呼び出されたときにバインドされていることを意味します。したがって、この関数を呼び出した直後にを呼び出すことができ、レンダリングに行ったときに何が起こるかについては何もglBindBuffer(GL_ARRAY_BUFFER, 0)変わりません。うまくレンダリングされます。

このようにして、属性ごとに異なるバッファオブジェクトを使用できます。glVertexAttribPointer情報は、その特定の属性の別の呼び出しで変更するまで保持されます。

于 2012-01-01T03:32:55.643 に答える