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, даже самая простая, выдает такую ошибку.