2017-01-30 4 views
3

私は、レンダリングデータの1つのブロックであることを意味する、minecraftのようなチャンクシステムを持っています。プレイヤーが移動して別のチャンクに入ると、新しいものがロードされている間に範囲外のチャンクがアンロードされているので、レンダリングデータを表示する前に別のスレッドでレンダリングデータを計算する必要があります。データはすでにそれがこのVBOをスレッド間で同期させるための最良の方法

メイン/スレッドがデータ生成スレッド

|   Request Chunk   | 
    | -------------------------------> | 
    |         | 
    |         | Generating render data (FloatBuffer) 
    |         | 
    |         . 
    |         . 
    |         . 
    |  Get Ready Chunks   | 
    | <------------------------------- | 
    |         | 
    | Upload Data      | 
    |         | 
    | Render       | 
    |         | 

「要求チャンク」とは、「レディチャンクを取得します」そう同期されていないレンダーのように見えるディスクからロードされると仮定すると、

レンダリングスレッドは実際には独立して動作します。

この問題は、一度にたくさんのチャンクをアップロードすると、フレームドロップが発生しますが、アップロードするまでにどれくらい時間がかかるかを計算することは確実にできません。フレームごとに1つだけ増やしても、スピードをあげることはできませんが、それはうまくいきます(現時点では実装されています)。

私は1つのGLコンテキストしか使用していないので、今はメインスレッドでのみVBOを作成できます。

他のスレッドでVBOを作成してメインスレッドに渡すなど、これを解決する方法はありますか?

答えて

-1

残念ながら、OpenGLはその性質上、シングルスレッドです。そのため、OpenGL呼び出しは単一のスレッドからしか実行できません。チャンクを別のスレッドのバックグラウンドでロードすることができます(I/Oをブロックする必要があります)。最終的にグラフィックカードにアップロードするには、メインのOpenGLスレッドから行う必要があります。

あなたができることの1つはglBufferSubData()です。一度にすべてではなく、ジオメトリーのまとまりを個別にアップロードすることができます。ヒッチを完全に取り除くことはできないと思いますので、チャンクをロードしている間にフレームごとに一定量のジオメトリを転送しようとする可能性があります。したがって、少なくとも複数のプロセスにわたってプロセスを広げることができますフレーム。

+1

実際には、[here](http://stackoverflow.com/questions/8912986/opengl-vbo-within-multiple-threads)などの共有コンテキストを使用して、スレッド間でバッファを作成/共有することができます。ここに](http://stackoverflow.com/questions/7495109/multiple-context-with-different-version)と[ここ](http://stackoverflow.com/questions/8116305/opengl-secondary-thread-for-ロードリソース/ 8126219#8126219)。 – BDL

+0

まあ、私が知らなかったことがあります。私はこれを調べます。 – Bartvbl

+0

@BDL:私が読んでいるもの(あなたがリンクしたページ以外のページでも)から、複数のコンテキストは、ほとんどのドライバによってシリアルOpenGLコールに変換されます。したがって、OpenGLコンテキストスイッチのパフォーマンスペナルティを犠牲にして、OpenGLにリソースを自由にアップロードできることを除けば、複数のコンテキストを使用するもう1つの理由はありますか?私には、複数フレームにわたるリソースローディングのストリーミングとスミアリングが優れているようです。 – Bartvbl

2

正に、1フレームあたりのアップロード数を制限するあなたのアプローチはおそらく行く方法です。私が取り組んできた商用ゲームでさえ、ストリーミング・ヒッチを避けるためにこれを行います。他のスレッドで可能なすべての作業を行い、次にレンダリングスレッドでのサブミッション自体のみを行います。

これを高速化するには、実際にチャンクごとにアップロードする必要があるデータ量を減らす方法があります。たとえば、自分のボクセルレンダラーでは、チャンクサイズは64x64x64です。つまり、コンポーネントには1つのコンポーネントにつき8ビットしか必要ありません(余分なビット数を必要とします)。そして、ピクセルシェーダの微分からそれらを計算することによって法線を提出する必要がなくなります。等々。

関連する問題