2013-12-10 57 views
2

我试图找到一个可以最大限度地减少Java OpenGL(JOGL)应用程序中的内存分配和垃圾回收。我将一些C/C++/C#OpenGL项目移植到Java中作为学习练习。我遇到的一件事是在Java中缺乏指针,并在应用程序运行时分配它们的对象和GC。在C/C++/C#中,我可以让应用程序启动并运行,无需通过传递引用来分配任何额外的内存或对象,但在Java中,似乎我的设计不兼容。Java OpenGL(JOGL)对象数组和浮动缓冲区

随着这些设计的发展,他们正在使用更高层次的对象。在C中,它们是向量和矩阵以及C++/C#类中的结构。这些都基本归结为内存中的字节数组。然后在这个或那个方法中,为应用程序内部的OpenGL调用或对象数组float []浮动[],以便我们可以使用基于对象的操作,例如运算符重载,加法和乘法或属性访问。任何使用OpenGL的人都会看到我在做什么。这样我就可以分配负载上的所有内容,并简单地传递数据。

Java引发了我的一些循环。看起来我无法来回传送数据,因此我一直在创建大量数据,并且GC来了并且工作。这是显而易见的资源消耗和清理,并在应用程序运行期间明显的口吃。我通过为我的几何数据创建FloatBuffers和VectorXf数组并将FloatBuffer传递给OpenGL,从而缓解了这一点。但是当我需要更新矢量数据时,我必须将数据重新复制回浮动缓冲区。这也意味着我存储了两倍的数据并导致了floatbuffer填充的开销。

我想听听其他人如何处理这些问题。我想保留内置功能的高阶对象,但能够将数据传递给OpenGL。我的设计是否与Java不兼容?我是否需要专门移动到FloatBuffers?如何将组件数据传递到更高级的对象中,而不会造成对象创建的损失。许多OpenGL应用程序存在,我怀疑有一些'魔术'可以使用float []和Object []的相同缓冲区,或者为对象数据分配连续的块并将引用传递给OpenGL。

回答

3

管理OpenGL数据的驱动力是你不想对包含几何图形或纹理的内存负责。使用float[]甚至FloatBuffers只能用于将几何数​​据传输到OpenGL缓冲区对象中。一旦创建了OpenGL缓冲区并将数据复制到其中,就不再需要在JVM中保留副本。在几乎所有的现代硬件上,这将导致数据保留在显卡本身上,完全在JVM之外。理想情况下,如果大多数几何图形是静态的,则可以在启动时将其复制到OpenGL缓冲区,而不必再次直接对其进行管理。如果你正在处理大量的动态几何体,那么你仍然需要将数据来回传递给OpenGL驱动程序。在这种情况下,您可能需要维护一个FloatBuffers池,该FloatBuffers池可以用作在生成代码或发现变化的几何图形与驱动程序之间移动数据的渡轮。 FloatBuffers是不可避免的,因为OpenGL需要一种给定格式的数据,这与JVM中数据的内部表示方式不同,但至少你不需要为每一组数据保留一个单独的FloatBuffer你有数据。

+0

这就是我所在的位置。为所有内容创建VBO并传递给GL,然后删除缓冲区。奇怪的事情是应用程序将在glBufferData上进行核心转储的五分之一。就像代码在浮点缓冲区已满或在某处为空之前移动到glBufferData调用一样。我在启动后崩溃后所做的所有工作都会重新开始,并且可以正常工作。仍然在开展这项活动。对于动态内容,屏幕字体输出,当你通过glDrawArrays向硬件陈述数据时,我会保留一个缓冲区来轮渡。其他一切都是静态的。 – user2811897

+0

FloatBuffers是一种痛苦。它们保持内部指针指向缓冲区中的“当前点”,因此很容易追加到它们。我在处理它们时遇到的大多数崩溃都涉及到在将它发送给GL之前忘记将指针重置为0,这意味着OpenGL将从缓冲区的中间或末端开始读取,并可能会流入未初始化的内存。其他潜在的错误来源包括错误计算缓冲区中可用的字节数,您需要将其传递到glBufferData中。 – Jherico

+0

在glBufferData开始之前,所有的缓冲区都被设置为位置(0)。它也奇怪它只发生一段时间。运行相同的代码。大小,也许但我实际上是directAllocate()ByteBuffers asFloatBuffer所以我的大小是以字节计算的,所以我99%确定它们是准确的。它的C端口像langs,所以数学是一样的,我希望... – user2811897

0

我的经验: 我用FloatBuffers只传输数据,但我发现,这是真正的动态网格杀的表现,因为我有我的VEC阵列转换为FloatBuffers每次我改变我的网格。现在我摆脱了我的vec阵列,并且只通过我的网格类持久地使用FloatBuffers,不太优雅来处理它们,但速度更快。所以我建议你保留&用FloatBuffers更新所有的几何图形数据