10

OpenGL と OpenGLES に関するチュートリアルを読んでいますがglVertexAttribPointer、これら 2 つの API での関数の使用について少し混乱しています。

OpenGLチュートリアルでは、この関数は最後のパラメーターとして数値オフセット (const GLVoid* へのキャスト付き) を使用し、頂点は現在の配列バッファーから直接取得されると想定しています。

glVertexAttribPointer(vs_position, 2, GL_FLOAT, GL_TRUE, 5 * sizeof(GLfloat), (const GLvoid*) (3*sizeof(GLfloat)) );

OpenGLESチュートリアルでは、最後のパラメーターは頂点を表す構造体を直接指しています。

GLFloat vertices[] = {...definition};
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);

これら2つの機能がどのように機能するか理解できません。それらはまったく異なる機能ですか?

4

2 に答える 2

26

これらは、2 つの異なる方法で使用されている同じ機能です。なぜこのように機能するのかを説明しますが、気にしないでください。それは非常に愚かで無関係な理由によるものです。

重要なのは、彼らが何をしているかです。そして、彼らが何をしているのかは、あなたが示していない何か、つまり にバインドされているものに依存しますGL_ARRAY_BUFFER

ほら、それに応じての挙動がglVertexAttribPointer 変わります。GL_ARRAY_BUFFERを呼び出したときにバインドされたバッファ オブジェクトがない場合glVertexAttribPointer、関数は最終的な値がポインタであると想定します(関数の名前が示すように: glVertexAttrib Pointer )。具体的には、クライアント所有のメモリへのポインタです。

レンダリングの段階になると、頂点属性データは以前に提供されたポインターから取得されます。したがって、2 番目の例では、標準 C スタイルで宣言されたクライアント データの配列をソース データとして使用しています。バッファ オブジェクトは関係ありません。

注: OpenGL 3.1+ のコア プロファイルでは、クライアント メモリを使用する機能が削除されました。そこでは、以下で説明するように、バッファ オブジェクトを使用する必要があります。

GL_ARRAY_BUFFERが呼び出されたときにバッファ オブジェクトがバインドされている場合glVertexAttribPointer、何か特別なことが起こります。OpenGL は、ポインター (C/C++ に関する限り、最終パラメーターが何であるか) が、実際には にバインドされたバッファーへのバイト オフセットGL_ARRAY_BUFFERであると見なします。ポインターを整数に変換し、その整数オフセットと現在バインドされているバッファー オブジェクトを格納しますGL_ARRAY_BUFFER

したがって、上記のコードは3*sizeof(GLfloat)、バイト オフセットを取得し、それをポインタに変換します。OpenGL はポインターを受け取り、それをオフセットに変換して戻し3*sizeof(GLfloat)ます。

レンダリングの段階になると、OpenGL は、以前に指定されたオフセットを使用して、以前に指定されたバッファー オブジェクトから読み取ります。

最初の例では、頂点データを GPU メモリ内のバッファー オブジェクトに配置します。2 番目の例では、CPU メモリ内の通常の C/C++ 配列に頂点データを配置します。

于 2013-03-13T09:04:16.397 に答える
1

GL仕様はこれを明確に述べています:

ケース 1: ゼロ以外の名前付きバッファ オブジェクトが GL_ARRAY_BUFFER ターゲットにバインドされ、ジェネリック頂点属性配列が指定されている場合、ポインタはバッファ オブジェクトのデータ ストアへのバイト オフセットとして扱われます。

ケース 2: 配列内の最初のジェネリック頂点属性の最初のコンポーネントへのポインターを指定します。

于 2014-02-26T18:14:03.417 に答える