如何在单独的线程上将纹理加载到主内存并在另一个线程上使用它进行渲染?

时间:2019-02-14 12:01:23

标签: c++ multithreading opengl textures

我正在创建一个新的应用程序,并且我想支持多线程纹理加载。如何在单独的线程上将纹理加载到主内存?

我正在使用SDL2加载png文件。我创建了一个线程安全队列类,使用SDL_Surface surface函数将图像加载到IMG_Load中,将曲面推入队列,如果队列不为空,我得到了推入曲面的像素并将其添加到纹理缓冲区-{ {1}}

我尝试在glTexImage2D()函数和LoadingThread上设置一个断点,但是当前不会命中该断点。此行没有与调试器的目标代码类型关联的可执行代码。可能的原因包括:条件编译,编译器优化,当前调试器代码类型不支持此行的目标体系结构。我正在调试(未启用优化)64位。

Texture::LoadFromFile()

现在,程序停止并等待,直到加载并渲染纹理。我希望它在纹理加载时运行,而当纹理加载时,程序将渲染纹理(渲染不是问题)。

1 个答案:

答案 0 :(得分:1)

此问题有两个部分:

通过单独的线程将图像上传到GPU

您需要在渲染线程和加载线程上都设置一个OpenGL上下文,并将它们配置为共享资源。我只用Qt做到了,但是this SDL2 thread听起来很有希望。这样,您就可以在加载线程上调用EnsureInitialized()并生成可从两个上下文访问的OpenGL纹理ID。

将结果传达回另一个线程

您对LoadFromFile有了正确的想法,但随后选择立即阻止它。 相反,您应该将返回的std::async存储在某个位置,并在渲染循环的每次迭代中检查它是否为std::future。一旦有效,请抓取结果并将其存储在渲染循环本地状态下。 (即局部变量),从那时起,您显然不再需要检查未来。

更通用的机制可能是使用一个.valid()来将纹理名称映射到OpenGL纹理ID。可以将加载的纹理初始化为已知无效的枚举,而加载的纹理将包含纹理ID。