38

次のように、OpenGL で頂点バッファーを設定しています。

int vboVertexHandle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
glBufferData(GL_ARRAY_BUFFER, vertexData, GL_DYNAMIC_DRAW);

後で、頂点を「vertexData」に追加または削除したい場合、これを行う適切な方法は何ですか? それは可能ですか?GPUに再送信せずに配列を直接変更することはできないと思います。

vertexData 配列を変更する場合は、これを再度呼び出します。

glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
glBufferData(GL_ARRAY_BUFFER, vertexData, GL_DYNAMIC_DRAW);

...古いバッファを新しいデータで上書きしますか? それとも、古いものも削除する必要がありますか? より良い方法はありますか?

4

3 に答える 3

40

OpenGL バッファ オブジェクトのサイズは、 を呼び出すときに設定されますglBufferData。つまり、OpenGL は、glBufferData(OP にはリストされていない) の 2 番目の引数で指定した量のメモリを割り当てます。実際、たとえばglBufferData( GL_ARRAY_BUFFER, bufferSize, NULL, GL_DYNAMIC_DRAW );OpenGLを呼び出すと、初期化されていないデータbufferSizeのバイトのバッファが作成されます。

glBufferSubDataglMapBuffer、またはデータを渡すためのその他のルーチンを使用して、任意の量のデータ (バッファーのサイズまで) をロードできます。glBufferDataバッファのサイズを変更する唯一の方法は、同じバッファ ID (から返される値) の新しいサイズでを呼び出すことglGenBuffersです。

つまり、バッファ内のデータのサブセットをいつでも使用できます (これは頂点の削除に似ています)。 を使用してレンダリングするとglDrawElements、バッファ内の要素にランダムにアクセスできます。バッファーに頂点を追加するには、より大きなバッファーを割り当てる必要があり、バッファー内のすべてのデータを再読み込みする必要があります。

于 2013-04-05T00:09:14.687 に答える
7

http://www.opengl.org/wiki/GLAPI/glBufferData

glBufferData は、現在ターゲットにバインドされているバッファー オブジェクトの新しいデータ ストアを作成します。既存のデータ ストアはすべて削除されます。

これは、への呼び出しがglBufferDataデータを「再割り当て」し、バッファが新しいサイズになることを説明しています。古いデータはすべて失われます。バッファの一部だけに書き込みたい場合は、glBufferSubData代わりに使用してください。

http://www.opengl.org/wiki/GLAPI/glBufferSubData

編集:glBufferSubDataデータを置き換えたい場合のみです。代わりにバッファのサイズを変更するには、 を呼び出す必要がありますglBufferData

また、最初にバッファを破棄して新しいバッファを生成する必要はありません。GLuint は、OpenGL の一種の「ポインタ」にすぎないことを忘れないでください。これは実際のストレージではないため、同じ「ポインター」を再利用してもまったく問題ありません (もちろん、まだ削除していない場合)。

于 2013-04-04T23:03:57.137 に答える