Hello,
I'm creating an application where lwjgl is started in a non-main thread. It shouldn't be a problem, right?
I use the following code: `
glfwSetErrorCallback(errorCallback = GLFWErrorCallback.createPrint(System.err));
if (!glfwInit()) {
System.err.println("Couldn't initialize glfw context. Using software renderer.");
enabled = false;
reportOpenGLStartupError(null, "glfwInit()");
return;
}
// get monitor's size to set max width / height
GLFWVidMode videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
maxWidth = videoMode.width();
maxHeight = videoMode.height();
// set current heights
int w = (int) (maxWidth * 0.7);
int h = (int) (maxHeight * 0.7);
if (w < 900)
w = 900;
if (h < 600)
h = 600;
Client.clientWidth = width = frameWidth = w;
Client.clientHeight = height = frameHeight = h;
// resizable and
glfwWindowHint(GLFW_RESIZABLE, 1);
glfwWindowHint(GLFW_VISIBLE, 0);
window = glfwCreateWindow(width, height, "Emps-World", 0, 0);
if (window == 0) {
enabled = false;
System.err.println("Couldn't initialize glfw window ("+width+"/"+height+"). Using software renderer.");
return;
}
// make current window current contest and create GL capabilities
glfwMakeContextCurrent(window);
GL.createCapabilities();
System.out.println("[GraphicsDisplay]: init(): current thread: "+Thread.currentThread().getName());
`
Now this works on both, my laptop and on my Desktop computer. However, on another Windows 10 setup it crashes with following exception:
java.lang.IllegalStateException: There is no OpenGL context current in the current thread.
Do I have something wrong? Calling glfwMakeContextCurrent(window); should bind the current thread to the current OpenGL Context?
Thanks in advance!
Thomy
Deleting following folder fixed the problem:
C:\Users\User\AppData\Local\Temp\lwjglUser
Looks like I am forced to delete that folder upon every start of our application, since this has already been causing a lot of troubles and a lot of different errors.
Any ideas what could be causing them?
I'm creating an application where lwjgl is started in a non-main thread. It shouldn't be a problem, right?
It is a problem. Most GLFW functions are required to be called from the main thread, which also has to be the first thread on macOS (see -XstartOnFirstThread). The javadoc of each function mentions if it's callable from any thread or only from main. This is neither an LWJGL nor a GLFW limitation; it's the only way to write a usable cross-platform windowing system. Your application may work on Windows, but will certainly fail on macOS. Note that this applies to GLFW functions only; OpenGL contexts can be made current in other threads and those threads can be used for rendering.
Looks like I am forced to delete that folder upon every start of our application, since this has already been causing a lot of troubles and a lot of different errors.
Any ideas what could be causing them?
This is odd, but there is not enough information to provide an answer. Which LWJGL version do you use? Could you please run your application with -Dorg.lwjgl.util.Debug=true and -Dorg.lwjgl.util.DebugLoader=true and attach the output here? (from a run that fails)
Thanks a lot! :)
I am already using -xStartOnFirstThread on macOS and user have reported that it's working fine, no errors there.
The issue is indeed odd. I will provide an outprint if I find a user having this issue again. It was only happening on a user's computer with Windows 10 and lwjgl-3.1.1. Deleting the lwjgl folder in the user's temp directory completely fixed the problem for the user.
Though, in theory, I should be able to run lwjgl on the non-main thread on Windows if using the code from above. It works fine on my computer, no matter in which thread I run it.
Note that this applies to GLFW functions only; OpenGL contexts can be made current in other threads and those threads can be used for rendering.
But, if you need an GLFW window (even if hidden) to create an OpenGL context, how would one go at having the OpenGL context in a different thread than the main thread? And how to have two parallel OpenGL contexts on different threads?
I think an OpenGL context can only safely be active on one thread at a time. You can set the active context for a thread using glfwMakeContextCurrent, which can be called from any thread.
And how does this work on the larger scale level? In the OS, there _must_ be multiple OpenGL contexts open at the same time without problems, what's the difference there? Where does this limitation come from (Java, GLFW, OS allowing one context per process, ...)?
Of course there can exist multiple OpenGL contexts at the same time. However an OpenGL context is inherently _not_ thread-safe and therefore only _one_ thread can access the same OpenGL context at any given time. It is up to you which thread that is (can be changed).
OpenGL uses thread-local memory to keep track of which context is associated with the current thread to direct OpenGL API calls to the right context (in case OpenGL function addresses are the same for all OpenGL contexts) and to enforce this single-threadedness. This goes in cooperation with the windowing subsystem of the operating system, such as WGL on Windows or GLX on Linux, which provide methods (such as wglMakeCurrent - wrapped via GLFW's glfwMakeCurrent) to switch the current thread of the context associated to a given drawable/window.
What happens on this topic if the machine used has multiple graphics cards?
Not sure if this is the issue, but by default the debug library does not have a thread as the main GLFW thread. You need to set that yourself for it's checks to pass.