【问题标题】:OpenGL ES Rendering thread on iOSiOS上的OpenGL ES渲染线程
【发布时间】:2017-07-24 08:40:31
【问题描述】:

我正在尝试对我的 iOS 应用程序进行多线程处理,以使其更具响应性。我想要一个线程来处理所有的 OpenGL 东西,比如渲染和加载缓冲区对象和纹理等。但我很难实现这一点。

我知道一个线程应该有它自己的上下文以便调用 gl 函数而不冒未定义行为的风险。所以在我的应用程序中,我在 OpenGL 专用线程中创建了一个新上下文,然后将其设置为当前上下文。然后我在该线程上进行所有加载和渲染。

我感到困惑的是 GLKView 上下文。我把它设置成什么?我是否将其设置为我在新线程中创建的上下文?还是我需要在主线程上创建另一个上下文并将其分配给它?然后让这两个上下文共享一个sharegroup?

【问题讨论】:

    标签: ios opengl-es


    【解决方案1】:

    这应该可行:

    1. 使用init(api:) 或使用init(api:shareGroup:) 并将nil 传递给第二个参数来创建您的背景上下文。
    2. 获取您刚刚创建的背景上下文的shareGroup
    3. 创建一个新的上下文,传递 2) 的 shareGroup 作为初始化器 init(api:shareGroup:) 的第二个参数。
    4. 使用 3) 中的上下文来初始化您的 GLKView。

    另外,请记住上下文之间的you can not share Vertex Array Objects。我曾经使用第二个上下文实现异步后台加载,但必须在后台初始化纹理、VBO 和 IBO,然后在主线程(例如,使用 GCD)上 Rendez-vouz(同步)来组装 VAO。真的很痛苦……

    【讨论】:

    • 感谢您的回答!我只是按照您的步骤操作,但仍然无法正常工作。为了澄清,1)在我的新线程上创建背景上下文。 2) 在主线程上,从 1) 获取共享组。 3)创建一个新的上下文并将其传递给共享组。 4) 使用 3) 中创建的上下文初始化 GLKView 上下文。现在,在应用程序的初始化阶段,我使用我的 gl 线程来加载 gl 的东西。然后在控制器中的绘图调用中,我使用 gl 线程绘制到屏幕。我是否需要将 VAO 与主线程上下文同步,即使我是从我的专用 gl 线程中绘制的?
    • 我刚刚阅读了这个答案stackoverflow.com/a/19874708/6066861,它说 GLKit 在绘制函数完成后直接将渲染缓冲区呈现给屏幕。由于我将绘图移动到我的 GL 特定线程,因此可能是 GLKit 绘图功能在我实际在线程上绘制任何内容之前完成。这意味着我必须等到线程完成其任务。这破坏了在另一个线程上执行此操作的意义。也许我试图实现的目标对于 GLKit 是不可行的。
    • 我明白了。我没有使用过 GLKit(只是普通的旧 OpenGL ES),但我总是在主线程/上下文上绘制。我只使用后台上下文来预加载大型资源。
    • 我还没有尝试过,但是应该可以在背景线程中对纹理执行绘制,然后在主上下文中使用该(共享)纹理进行纹理映射(例如)四边形等...我认为屏幕的最终渲染只能在主线程中完成,但我可能错了...
    • 我想我会使用主线程/上下文进行绘图,并使用后台线程/上下文进行预加载。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    相关资源
    最近更新 更多