web-dev-qa-db-ja.com

float []ではなくFloatBufferを使用する理由

私はAndroidコードでしばらくFloatBuffersを使用しています(いくつかのopenglesチュートリアルからコピーしたものです)が、この構成が何であり、なぜ必要なのか正確に理解できません。

たとえば、このコード(または類似のコード)は、多くの人のコードとAndroidチュートリアルにあります:

float[] vertices = ...some array...

ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); 
vbb.order(ByteOrder.nativeOrder());    // use the device hardware's native byte order
FloatBuffer fb = vbb.asFloatBuffer();  // create a floating point buffer from the ByteBuffer
fb.put(vertices);    // add the coordinates to the FloatBuffer
fb.position(0);      // set the buffer to read the first coordinate

これは、私が知る限り、浮動小数点数の配列の単なるラッパーのようなものでは、非常に冗長で厄介なようです。

質問:

  • 他の種類のコレクションまたは浮動小数点の単純な配列とは対照的に、このタイプのクラス(ByteBuffer、FloatBuffer)の正当化は何ですか?

  • FloatBufferに変換する前にByteBufferを作成する背後にある考えは何ですか?

46
Tim

主な理由はパフォーマンスです。ByteBuffersと他のNIOクラスは、ネイティブコードとのインターフェース時に(通常、一時バッファーにデータをコピーする必要を回避することにより)高速化された操作を可能にします。

これは、たとえば多くのOpenGLレンダリング呼び出しを行う場合には非常に重要です。

最初にByteBufferを作成する理由は、allocateDirect呼び出しを使用してdirectバイトバッファーを作成することです。これにより、高速化された操作のメリットが得られます。次に、これから同じメモリを共有するFloatBufferを作成します。 FloatBuffer自体には何らかの理由でallocateDirectメソッドがないため、ByteBufferを経由する必要があります。

42
mikera

AndroidではJava=でコーディングを行っていますが、OpenGL ESの基礎となる実装は実際にはCで記述されています。OpenGLにデータを渡す前に、データを変換してフォームに変換する必要がありますJavaおよびネイティブシステムはそれらのバイトを同じ順序で格納しない可能性があるため、特別な一連のバッファクラスを使用して、データを保持するのに十分な大きさのByteBufferを作成し、それを通知します。ネイティブのバイトオーダーを使用してデータを格納します。次に、それをFloatBufferに変換して、浮動小数点データを保持できるようにします。最後に、配列をバッファーにコピーします。

13
Anchal