5

私は現在、LWJGLを使用してJava1.6で記述された2DトップダウンRPGに取り組んでいます。ゲームにVBOの使用を実装しましたが、現在は2つを維持しています。1つは頂点データ用で、もう1つはテクスチャ座標用です。

オブジェクトを更新するための本当に論理的な方法がまだないことを除いて、すべて正常に機能しています。例として、特定のタイルにテクスチャを変更させたい場合(テクスチャシートの別の領域を表示するためにVBO内のテクスチャ座標を変更する)、対応するテクスチャ座標のみを変更する方法がわかりません。この単一のタイル。今考えられるのは、ループごとに必要なすべてのデータでバッファーをいっぱいにし、フレームごとにglBufferDataでアップロードすることだけです。それは機能しますが、それを行うための最良の方法ではないようです(またはそうですか?)。

ここで、新しいメモリを割り当てず、変更するように指示した部分のみを変更するglBufferSubDataコマンドがあります。問題は、変更する必要のある領域(オフセット)を追跡する方法がわからないことです。LWJGLはglBufferSubData(target、offset、data);を提供します。コマンド。これは、バッファの開始のみが機能する必要があります。オフセットはインデックスのようなものですか?

したがって、最初にこれらのバッファをVBOにアップロードしてから、2番目のfloat[]の2番目の値を変更したい場合:

FloatBuffer vertexData = BufferUtils.createFloatBuffer(amountOfVertices * vertexSize);
vertexData.put(new float[]{100, 100, 300, 100, 300, 300, 100, 300});
vertexData.put(new float[]{400, 100, 600, 100, 600, 300, 400, 300});
vertexData.flip();

新しいデータを生成し、それを小さなFloatBuffer内に配置し、glBufferSubData(GL_VERTEX_ARRAY、10、newFloatBuffer);でアップロードします。10は、10番目の古い値から値を変更したいためです。

そうですか?それを行うためのより良い方法はありますか?また、フレームごとにデータ全体を再アップロードしても大丈夫ですか?

4

1 に答える 1

8

LWJGL glBufferSubData()は、任意のデータを任意のバッファー位置に書き込むことができるはずなので、オフセットをバイトカウントとして想定しています。インデックスでfloatを更新する場合、java floatは非常に一般的な4バイトをi使用するため、オフセットはになります。i * 4残りのバッファの内容はすべて書き込まれるため、ターゲットバッファには少なくとも
(i + floatBuffer.remaining()) * 4バイトの容量が必要です。正しい準備については、Buffersのflip()メソッドを参照するか、position(int)をlimit(int)と一緒に使用して、書き込む残りのコンテンツを指定してください。

この更新戦略は、一時的なFloatBuffersを使用してglBufferSubData()を何度も呼び出さない限り、問題ありません。また、スワッピング(ピンポン)用に同じサイズの2番目のターゲットバッファーを用意することもできます。これMapBuffer()は、もう1つが使用されている間に、全体的な更新に使用してマップできます。

クライアント側で完全なFloatBufferを保持し、何度もglBufferData()呼び出すのではなく、を使用して一度にアップロードしたいと思います。glBufferSubData()しかし、いくつかの数字を知らなければ、見分けるのは難しいです。

于 2012-08-14T20:43:26.063 に答える