SDL/OpenGL:实现"加载线程"

Pue*_*tis 6 c++ opengl sdl

我目前正在尝试为一个非常基本的游戏引擎实现一个"加载线程",它负责加载例如纹理或音频,同时主线程保持呈现正确的消息/屏幕,直到操作完成或甚至在加载时渲染常规游戏场景较小的对象出现在背景中.

现在,我到目前为止还没有OpenGL专家,但是当我实现这样一个"加载"机制时,我很快发现OGL不喜欢从非常多的创建的线程访问渲染上下文.我用Google搜索,解决方案似乎是:

"在线程上创建第二个渲染上下文,并与主线程的上下文共享"

这个问题是我使用SDL来处理我的窗口管理和上下文创建,据我所知,在检查API时,没有办法告诉SDL在彼此之间共享上下文:(

我得出结论,我的案例的最佳解决方案是:

方法A)改变SDL库以支持与平台特定功能的上下文共享(wglShareLists()和glXCreateContext()我假设)

方法B)让"加载线程"仅将数据加载到存储器中并将其处理为OpenGL友好格式并将其传递给主线程,例如负责将纹理上载到图形适配器.当然,这仅适用于需要完成有效OpenGL上下文的数据

第一种解决方案是我认为效率最低的解决方案.我真的不想破坏SDL,除此之外,我读到上下文共享不是一个高性能的操作.所以到目前为止,我的下一步将采用第二种方法.

编辑:关于"高性能操作":我读错了文章,实际上并不是表现密集.本文建议使用第二个上下文将CPU密集型操作转移到第二个线程.对不起

在完成所有这些介绍之后,如果有人能够对以下问题给我一些提示和评论,我将非常感激:

1)有没有办法与SDL共享上下文,无论如何这样做会有什么好处吗?

2)是否还有其他更"优雅"的方式来加载我可能错过或未考虑的后台数据?

3)我认为采用方法B的意图是否是一个不错的选择?在我的主线程上阻止渲染的OpenGL操作仍会有轻微的开销,或者它可以被忽略的那么小?

Nic*_*las 6

有没有办法与SDL共享上下文

没有.

是!

您必须使用特定于平台的调用来获取当前上下文.从那里,您可以创建新的上下文并使其共享,也可以使用特定于平台的调用.

是否还有其他更"优雅"的方式来加载我可能错过或未考虑的后台数据?

并不是的.您可以很好地枚举这些选项:破解SDL以获取所需的数据,或者无效地加载数据.

但是,您可以将数据加载到映射的缓冲区对象中并将数据传输到OpenGL.您只能在OpenGL线程上进行映射/取消映射,但映射时获得的指针可用于任何线程.因此映射缓冲区,将其传递给工作线程.它将数据加载到映射的内存中,并翻转一个开关.GL线程取消映射指针(工作线程现在应该忘记指针)并上传纹理数据.

我打算采用方法B的意图是否是一个不错的选择?

定义"好"?如果不了解有关您的问题域的更多信息,就无法回答这个问题.

  • @Nicol Bolas:实际上你可以与SDL共享上下文,如果你不编写平台依赖代码:wglGetCurrent {DC,Context},glXGetCurrent {Display,Drawable,Context},你会想到其余部分.我在我的PBuffer便利库中使用了那些. (3认同)