objective-c - 顶点数组对象 (VAO) 能否在 OpenGL ES 中的 EAGLContext 之间共享?

标签 objective-c ios multithreading opengl-es eaglcontext

剧透:我相当有信心答案是NO,但这只是在经过一天非常沮丧的调试之后。现在我想知道情况是否确实如此(如果是这样,我怎么知道的),或者我是否只是在做一些完全错误的事情。

情况是这样的。我正在使用 OpenGL ES 2.0 渲染我从各种文件(.obj、.md2 等)加载的一些网格。为了性能和用户体验,我将这些网格及其相关纹理的实际加载委托(delegate)给使用 GCD 的后台线程。

根据 Apple's instructions ,在每个后台线程上,我创建并设置了一个新的 EAGLContext,它与主渲染上下文具有相同的 shareGroup。这允许在后台线程上创建的 OpenGL 对象(如纹理和缓冲区对象)立即由主线程上的上下文使用。

这一直很顺利。现在,我最近了解到 Vertex Array Objects作为缓存与渲染某些缓冲区内容相关联的 OpenGL 状态的一种方式。它看起来不错,并且减少了渲染每个网格所需的样板状态检查和设置代码。最重要的是,Apple 还建议在其 Best Practices for Working with Vertex Data 中使用它们。指导。

但我在让 VAO 为我工作时遇到了严重的问题。就像我处理所有加载一样,我会在后台线程上将文件中的网格加载到内存中,然后生成所有关联的 OpenGL 对象。毫无疑问,我第一次尝试使用 VAO 调用 glDrawElements() 时,应用程序崩溃并显示 EXC_BAD_ACCESS。没有 VAO,它渲染得很好。

调试 EXC_BAD_ACCESS 很痛苦,尤其是当 NSZombies 无济于事时(它们显然无济于事),但在分析捕获的 OpenGL 帧一段时间后,我意识到,在创建后台线程上的 VAO 运行良好(没有 GL_ERROR,并且 id 非零),当绑定(bind)到主线程上的 VAO 时,我会得到一个 GL_INVALID_OPERATION,其中 the docs尝试绑定(bind)到不存在的 VAO 时会发生状态。果然,在渲染时查看当前上下文中的所有对象时,看不到一个 VAO,但是所有使用 VAO 生成的 VBO AT THE同时出现。如果我在主线程上加载 VAO,它工作正常。非常令人沮丧。

我将加载代码提炼为更原子的形式:

- (void)generate {

    glGenVertexArraysOES(1, &_vao);
    glBindVertexArrayOES(_vao);

    _vbos = malloc(sizeof(GLuint) * 4);
    glGenBuffers(4, vbos);
}

当上面的代码在后台线程上执行时,有一个有效的 EAGLContext 和相同的 shareGroup 作为主上下文,主上下文将有 4 个 VBO,但没有VAO。如果我在主线程上执行它,在主上下文中,它将有 4 个 VBO 和 VAO。这使我得出结论,在处理 VAO 时,EAGLContext 的对象共享性质存在一些奇怪的异常(exception)。如果真是这样,我真的希望 Apple 文档能在某处注明这一点。必须手动发现这样的小花絮是非常不方便的。是这样吗,还是我遗漏了什么?

最佳答案

根据 this , OpenGL-ES 明确禁止共享 VAO 对象:

Should vertex array objects be sharable across multiple OpenGL ES contexts?

RESOLVED: No. The OpenGL ES working group took a straw-poll and agreed that compatibility with OpenGL and ease of implementation were more important than creating the first non-shared named object in OpenGL ES.

如您所述,VBO 仍然是可共享的,因此您只需为绑定(bind)共享 VBO 的每个上下文创建一个 VAO。

关于objective-c - 顶点数组对象 (VAO) 能否在 OpenGL ES 中的 EAGLContext 之间共享?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7125257/

相关文章:

objective-c - Cocoa 应用程序处理标准 HTTP url 方案

objective-c - 我可以让 AFNetworking 自动将 NULL 解析为 nil 吗?

ios - 应用程序崩溃,+[SVGKImage imageWithSource :] 中的 *** 断言失败

java - 如果我保留对 Runnable 的引用,它运行的线程何时会被释放?

java - 如何在 spring-batch 中拆分和加入流程以配置作业中的设置和拆卸步骤

ios - 初始化字符串,为什么需要@?

objective-c - 来自数组的随机 NSNumber

swift - 暂停和重新启动辅助同步线程

objective-c - 如何从iPhone应用程序中的服务器播放视频URL

ios - Firebase iOS/Swift 和深层链接