是的,我知道opengl不是线程安全的,但我想要的是运行一个新的窗口与opengl在它的一个不同的线程完全没有做任何类型的数据操作opengl和引起奇怪的错误我想要的是有一个网络服务器,根据发送的请求运行一个opengl线程渲染它,然后保存到一个图片(基本上我试图渲染三维虚拟头像的网站).但我一直得到这个错误:
OpenTK.Windowing.GraphicsLibraryFramework.GLFWException: GLFW can only be called from the main thread!
代码(在公共领域下许可):
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();
}
}
}
}
访问网页后抛出异常,但我很确定它应该在理论上运行良好,因为我没有做任何访问以外的初始化游戏type: GameWindow
对象与参数从查询和运行它。所以我想知道什么是背后的技术原因glfw不让我运行它在一个不同的线程,即使它将在理论上运行良好?如果只要我不从不同的线程进行数据操作,它就能正常运行,有没有办法绕过异常,或者我可以通过自己编译OpenTK并删除异常来避免错误,并期望它能正常运行?
1条答案
按热度按时间bz4sfanl1#
大多数GLFW函数,包括
glfwCreateWindow
,必须从主线程调用。在主GLFW引用和OpenTK引用中完全是这样说的。OpenGL不是GLFW。GLFW线程规则适用于GLFW函数,所以在调用GLFW函数时必须遵守这些规则。如果你想在非主线程中运行OpenGL代码,那也没问题。
重要的是,
glfwMakeContextCurrent
可以从任何线程调用。这意味着你可以在主线程上创建一个窗口,然后将其交给第二个线程,第二个线程可以使用该窗口的OpenGL上下文。第二个线程也可以调用glfwSwapBuffers
,但其他各种窗口函数,如glfwPollEvents
,仍然必须从主线程调用。如果您不确定GLFW函数的线程安全性,请检查引用,它会告诉您:https://www.glfw.org/docs/3.3/modules.html