Yes I know opengl is not thread safe but what I want is run a new window with opengl in it on a different thread entirely without doing any sort of data manipulation over opengl and causing weird bugs what i want is have a web server that based on requests sent run a opengl thread render it then save it to a picture (basically im trying to render 3d virtual avatars for a website). But I kept getting this error:
OpenTK.Windowing.GraphicsLibraryFramework.GLFWException: GLFW can only be called from the main thread!
Code being (Licensed under public domain):
public async Task RenderAvatar() {
while(true) {
HttpListenerContext td = await httpServer.GetContextAsync();
HttpListenerRequest req = td.Request;
HttpListenerResponse res = td.Response;
if(req.HttpMethod == "GET") {
if(req.Url.AbsolutePath.ToString() == "/renderAvatar.3d") {
var parameters = HttpUtility.ParseQueryString(req.Url.Query);
if(parameters.Count == 3) {
var pant = parameters[0].ToString();
var face = parameters[1].ToString();
var shirt = parameters[2].ToString();
Game game = new Game(new string[]{pant,face,shirt, null},new string[]{ "head",
"neck",
"torso",
"larm",
"rarm",
"lleg",
"rleg",null});
game.Run();
}
}
}
}
after accessing the web page exception throws but I'm pretty sure it should run fine in theory since I do not do any sort of access other than initializing game type: GameWindow
object with parameters taken from the query and running it.
So I want to know what is the technical reason behind glfw don't letting me to run it on a different thread even if it will work fine in theory?
If it will run fine as long as I don't do data manipulation from different thread Is theres a way to bypass the exception or can I avoid the error by Compiling OpenTK myself and removing the exception and expect it to run fine?
Most GLFW functions, including glfwCreateWindow
must by called from the main thread. It says exactly that in the main GLFW reference and the OpenTK reference.
OpenGL is not GLFW. The GLFW thread rules apply to GLFW functions, and so you must respect them while calling GLFW functions. If you want to run OpenGL code in a non main thread, that is all fine.
Importantly, glfwMakeContextCurrent
may be called from any thread. This means that you can make a window on the main thread, hand it off to a second thread, and the second thread can then use the OpenGL context of that window. The second thread can also call glfwSwapBuffers
, but various other window functions like glfwPollEvents
still must be called from the main thread.
If you are ever unsure about the thread safety of a GLFW function, check the reference and it will tell you: https://www.glfw.org/docs/3.3/modules.html