web-dev-qa-db-fra.com

Pourquoi FloatBuffer au lieu de float []?

J'utilise FloatBuffers dans mon Android depuis un certain temps (copié à partir d'un didacticiel Opengles), mais je ne peux pas comprendre exactement ce qu'est cette construction et pourquoi elle est nécessaire.

Par exemple, ce code (ou similaire) que je vois dans de nombreux codes de nombreux peuples et Android tutoriels:

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

Cela semble terriblement verbeux et désordonné pour quelque chose qui, pour autant que je sache, n'est qu'un emballage sophistiqué autour d'un tableau de flotteurs.

Des questions:

  • Quelle est la justification de ce type de classe (ByteBuffer, FloatBuffer), par opposition à tout autre type de collection ou simple tableau de flottants?

  • Quelle est l'idée derrière la création d'un ByteBuffer avant de le convertir en FloatBuffer?

46
Tim

La principale raison est la performance: ByteBuffers et les autres classes NIO permettent des opérations accélérées lors de l'interfaçage avec du code natif (généralement en évitant de copier des données dans un tampon temporaire).

C'est assez important si vous faites beaucoup d'appels de rendu OpenGL par exemple.

La première raison de la création d'un ByteBuffer est que vous souhaitez utiliser l'appel allocateDirect pour créer un tampon d'octets direct, qui bénéficie des opérations accélérées. Vous créez ensuite un FloatBuffer à partir de celui-ci qui partage la même mémoire. Le FloatBuffer n'a pas lui-même de méthode allocateDirect pour une raison quelconque, c'est pourquoi vous devez passer par ByteBuffer.

42
mikera

Nous faisons notre codage en Java sur Android, mais l'implémentation sous-jacente d'OpenGL ES est en fait écrite en C. Avant de transmettre nos données à OpenGL, nous devons les convertir dans une forme qui va à comprendre. Java et le système natif peut ne pas stocker leurs octets dans le même ordre, nous utilisons donc un ensemble spécial de classes de tampon et créons un ByteBuffer assez grand pour contenir nos données, et le dire pour stocker ses données en utilisant l'ordre d'octets natif. Nous le convertissons ensuite en un FloatBuffer afin que nous puissions l'utiliser pour contenir des données à virgule flottante. Enfin, nous copions notre tableau dans le tampon.

13
Anchal