2

Java OpenGL (JOGL) アプリケーションでのメモリ割り当てとガベージ コレクションを最小限に抑える方法を見つけようとしています。学習課題として、いくつかの C/C++/C# OpenGL プロジェクトを Java に移植しています。私が直面していることの 1 つは、Java のポインターの欠如と、アプリケーションの実行時のオブジェクトの割り当てとそれらの GC です。C/C++/C# では、参照を渡すことで追加のメモリやオブジェクトを割り当てることなく、アプリケーションを起動して簡単に実行できますが、Java では設計に互換性がないようです。

これらの設計が進化するにつれて、より高いレベルのオブジェクトが使用されています。C では、これらはベクトルと行列の構造体であり、C++/C# クラスではそうでした。これらはすべて、本質的にメモリ内のバイト配列に要約されます。次に、アプリケーション内で OpenGL 呼び出しまたはオブジェクト配列のために何らかの方法で float[] にキャストされるため、演算子のオーバーロード、加算と乗算、またはプロパティ アクセスなどのオブジェクト ベースの操作を使用できます。OpenGL を扱っている人は、おそらく私が何をしているかを知っているでしょう。このようにして、ロード時にすべてを割り当て、データを単純に渡します。

Java がいくつかのループを引き起こしました。データを前後にキャストできないように見えるため、大量のデータを作成し続け、GC が機能します。これは、リソースの消費とクリーンアップ、およびアプリケーション実行中の顕著なカクつきによって顕著になります。ジオメトリ データの VectorXf 配列に加えて FloatBuffer を作成し、その FloatBuffer を OpenGL に渡すことで、この問題の一部を軽減しました。しかし、Vector データを更新する必要がある場合は、データを float バッファーに再コピーする必要があります。これは、2 倍のデータを格納していて、floatbuffer フィルのオーバーヘッドが発生していることも意味します。

他の人がこれらの問題にどのように対処しているかを聞きたいです。組み込みの機能のために高次のオブジェクトを保持したいのですが、データを OpenGL に渡すことができます。私のデザインは単に Java と互換性がないのでしょうか? 排他的に FloatBuffers に移動する必要がありますか? オブジェクト作成のペナルティなしで、コンポーネント データを高次オブジェクトに渡すにはどうすればよいでしょうか。非常に多くの OpenGL アプリケーションが存在するため、float[] と Object[] に同じバッファを使用するか、オブジェクト データに連続したブロックを割り当てて OpenGL への参照を渡すという「魔法」があると思われます。

4

2 に答える 2

3

OpenGL データを管理する原動力は、ジオメトリやテクスチャを含むメモリに責任を持ちたくないということです。float[]FloatBuffers または FloatBuffersの使用は、ジオメトリ データを OpenGL バッファ オブジェクトに転送する目的でのみ使用する必要があります。OpenGL バッファーを作成してデータをそこにコピーしたら、JVM にコピーを保持する必要はなくなります。事実上すべての最新のハードウェアでは、データがビデオ カード自体に保持され、完全に JVM の外部になります。

理想的には、ほとんどのジオメトリが静的である場合、起動時に OpenGL バッファにコピーでき、再度直接管理する必要はありません。多くの動的なジオメトリを扱っている場合でも、データを OpenGL ドライバーとやり取りする必要があります。この場合、おそらく、変化するジオメトリを生成または検出するコードとドライバーの間でデータを移動するためのフェリーとして機能できる FloatBuffers のプールを維持する必要があります。OpenGL は、JVM 内のデータの内部表現とは異なる特定の形式のデータを想定しているため、FloatBuffer は避けられませんが、少なくとも、すべてのセットに対して個別の FloatBuffer を保持する必要はありません。あなたが持っているデータ。

于 2013-12-10T23:37:05.397 に答える
0

私の経験: データの転送のみに FloatBuffers を使用していましたが、メッシュを変更するたびに Vec 配列を FloatBuffers に変換する必要があったため、これは実際には動的メッシュのパフォーマンスを低下させることがわかりました。今では vec 配列を取り除き、メッシュ クラスを介して FloatBuffers のみを永続的に使用しています。これらを処理するのはエレガントではありませんが、はるかに高速です。したがって、すべてのジオメトリ データを FloatBuffers で保持および更新することをお勧めします。

于 2016-12-27T23:08:47.083 に答える