为啥使用 FloatBuffer 而不是 float[]?

Posted

技术标签:

【中文标题】为啥使用 FloatBuffer 而不是 float[]?【英文标题】:Why FloatBuffer instead of float[]?为什么使用 FloatBuffer 而不是 float[]? 【发布时间】:2012-05-28 15:45:29 【问题描述】:

我在我的 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)的理由是什么?

在将 ByteBuffer 转换为 FloatBuffer 之前创建它的想法是什么?

【问题讨论】:

【参考方案1】:

主要原因是性能:ByteBuffers 和其他 NIO 类在与本机代码交互时启用加速操作(通常通过避免将数据复制到临时缓冲区的需要)。

例如,如果您正在执行大量 OpenGL 渲染调用,这一点非常重要。

首先创建 ByteBuffer 的原因是您想使用 allocateDirect 调用来创建 direct 字节缓冲区,这得益于加速操作。然后,您可以从中创建一个共享相同内存的 FloatBuffer。由于某种原因,FloatBuffer 本身没有 allocateDirect 方法,这就是您必须通过 ByteBuffer 的原因。

【讨论】:

【参考方案2】:

我们在 Android 上使用 Java 编写代码,但 OpenGL ES 的底层实现实际上是用 C 编写的。在我们将数据传递给 OpenGL 之前,我们需要将其转换为它可以理解的形式。 Java 和本机系统可能不会以相同的顺序存储它们的字节,因此我们使用一组特殊的缓冲区类并创建一个足够大的 ByteBuffer 来保存我们的数据,并告诉它使用本机字节顺序存储数据。然后我们将其转换为 FloatBuffer,以便我们可以使用它来保存浮点数据。最后,我们将数组复制到缓冲区中。

【讨论】:

以上是关于为啥使用 FloatBuffer 而不是 float[]?的主要内容,如果未能解决你的问题,请参考以下文章

Android OpenGL动态大小FloatBuffer?

opengl中的Floatbuffer和IntBuffer与java中数据的存储方式不同的解决方法

返回随机数而不是具体的 5.1

为啥我总是要使用 ||而不是 |和 && 而不是 &?

为啥使用常量而不是枚举?

为啥 Kivy 使用浮点数而不是整数?