Introduction:
I am currently designing a game in Java using the LWJGL 3.0, with Gradle. I have quite an advanced knowledge on multi-threading, and I am aware how GLFW does/doesn't implement multi-threading from this guide. Currently, I have one class Updater
with a loop for updating, and another class Renderer
for rendering, each extending Runnable with their own loops and time calculations. Below is a diagram showing the structure of the classes and update and render methods. I have also set up a lock system, using the Java Lock class (again below).
My Problem:
Despite setting each thread as the current context before each loop executes its window call, and setting the current context to null at the end, I still get the error Exception in thread "RENDERER" java.lang.IllegalStateException: GLFW error [0x10008]: WGL: Failed to make context current: The requested resource is in use.
Any idea as to why? Been at this for a few hours now.
Loop class:
private void threadLoop() {
try {
lock.lock();
locked = true;
loop();
TPS++;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
locked = false;
}
}
@Override
public void run() {
init();
long lastTime = System.nanoTime();
double ns = SECOND / (MAX_TPS/2);
double delta = 0;
long timer = System.currentTimeMillis();
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while(delta >= 1) {
threadLoop();
TPS++;
delta--;
}
if(System.currentTimeMillis() - timer > 1000) {
finalTPS = TPS;
timer += 1000;
TPS = 0;
}
}
stop();
}
Thread Manager:
public void update() {
if (window == null) return;
window.setThread();
window.update();
window.nullThread();
}
public void render() {
if (window == null) return;
window.setThread();
window.render();
window.nullThread();
}
Renderer:
@Override
protected void loop() {
if (state != null) state.render();
threadManager.intermediateCode();
threadManager.render();
}
Updater:
@Override
protected void loop() {
if (state != null) state.update();
threadManager.intermediateCode();
threadManager.update();
}
Window:
public void setThread() {
glfwMakeContextCurrent(getID());
}
public void nullThread() {
glfwMakeContextCurrent(NULL);
}
public void render() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 0.3f, 0.8f, 0.0f);
glfwSwapBuffers(ID);
System.out.println("Rendered window");
}
public void update() {
glfwPollEvents();
System.out.println("Updated window");
}