这个解决方案间歇性地有效,该程序经常崩溃,由于一组错误(主要来自X窗口系统)的变化令我感到困惑。这使我对我最初的假设产生了疑问,即只要在上下文创建的线程中执行所有OpenGL调用,一切都应该还能正常工作。在花费了一整天在互联网上搜索答案后,我已经被彻底难住了。
更简洁地说:是否可能使用OpenGL在除主线程之外的线程中执行3D渲染? 我可以继续使用诸如SDL或GLFW等跨平台窗口库进行此配置吗? 是否有更好的方法来实现我想做的事情?
到目前为止,我一直在使用C++在Linux(Ubuntu 11.04)上进行开发,尽管我还可以使用Java和Python,如果有更适合这些语言的解决方案。
多线程版本的应用程序出现的错误:
XIO:在 X 服务器 ":0.0" 上发生致命 IO 错误 11(资源暂时不可用),在 73 个请求(已知处理的 73 个请求)后,剩余 0 个事件。
失败请求的 X 错误:BadColor(无效的颜色映射参数) 失败请求的主要操作码:79(X_FreeColormap) 失败请求中的资源 ID:0x4600001 失败请求序列号:72 输出流中的当前序列号:73
游戏:../../src/xcb_io.c:140:dequeue_pending_request:断言“req == dpy->xcb->pending_requests”失败。 中止
我总是会得到以上三个错误之一,我得到的是随机变化的,这似乎证实了我的问题确实源于我的线程使用。请记住,我是边学边做,所以非常有可能在我无知的情况下犯了某些愚蠢的错误。
解决方案: 对于任何遇到类似问题的人,我通过将调用SDL_Init(SDL_INIT_VIDEO)
的操作移动到渲染线程,并使用互斥锁锁定上下文初始化,解决了我的问题。这确保了上下文在将要使用它的线程中创建,防止主循环在初始化任务完成之前开始。启动过程的简化概述如下:
1)主线程初始化struct
,该结构将在两个线程之间共享,其中包含互斥锁。
2)主线程生成渲染线程并休眠一段短时间(1-5毫秒),以便渲染线程有时间锁定互斥锁。在此暂停后,主线程在尝试锁定互斥锁时阻塞。
3)渲染线程锁定互斥锁,初始化 SDL 的视频子系统并创建 OpenGL 上下文。
4)渲染线程解锁互斥锁并进入其“渲染循环”。
务必阅读答案和评论,那里有很多有用的信息。
MsgWaitForMultipleObjectsEx
等效函数(也许名字更短)。就像poll
一样,但能够等待文件、子进程、定时器、线程、互斥体和UI消息。 - Ben Voigt