为啥我们可以直接在ByteBuffer中分配字节而不在FloatBuffer中分配浮点数

Posted

技术标签:

【中文标题】为啥我们可以直接在ByteBuffer中分配字节而不在FloatBuffer中分配浮点数【英文标题】:Why can we directly allocate bytes in ByteBuffer but not floating Point in FloatBuffer为什么我们可以直接在ByteBuffer中分配字节而不在FloatBuffer中分配浮点数 【发布时间】:2014-12-02 08:30:13 【问题描述】:

在使用openGL(ES)的java中,我们可以像直接分配ByteBuffer一样

ByteBuffer bf ;
bf.allocateDirect();

但是在 FloatBuffer 不可用的情况下我们不能这样做,这是为什么呢?

我想知道是不是因为:

字节可在硬件级别访问(因为 OpenGL 与 delvik 不同,它在硬件之上工作)并且硬件中的寄存器(GPU 的硬件)以字节为单位,即使是浮点数也应该存储在 4 字节寄存器中,这可能不可用,所以我们不能直接分配,而是应该告诉缓冲区为给定大小的块分配内存,然后将数据放入这些块中并再次将其视为 FloatBuffer。

【问题讨论】:

【参考方案1】:

OpenGL es 是用 c 编写的。在 c 浮点数中,整数等不像 java 那样是固定大小的。 java中的浮点数是32位。现在让我们来看看 java 是如何使用 opengl 的。当您使用 java 将顶点发送到图形管道时,您实际上调用了为您完成脏工作的 c 函数。这称为 ndk,您可以在此处找到更多信息:https://developer.android.com/tools/sdk/ndk/index.html。 C 被转换为汇编代码,因此每个浮点数在每个电话上可以具有不同的字节大小,具体取决于 cpu 架构。您使用 nio 缓冲区(更多:https://docs.oracle.com/javase/7/docs/api/java/nio/Buffer.html)来确保您的浮点数组大小基于手机的 cpu 架构(本机顺序),而不是基于 jvm 固定的原始大小。最后,假设您有一个 java 浮点数的顶点数组(32 位固定大小)。你的 cpu 浮点数是 64 位的。如果您从 java 调用 opengl es 函数,您的程序将最终崩溃。希望我有所帮助。

【讨论】:

OpenGL 使用自己的浮点数、整数等类型,这些类型具有明确定义的大小。这些类型的大小不依赖于平台。 GLfloat 保证在每个平台上都是 32 位。 是的,glfloat 保证为 32 位,但是当您在 opengl es 中发送顶点时,它们不是 GLfloats 而是浮点数,这意味着它取决于平台并且您必须使用 nio 缓冲区。如果我错了,请纠正我,我不像你那样有经验。

以上是关于为啥我们可以直接在ByteBuffer中分配字节而不在FloatBuffer中分配浮点数的主要内容,如果未能解决你的问题,请参考以下文章

为啥 MSVC 不在生成的汇编代码中分配 32 字节的影子空间?

将文件加载为字节数组,而不在内存中分配它 C#

为啥编译器在堆栈中分配的比需要的多?

.NET 如何测量请求中分配的字节数?

47 VM.maxDirectMemory() 来自于哪里

47 VM.maxDirectMemory() 来自于哪里