【发布时间】:2011-10-12 20:48:58
【问题描述】:
我目前尝试为一个非常基本的游戏引擎实现一个“加载线程”,它负责加载例如纹理或音频,而主线程不断渲染正确的消息/屏幕,直到操作完成,甚至渲染常规游戏场景,同时在后台加载较小的对象。
现在,我到目前为止还不是 OpenGL 专家,但是当我实现了这样一种“加载”机制时,我很快发现 OGL 不喜欢从一个线程访问渲染上下文,而不是它创建的线程。很多。我搜索了一下,解决方案似乎是:
“在线程上创建第二个渲染上下文,并与主线程的上下文共享”
问题在于我使用 SDL 来处理我的窗口管理和上下文创建,据我检查 API 可以看出,没有办法告诉 SDL 在彼此之间共享上下文:(
我得出的结论是,我的案例的最佳解决方案是:
方法 A) 更改 SDL 库以支持与平台特定函数的上下文共享(我假设为 wglShareLists() 和 glXCreateContext())
方法 B)让“加载线程”仅将数据加载到内存中并将其处理为 OpenGL 友好的格式并将其传递给主线程,例如负责将纹理上传到图形适配器。当然,这仅适用于需要完成有效 OpenGL 上下文的数据
我猜第一个解决方案是效率最低的。我真的不想使用 SDL,除此之外,我读到上下文共享不是一种高性能操作。所以我的下一步将是目前为止的第二种方法。
编辑:关于“高性能操作”:我读错了文章,实际上并不是性能密集型。该文章建议将 CPU 密集型操作转移到具有第二个上下文的第二个线程。很抱歉
在所有这些介绍之后,如果有人能给我一些提示和解决以下问题,我将不胜感激:
1) 有没有办法与 SDL 共享上下文?这样做有什么好处吗?
2) 有没有其他更“优雅”的方式来在后台加载我可能错过或没想到的数据?
3) 我打算采用方法 B 的意图是否被认为是一个不错的选择?我的主线程上的 OpenGL 操作仍然会产生轻微的开销,这会阻塞渲染,还是小到可以忽略?
【问题讨论】:
-
我会选择解决方案 B。让后台线程加载所有必要的数据,让主线程处理绘图。
-
谢谢,我现在正在重构我的代码,以便以这种方式加载我的数据。但也许有人仍然有一些 cmets 让这个问题提供更多信息,以防有人遇到同样的问题:)
-
请记住,这个解决方案说起来容易做起来难:根据您应用程序的细节,您的线程很可能必须正确同步,这并不总是简单的任务。我假设您已经研究过单线程替代方案,但没有找到适合您的方案。
-
不幸的是,我没有找到合适的单线程解决方案:(但我仍在搜索。对于同步:我考虑过在每帧完成后查询线程,如果是这样,我知道我的数据已准备好由 OpenGL 处理。完成此步骤后,我的应用程序可以使用数据。如果我有一个正在运行的加载屏幕,我认为不需要做更多的事情 - 对于延迟在游戏场景运行时加载我还必须检查数据是否真的准备好。另外,还有一点点开销,但我认为没有其他解决方法
-
“我读到上下文共享不是高性能操作。”你在哪里读到的?因为这显然是错误的。