1

iOS 5 のストック「回転キューブ」OpenGL の例では、次のコードがあります。

glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));

めちゃくちゃな部分は への最後の引数glVertexAttribPointerです。ドキュメントによると、最後の引数は配列へのポインターです。

しかし、このプログラムでは、まっすぐな数を使用しています。実際、BUFFER_OFFSET次のように定義されます。

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

gCubeVertexDataでは、メモリ アドレス 0 から始まる配列に依存しているのでしょうか。

だから、私は2つのことを理解していません:

  1. コードの 3 行目を次のように「修正」すると、例が機能しない(立方体が描画されない)のはなぜですか?

    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, gCubeVertexData );
    
  2. glVertexAttribPointerを呼び出す正しい方法は何ですか?

ドキュメントにあるように、最後のインデックスのメモリ ポインターを渡すことになっていると思いました。実際、ここで別のサンプルが glVertexAttribPointer を使用しています。

glVertexAttribPointer(ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(vertexStruct), &vertices[0].position);
glEnableVertexAttribArray(ATTRIB_POSITION);
glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(vertexStruct), &vertices[0].color);
glEnableVertexAttribArray(ATTRIB_COLOR);

したがって、後者の例では、直接の数値ではなく、ポインター (最後の引数) のメモリアドレスが渡されていることがわかります。

4

1 に答える 1

2

glVertexAttribPointer は、次の 2 つの方法で使用できます。

1) クライアント側の頂点配列を使用。この場合、最後の引数は配列へのポインターです。これについては正しいです。

2)ポインターとして使用されることに加えて、リンクしたドキュメントページをさらに下に読むと、次のように表示されます。

ゼロ以外の名前付きバッファ オブジェクトが GL_ARRAY_BUFFER ターゲット (glBindBuffer を参照) にバインドされ、一般的な頂点属性配列が指定されている場合、ポインタはバッファ オブジェクトのデータ ストアへのバイト オフセットとして扱われます。

これは、glVertexAttribPointer を使用して、以前に opengl (glBindBuffer/glBufferData) にアップロードしたバッファである VBO を指す場合に使用します。

明確にするために:

glBindBuffer にバインドされたアクティブなバッファーがない場合、glVertexAttribArray はポインターを受け取ります。バッファがバインドされている場合、glVertexAttribArray はバインドされたバッファへのオフセットを取得します。これは0、バッファの先頭から描画を開始する場合の値になります。

于 2012-09-06T05:33:33.147 に答える