SDL / OpenGL:实现“加载线程” [英] SDL / OpenGL: Implementing a "Loading thread"

查看:244
本文介绍了SDL / OpenGL:实现“加载线程”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前尝试为一个非常基本的游戏引擎实现一个加载线程,它负责加载。纹理或音频,而主线程继续呈现正确的消息/屏幕,直到操作完成或甚至渲染常规游戏场景,而较小对象的加载发生在后台。



,我是迄今为止没有OpenGL专家,但是当我实现这样一个加载机制,我很快发现,OGL不喜欢从一个线程访问渲染上下文,而不是非常创建它。我尝试了一下,解决方案似乎是:



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



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



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


方法A)更改SDL库以支持与平台特定函数(wglShareLists()和glXCreateContext()假设)的上下文共享



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



第一个解决方案是我想的最低效的。我不是真的想使用SDL,除了我读的上下文共享不是一个高性能的操作。所以我的下一步是到目前为止的第二种方法。



编辑:关于高性能操作:我读的文章错了,不是性能密集型。文章建议将CPU密集型操作转移到具有第二上下文的第二线程。对不起,



毕竟这个介绍后,我真的很感激,如果任何人可以给我一些提示和评论以下问题:



1)有什么方法可以与SDL共享上下文,这样做有什么好处吗?



2)有没有其他更优雅的方式在后台加载我可能错过或没有想到的数据?



3)我的进入B的意向是否被认为是一个好的选择?在阻止渲染的主线程上,OpenGL操作仍然会有少量开销,或者是小到可以忽略的。

解决方案


有什么办法与SDL共享上下文


否。



是!



您必须获取当前上下文,调用。


还有其他更多的优雅


不是真的,我们可以在后台加载我的数据。你枚举的选项很好:hack SDL获得你需要的数据,或加载数据低效。



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


我的意图方法B被认为是一个好的选择?


定义好?没有办法回答这个问题,而不了解你的问题域。


I currently try to implement a "Loading thread" for a very basic gaming engine, which takes care of loading e.g. textures or audio while the main thread keeps rendering a proper message/screen until the operation is finished or even render regular game scenes while loading of smaller objects occurs in background.

Now, I am by far no OpenGL expert, but as I implemented such a "Loading" mechanism I quickly found out that OGL doesn't like access to the rendering context from a thread other than the one it was created on very much. I googled around and the solution seems to be:

"Create a second rendering context on the thread and share it with the context of the main thread"

The problem with this is that I use SDL to take care of my window management and context creation, and as far as I can tell from inspecting the API there is no way to tell SDL to share contexts between each other :(

I came to the conclusion that the best solutions for my case are:

Approach A) Alter the SDL library to support context sharing with the platform specific functions (wglShareLists() and glXCreateContext() I assume)

Approach B) Let the "Loading Thread" only load the data into memory and process it to be in a OpenGL-friendly format and pass it to the main thread which e.g. takes care of uploading the texture to the graphics adapter. This, of course, only applies to data that needs a valid OpenGL context to be done

The first solution is the least efficient one I guess. I don't really want to mangle with SDL and beside that I read that context sharing is not a high-performance operation. So my next take would be on the second approach so far.

EDIT: Regarding the "high-performance operation": I read the article wrong, it actually isn't that performance intensive. The article suggested shifting the CPU intensive operations to the second thread with a second context. Sorry for that

After all this introduction I would really appreciate if anyone could give me some hints and comments to the following questions:

1) Is there any way to share contexts with SDL and would it be any good anyway to do so?

2) Is there any other more "elegant" way to load my data in the background that I may have missed or didn't think about?

3) Can my intention of going with approach B considered to be a good choice? There would still be slight overhead from the OpenGL operations on my main thread which blocks rendering, or is it that small that it can be ignored?

解决方案

Is there any way to share contexts with SDL

No.

Yes!

You have to get the current context, using platform-specific calls. From there, you can create a new context and make it shared, also with platform-specific calls.

Is there any other more "elegant" way to load my data in the background that I may have missed or didn't think about?

Not really. You enumerated the options quite well: hack SDL to get the data you need, or load data inefficiently.

However, you can load the data into mapped buffer objects and transfer the data to OpenGL. You can only do the mapping/unmapping on the OpenGL thread, but the pointer you get when you map can be used on any thread. So map a buffer, pass it to the worker thread. It loads data into the mapped memory, and flips a switch. The GL thread unmaps the pointer (the worker thread should forget about the pointer now) and uploads the texture data.

Can my intention of going with approach B considered to be a good choice?

Define "good"? There's no way to answer this without knowing more about your problem domain.

这篇关于SDL / OpenGL:实现“加载线程”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆