1

シーンをレンダリングするために、VBO で glDrawElements 呼び出しを使用しています。シーンは、頂点とテクスチャ座標を持つ布です。この例では、旗をレンダリングしています。

私のシーンでは、頂点は動的です。つまり、フレームごとに VBO に書き込む必要があります。私の処理の多くは CUDA を使用して GPU で行われるため、常に CPU メモリを GPU メモリにマッピングしています。一方、テクスチャ座標は静的です。glDrawElements でレンダリングするには (私が理解しているように)、頂点 VBO でテクスチャ座標をインターリーブしてから、glTexCoordPointer() と glEnableClientState() を呼び出すだけです。CPU <--> GPU メモリ マッピングを行うときに、すべてのテクスチャ座標を一緒に描画する必要があるため、これは最適ではありません。

vbo のテクスチャ データに触れずに vbo の頂点データを更新できるように vbo を配置する方法はありますか? 以下は、レンダリング用のコードです。現在、インデックス配列、頂点配列、テクスチャ配列の 3 つの配列が埋められています。

以下のコードでは、indexVbo がインデックス配列にマップされ、vbo が頂点配列にマップされています。ここで、テクスチャを組み込む必要があります。洞察や提案をいただければ幸いです。

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, flagTexId);

glPushMatrix();
    glColor3f(1.0, 1.0, 1.0);

    glVertexPointer(4, GL_FLOAT, 0, 0);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVbo);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    // Render flag mesh
    glDrawElements(GL_TRIANGLES, numTriangles * 3, GL_UNSIGNED_INT, 0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix(); 

glDisable(GL_TEXTURE_2D);
4

1 に答える 1

3

両方の頂点属性に対して別々の VBO を保持できます。そうすれば、tex-coord を静的としてマークし、もう一方を動的としてマークすることもできます。

これが実際に速いかどうかは、ドライバー、メモリの設定など、多くの要因に依存します。データの一部を静的メモリに置くことの利点は、キャッシュ ラインに頂点全体を配置することの利点を上回る場合があります (インターリーブする場合)。しかし、そうではないかもしれません。ターゲットシステムでベンチマークを行ってください。

IMO、属性を異なる VBO に分割するための良い議論は、それがデータの最も「自然な」表現であるということです。しかし、それは個人の好みと、それがプログラミングに影響を与えるかどうかによると思います:-)

ところで、小さなバグがあるようです:gl*Pointer呼び出しの前に正しい VBO をバインドする必要があります (また、頂点に単一の VBO を使用している場合、オフセットとストライドは正しくありません)。これは、個別の VBO をバインドする方法でもあります。gl*Pointer呼び出しの前に正しいものを選択するだけです。

glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex);
glVertexPointer(4, GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, vbo_texcoord);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
于 2011-04-13T08:36:33.173 に答える