LWJGL Нет контекста или функция недоступна в текущем контексте

Пишу на LWJGL простое приложение, которое рисует в окне. Когда оно начало разделяться на несколько потоков, сразу возникли проблемы при вызове OpenGL функций:

> FATAL ERROR in native method: Thread[GAME_LOOP_THREAD,5,main]: No
> context is current or a function that is not available in the current
> context was called. The JVM will abort execution.     at
> org.lwjgl.opengl.GL20C.glCreateProgram(Native Method)     at
> org.lwjgl.opengl.GL20.glCreateProgram(GL20.java:188)  at
> aoizora.shader.ShaderProgram.<init>(ShaderProgram.java:13)    at
> aoizora.game.GameEngine.init(GameEngine.java:58)  at
> aoizora.game.GameEngine.run(GameEngine.java:43)

Насколько я могу понять, проблема из-за того, что контекст создается в каком-то не том потоке. Как сделать, чтобы заработало? Вот весь мой код:

Главная функция

public class Main
{
    public static void main(String[] args)
    {
        try
        {
            GameLogic logic = new Game();
            GameEngine engine = new GameEngine("Game", 600, 480, true, logic);
            engine.start();
        }
        catch (Exception e)
        {
            e.printStackTrace();
            System.exit(-1);
        }
    }
}

Интерфейс для логики приложения

public interface GameLogic
{
    void init(Window window, Render render) throws Exception;

    void input(Window window);

    void render(Window window);

    void update(float interval);

    void cleanup();
}

Движок

public class GameEngine implements Runnable
{
    private Window window;
    private Thread thread;
    private GameLogic logic;
    private ShaderProgram shaderProgram;
    private Render render;

    public GameEngine(String title, int width, int height, boolean vSync, GameLogic logic)
    {
        WindowOptions opts = new WindowOptions();
        opts.title = title;
        opts.width = width;
        opts.height = height;

        window = new Window(opts);

        this.render = new Render();
        this.thread = new Thread(this, "GAME_LOOP_THREAD");
        this.logic = logic;
    }

    public void start()
    {
        thread.start();
    }

    @Override
    public void run()
    {
        try
        {
            init();
            loop();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            cleanup();
        }
    }

    private void init() throws Exception
    {
        shaderProgram = new ShaderProgram();
        shaderProgram.createVertexShader(FileUtils.readFile("vertex.vs"));
        shaderProgram.createFragmentShader(FileUtils.readFile("fragment.fs"));
        shaderProgram.link();
    }

    private void loop()
    {
        while (!window.windowShouldClose())
        {
            window.pollEvents();

            input();
            render();
            update(1f);
        }
    }

    protected void input()
    {
        logic.input(window);
    }

    protected void update(float interval)
    {
        logic.update(interval);
    }

    protected void render()
    {
        logic.render(window);
        window.update();
    }

    private void cleanup()
    {
        logic.cleanup();
        window.cleanup();
    }
}

Реализация логики приложения

public class Game implements GameLogic
{
    private int direction = 0;
    private float color = 0.0f;

    public Game()
    {

    }

    @Override
    public void init(Window window, Render render) throws Exception
    {

    }

    @Override
    public void input(Window window)
    {
        if (window.isKeyPressed(GLFW_KEY_UP))
        {
            direction = 1;
        }
        else if (window.isKeyPressed(GLFW_KEY_DOWN))
        {
            direction = -1;
        }
        else
        {
            direction = 0;
        }
    }

    @Override
    public void render(Window window)
    {
        if (window.isResized())
        {
            glViewport(0, 0, window.getWidth(), window.getHeight());
        }
        window.setClearColor(color, color, color, 0.0f);
    }

    @Override
    public void update(float interval)
    {
        color += direction * 0.01f;
        if (color > 1)
        {
            color = 1.0f;
        }
        else if (color < 0)
        {
            color = 0.0f;
        }
    }

    @Override
    public void cleanup()
    {

    }
}

Класс визуализации

public class Render
{
    public Render()
    {
        GL.createCapabilities();
    }

    public void init() throws Exception
    {

    }

    public void clear()
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    }
}

Шейдеры не буду показывать, потому что не в них проблема. Любая функция OpenGL, даже самая простая, выдает такую ошибку.


Ответы (0 шт):