【问题标题】:How do you make a new thread in java with opengl support?如何在 java 中创建一个支持 opengl 的新线程?
【发布时间】:2014-02-22 20:53:38
【问题描述】:

我正在使用 lwjgl 制作一个新的 3D java 游戏,一切进展顺利,但我试图在不同的线程中创建一些 3D 对象,如下所示:

new Thread(new Runnable() {
    @Override
    public void run() {
        for(int x = 1; x < 5; x++) {
            for(int z = 1; z < 5; z++) {
                Object3D curObject = game.createGrassBlock(game.maps.get(0));
                curObject.setPosition(x, curObject.getSize().getY() / 2, z);
                curObject.defaultPosition = curObject.getPosition();
                Thread.sleep(1);
            }
        }
    }
}).start();

但是,每当我运行该代码时,都会收到以下错误:

Exception in thread "Thread-4" java.lang.RuntimeException: No OpenGL context found in the current thread.
    at org.lwjgl.opengl.GLContext.getCapabilities(GLContext.java:124)
    at org.lwjgl.opengl.GL15.glGenBuffers(GL15.java:114)
    at com.gmail.br45entei.base.engine.rendering.Mesh.initMeshData(Mesh.java:43)
    at com.gmail.br45entei.base.engine.rendering.Mesh.<init>(Mesh.java:32)
    at com.gmail.br45entei.base.engine.rendering.Object3D.updateMeshes(Object3D.java:891)
    at com.gmail.br45entei.base.engine.rendering.Object3D.setShape(Object3D.java:942)
    at com.gmail.br45entei.base.engine.rendering.Object3D.<init>(Object3D.java:663)
    at com.gmail.br45entei.base.game.Game.createGrassBlock(Game.java:293)
    at com.gmail.br45entei.base.game.Game.access$1(Game.java:292)
    at com.gmail.br45entei.base.game.Game$1.run(Game.java:220)
    at java.lang.Thread.run(Unknown Source)

我确信代码在我的 Game.java 中运行良好(但滞后)而不在新线程中调用它,我很难过,因为我不知道为什么新线程不会有相同的 opengl上下文作为主线程...有什么想法吗?感谢阅读!

【问题讨论】:

    标签: java multithreading opengl runnable


    【解决方案1】:

    我不知道为什么一个新线程不会有与主线程相同的opengl上下文......

    因为 OpenGL 不是这样工作的。 OpenGL 上下文绑定到特定线程。每个上下文在任何时候都只能(最多)绑定到一个线程。而且 ech 线程在任何时候都只能有一个 GL 上下文。

    如果您想使用更多线程,您有多种选择:

    1. 仅使用一个 GL 上下文。但是您需要同步对它的访问,因此当前拥有它的线程必须取消绑定它,然后新的线程必须绑定它。这不适合您的问题。

    2. 使用不同的上下文。每个线程都可以始终绑定自己的 GL 上下文。默认情况下,上下文将相互独立。但是,这可以更改:您可以创建 共享上下文,它实际上将共享很多对象,因此线程 A 可以创建和操作 GL 对象,如 VBO、纹理、...和线程B 可以直接使用它们,就好像它自己创建/操作它们一样。看看这个OpenGL and multithreading article。您仍然必须使用某种同步,以便线程 B 知道线程 A 何时完成对对象的操作等等...请注意,您不仅需要在 CPU 上同步线程,还需要与GL,也要确保 GPU 在其他线程应该使用更新的对象之前实际上已经完成了挂起的操作。

    3. 穷人的多线程GL对象更新可以通过使用映射缓冲区对象来实现。只有一个 GL 上下文和一个线程处理它。但是这个线程可以通过glMapBuffer/glMapBufferRange将对象映射缓冲到客户端地址空间。内存映射是每个进程而不是每个线程的,因此当它被映射时,进程的任何线程都可以操作它。传统上,GL 不允许在 GL 中使用映射对象,因此当对象被映射时,GL 线程不能真正将其用于绘图。在 OpenGL 4.4 中,引入了 ARB_buffer_storage,它甚至允许在映射对象时使用它们 - 但同步完全取决于用户。

    【讨论】:

      猜你喜欢
      • 2013-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-19
      • 2020-01-01
      • 2013-09-30
      • 1970-01-01
      • 2021-04-10
      相关资源
      最近更新 更多