OpenGL在单独的线程中加载资源 [英] OpenGL loading resource in separated thread

查看:142
本文介绍了OpenGL在单独的线程中加载资源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是多线程OpenGL的新手.我不想在单独的线程中使用共享上下文.我找到了一种可以映射内存以进行异步资源加载的方法.

I am new to multithread OpenGL. I don't want to use shared context in separated thread. I found a way that we can map memory to do asynchronous resource loading.

但是我需要告诉glBufferData或glTexImage2D为我保留确切的内存大小.对于BMP,我们在标题中包含信息.但是要知道obj文件中的顶点数,我们需要遍历整个文件...商业游戏引擎如何做到这一点?设计自己的格式?

However I need to tell glBufferData or glTexImage2D to reserve the exact memory size for me. For BMP, we have information in the header. But to know the number of vertices in an obj file, we need to iterate through the whole file... How do commercial game engine do it? Design its own format?

推荐答案

一种对我有用的异步加载资源的方法是将不可避免的文件读取操作推入指定的线程中.它可以轻松地与惰性资源管理相结合,如下所示:

A way to load resources asynchronously that worked for me is to push the inevitable read-from-file operations into designated threads. It can be easily combined with lazy resource management like so:

  1. 设置场景,但不要立即从文件中加载资源.而是将其标记为unitialized并存储文件路径以供以后使用.
  2. 开始渲染场景
  3. 一旦遇到标记为uninitialized的资源,请启动一个线程,该线程将文件中的数据异步加载到 CPU 缓冲区中并存储元信息(例如,纹理的宽度和高度,数字网格等的顶点).现在,将请求的资源替换为默认值或简单地不执行任何操作"(假设渲染器可以处理空"资源).
  4. 在随后的渲染步骤和对资源的请求中,检查关联的加载线程是否已完成,如果已完成,则创建必要的 GPU 缓冲区,上传数据并将资源标记为initialized .存储的元数据可帮助您确定生成的缓冲区的必要大小.您现在可以按预期使用资源.
  1. Set up your scene but don't immediately load your resources from file. Instead, flag it as unitialized and store the file paths for later use.
  2. Start rendering your scene
  3. As soon as you encounter a resource flagged as uninitialized, start a thread that asynchronously loads the data from file into a CPU buffer and store meta info (e.g. width and height of textures, number of vertices for meshes etc.) as well. For now, replace the requested resource by some default or simply "do nothing" (assuming your renderer can handle "empty" resources).
  4. In subsequent rendering steps and requests for the resource, check if the associated loading thread has finished and, if so, create the necessary GPU buffers, upload the data and flag the resource as initialized. The stored metadata helps you to figure out the necessary size of the resulting buffers. You can now use the resource as intended.

以这种方式处理资源可避免在多个线程之间共享OpenGL上下文,因为您只能异步处理(可能很繁重)CPU绑定的从文件加载"操作.当然,您将不得不应对相互排斥的问题,以安全地检查加载线程是否已完成.此外,您可能会考虑定义和维护上传预算,以限制每帧从CPU传输到GPU的数据量,以避免帧率下降.

Handling resources this way avoids sharing OpenGL contexts between multiple threads since you only handle the (presumably very heavy) CPU-bound load-from-file operations asynchronously. Of course, you will have to cope with mutual exclusion to safely check whether or not a loading thread has finished. Furthermore, you might consider defining and maintaining an upload budget for limiting the amount of data transferred from CPU to GPU per frame in order to avoid framerate drops.

这篇关于OpenGL在单独的线程中加载资源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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