【发布时间】:2017-07-01 14:50:13
【问题描述】:
我有一个 Java 应用程序,我在其中计算 CPU 上的 3D 模型。计算需要一些时间(以秒为单位 - 分钟),但发生在迭代中,如果你愿意的话,细节级别。我正在使用 JOGL 来可视化模型。我想立即可视化模型,并在准备好后用新的细节级别更新视图。我有一个可以正常工作的设置,但我感觉我做错了什么(我正在用这个项目学习 OpenGL):现在我将新 LoD 的顶点信息缓存在 FloatBuffer 中并设置一只旗。渲染循环检查这个标志,如果它被设置,它将为 VBO 分配一个新的数据存储 (glBufferData)。我考虑使用glBufferSubData 以获得更好的性能(分配新的数据存储会导致更高级别的性能提升,至少有 1M 顶点)但问题是新的细节级别具有任意数量的顶点(不是与上一个细节级别相同)并且我无法预测,当第一次初始化 VBO 时,缓冲区应该最大有多大。我尝试分配一个非常大的缓冲区,但这让我遇到 JVM 崩溃或 GL 1281 错误(我想我正在尝试分配一个太大的缓冲区:1440*1440*4 字节)。我应该使用多个单独的 VBO 吗?我可以制作多大的 VBO?我是否应该为顶点颜色、法线和顶点位置设置一个单独的(一组)VBO?准备好新的详细程度后,最佳做法是什么?
额外信息:
在渲染循环中检查的输出带有一个新的缓冲区数据存储(使用System.currentTimeMillis() 测量的时间),以获取不同级别的细节到达,显示出明显的性能提升:
OpenGL received new data of length 0
Allocating a new data store took 0 ms
OpenGL received new data of length 0
Allocating a new data store took 0 ms
OpenGL received new data of length 360
Allocating a new data store took 3 ms
OpenGL received new data of length 6240
Allocating a new data store took 0 ms
OpenGL received new data of length 34020
Allocating a new data store took 0 ms
OpenGL received new data of length 177840
Allocating a new data store took 1 ms
OpenGL received new data of length 1018980
Allocating a new data store took 7 ms
OpenGL received new data of length 5214660
Allocating a new data store took 20 ms
OpenGL received new data of length 19392000
Allocating a new data store took 59 ms
OpenGL received new data of length 56229840
Allocating a new data store took 157 ms
实际代码:
long before = System.currentTimeMillis();
gl.glBufferData(GL_ARRAY_BUFFER, vertexData.limit() * 4, vertexData, GL_STATIC_DRAW);
System.out.println("Allocating a new data store took " + (System.currentTimeMillis() - before) + " ms");
其中vertexData 是在包含顶点数据的float[] 上使用GLBuffers.newDirectFloatBuffer(...) 分配的(这是在CPU 线程上完成的)。在旁注中,请注意最大的细节模型如何包含 5622984 个顶点(每个顶点由 10 个浮点值组成)。此代码有效,当我的电脑被要求使用这行代码分配该大小的缓冲区数据存储时,它不会抱怨。我很奇怪,因为如果我尝试通过硬编码这个字节量来直接在我的 init 例程中分配一个大小的缓冲区,JVM 就会崩溃......(#有问题的帧:
[nvoglv64.DLL+0xd16e7b])。所以改变
gl.glBufferData(
GL_ARRAY_BUFFER,
vertexData.limit() * 4,
vertexData,
GL_STATIC_DRAW);
到
gl.glBufferData(
GL_ARRAY_BUFFER,
56229840*4,
vertexData,
GL_STATIC_DRAW);
导致 JVM 崩溃。
【问题讨论】: