如何加载VBO并在单独的Java线程上呈现它?

时间:2016-04-28 13:54:42

标签: java multithreading opengl lwjgl vao

要创建虚拟世界,我使用轻量级Java游戏库(LWJGL)(Java + OpenGL)。我想将我的地形加载到工作线程的图形卡内存中,而在主线程上我想要采用这些已经加载的地形并渲染它们。为了做到这一点,我必须创建顶点数组对象(VAO),创建顶点缓冲对象(VBO),将VBO添加到VAO属性列表中,最后渲染所有内容。这在单线程系统上完美运行,但是我在多线程系统上实现它时遇到了问题。我知道VBO可以在OpenGL上下文之间共享,而VAO无法共享(reference1; reference2)。因此,为了实现我的目标我:

  1. 在主线程上创建VAO,
  2. 使用这些方法在工人胎面上创建VBO:

    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,ID); int ID = GL15.glGenBuffers(); GL15.glBufferData(GL15.GL_ARRAY_BUFFER,buffer,GL15.GL_STATIC_DRAW); GL20.glVertexAttribPointer(attributeNr,coordSize,GL11.GL_FLOAT,false,0,0); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,0);

  3. 在主线程上渲染它,但是我明白了 例外:

  4. 线程“main”中的异常org.lwjgl.opengl.OpenGLException:禁用元素数组缓冲区对象时无法使用偏移量

    我确信我没有渲染未加载的地形,因为我在渲染范围之外加载地形。我已经阅读了很多关于OpenGL共享上下文和并发的文章,问题和博客,但没有找到解决方案。我会非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

正如您已经说过的,VAO在上下文之间共享 NOT ,因此也无法从多个线程修改它们。

GL20.glVertexAttribPointer(attributeNr, coordSize, GL11.GL_FLOAT, false, 0, 0); 

正在修改VAO状态,因此必须从主线程调用它。

将数据上传(glBufferData)放在一个单独的线程中是完全可以的,但构建VAO只能从主线程完成。