2017-01-26 13 views
1

私は巨大なポイントクラウド(〜150M)をレンダリングしようとしていますが、OpenGLはその一部(〜52M)しかレンダリングしません。小さなデータセット(< 40M)をレンダリングすると、すべて正常に動作します。私は単一のVBOを使用しています。複数のVBOを使用すると、ポイントがレンダリングされますが、レンダリングは非常に遅くなります。私の要素のサイズは44バイトで、GPUには3GBのメモリがあります。これは約70Mポイントには十分であるはずですが、私は複数のVBOで100Mポイントをレンダリングすることができます。 私が気づいていないVBOごとにOpenGL固有の制限はありますか?glDrawArraysはポイントクラウド全体をレンダリングしません

それはあなたのシステムの一部のように見えます
glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glBufferData(GL_ARRAY_BUFFER, cloud.size() * sizeof(Point), cloud.data(), GL_STATIC_DRAW); 
// lot of other code 
glDrawArrays(GL_POINTS, 0, cloud.size()); 
+0

フレームごとにglBufferDataを呼び出すのではないですか? –

+0

'glBufferData()'がエラー状態を 'GL_OUT_OF_MEMORY'に設定していないことを確認していますか? – genpfault

+0

私はそうではありません。これは疑似コードです。実際には、データが変更されたときだけバッファを更新するためにダーティフラグを使用します。 – mitjap

答えて

6

は、このように148M*44bytesオーバーフローを渡して、バッファのサイズを格納する32ビットの符号なし整数を使用し、約54.9M50.4Mあなたメガバイトはバイナリまたは小数であるかどうかに依存して変換されます。まずOpenGLバインディングライブラリをチェックして、それが正しく宣言したプロトタイプが64ビットタイプを使用していることを確認します。そうであれば、バグはOpenGLドライバになければなりません。 glBufferSubDataglBufferStorage、または4ギガバイトの制限を回避する可能性があるglMapBufferRangeでバッファを、メモリマップ:あなたは、他の利用可能な機能のいずれかを使用してみてバッファに4GBのデータよりも多くを転送する

VAOを1つ使用し、複数のバッファー間でデータを分割することも考慮する必要があります。恐らく、あなたのPointは、位置、色などの異なる属性で構成されています。それぞれを別々のバッファに入れて、1つのVAOと1回の描画呼び出しを使用することができます。また、使用する属性のタイプを最適化することもできます(たとえば、短絡やバイトが発生する浮動小数点数を使用しないなど)。構造のレイアウト(フィールド間に不要な埋め込みがないことを確認してください)。

+0

'glBufferSubData'を使用するには、まず' glBufferData'を必要なサイズで呼び出す必要があります(これは 'GLsizei ')と使い方をして、' glBufferSubData'を使ってその部分を更新してください。私はそれを正しく理解していますか? 'glBufferStorage'については、私はこれが私の問題を解決すると思うが、私はOpenGL 4.4を利用できない。 2^32バイトのデータごとに1つのVBOを使用する必要があると思います。ありがとうございました! – mitjap

+1

まあ、 'glBufferSubData'はバッファのメモリがすでに割り当てられていると期待しています。これは' glBufferStorage'のためのものです。彼らが使用しているタイプで分かるように、実際にはもっと新しい機能です。 'glBufferStorage'を導入した' GL_ARB_buffer_storage'拡張がサポートされているかどうかはまだ確認できます。 – ybungalobill

+0

この回答は正しくありません。 'glBufferData'は明示的に' ptrbits'幅に指定された 'size'パラメータに対して' GLsizeiptr'型を使います。ここで 'ptrbits'はクライアントアドレス空間のアドレスに使われるビット数です。 – derhass

0

実際にはメモリが問題だとは思わないが、あなたのプログラムはあまりにも多くの描画呼び出しをすると言っているだろう。 glDrawArraysInstanced()を試してみてください。そのためには、頂点シェーダのすべてのインスタンスに対して新しい位置を提供する必要があります。おそらくそれが問題を解決します:D。 詳細を教えていただけない場合は申し訳ありませんが、OpenGLのスキルはちょっと鈍いですが、私は早く回復するつもりです。

関連する問題