3

私は現在ボクセルエンジン(たとえばMinecraftなど)を構築しており、openglを使用しています。

エンジンの現在の設計は次のようになります。

クラスマップ->チャンクの2D配列が含まれています(std::vectorのstd::vector)

クラスチャンク->ブロックの3D配列が含まれています(std :: vectorも使用)

class Block->には、ブロックの頂点が含まれています。(立方体、12個の三角形から構築);

私がやりたいのは、すべてのチャンクに、チャンク内のすべてのブロックを描画するdraw()関数を持たせることです。glGenBuffers()を使用してチャンクごとにバッファーを作成すると思いました。私が読んだチュートリアルから、最初にglVertexArrayを使用して頂点配列を作成し、それをバインドするよりも、ターゲットGL_ARRAY_BUFFERを使用してバッファーをバインドし、データを入力する必要があります。

これまで、glGenBuffers()を使用してチャンク内に作成されたバッファーを使用して、複数のブロックを含む単一のチャンクをレンダリングすることができましたが、メイン関数では、チャンク内でdraw()関数を呼び出すよりも、glVertexArrayを作成してバインドします。 glDrawArrays()を使用して、チャンクのバッファと描画をバインドします。

私の質問は、チャンクごとにVBOを作成するのは正しいですか?チャンクごとにglVertexArrayも作成する必要がありますか?または、すべてのチャンクに1つを使用し、毎回別のVBOをバインドする必要がありますか?

チュートリアルとopenglwikiを通じてVAOとVBOについてもっと勉強しようとしましたが、これまでのところ、それがどのように機能し、どのように適切に使用されるべきかを完全には理解していませんでした。

4

2 に答える 2

2

早すぎることを考えすぎている可能性があると思います。マップがチャンクに分割されているのはなぜですか? すべてのマップがメモリ内にないページングが予想されますか? マップ全体が GPU メモリに収まる場合は、マップごとに 1 つのバッファーを使用し、チャンクは必要ありません。最初にレンダリングをそのようにきれいにします。

その後、可視部分のみを描画するなどの最適化を考えることができます。または、より低いディテールで離れた部分を描画します。その時点で、GPU バッファーを保持する方法、いつ更新または破棄するかを決定します。それは単なるキャッシングの問題です。簡単ではありませんが、キャッシングの問題です。

より実用的には、チャンクで編成する場合、はい、チャンクごとに 1 つのバッファーです。1 つの頂点と 1 つのインデックス バッファー。1枚ずつ描きます。バッファの切り替えは、描画にとって悪いことではありません。しかし、バッファをロードするときは、部分ではなく全体をロードする必要があります。約 65k の頂点の下のバッファーを気にしないでください。

ただし、最初のステップとして、CPU メモリから描画します。物事がどのように並んでいるかをよりよく感じたら、キャッシングが続きます。早い段階で GPU 構造を設計に混在させないでください。また、ピッキングや AI などの CPU 構造も必要になります。1 つの「グラウンド トゥルース」データ セットが必要です。このデータ セットには、さまざまなニーズに合わせてさまざまなパーティションと表現が含まれます。

于 2014-10-05T13:26:11.517 に答える