顶点数组对象 (VAO) 可以在 OpenGL ES 中跨 EAGLContext 共享吗? [英] Can Vertex Array Objects (VAOs) be shared across EAGLContexts in OpenGL ES?

查看:35
本文介绍了顶点数组对象 (VAO) 可以在 OpenGL ES 中跨 EAGLContext 共享吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

剧透:我相当确信答案是 NO,但这只是在经过一天非常沮丧的调试之后.现在我想知道情况是否确实如此(如果是,我可能怎么知道),或者我只是做错了什么.

Spoiler: I'm fairly confident that the answer is NO, but that's only after a day of very frustrated debugging. Now I would like to know if that is indeed the case (and if so, how I might have known), or if I'm just doing something completely wrong.

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

Here's the situation. I'm using OpenGL ES 2.0 to render some meshes that I load from various files (.obj, .md2, etc.). For the sake of performance and User Experience, I delegate the actual loading of these meshes and their associated textures to a background thread using GCD.

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

Per Apple's instructions, on each background thread, I create and set a new EAGLContext with the same shareGroup as the main rendering context. This allows OpenGL objects, like texture and buffer objects, that were created on the background thread to be immediately used by the context on the main thread.

这已经非常成功了.现在,我最近了解到 Vertex Array Objects 作为一种缓存与渲染相关的 OpenGL 状态的方法某些缓冲区的内容.它看起来不错,并减少了渲染每个网格所需的样板状态检查和设置代码.最重要的是,Apple 还建议在其 使用顶点数据的最佳实践指南.

This has been working out splendidly. Now, I recently learned about Vertex Array Objects as a way to cache the OpenGL state associated with rendering the contents of certain buffers. It looks nice, and reduces the boilerplate state checking and setting code required to render each mesh. On top of it all, Apple also recommends using them in their Best Practices for Working with Vertex Data guide.

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

But I was having serious issues getting the VAOs to work for me at all. Like I do with all loading, I would load the mesh from a file into memory on a background thread, and then generate all associated OpenGL objects. Without fail, the first time I tried to call glDrawElements() using a VAO, the app crashes with EXC_BAD_ACCESS. Without the VAO, it renders fine.

调试 EXC_BAD_ACCESS 很痛苦,尤其是当 NSZombies 没有帮助时(他们显然不会),但是在分析捕获的 OpenGL 帧一段时间后,我意识到,虽然创建后台线程上的 VAO 运行良好(没有 GL_ERROR 和非零 id),当绑定到主线程上的 VAO 时,我会得到一个 GL_INVALID_OPERATION,其中 docs 状态在尝试绑定到不存在的 VAO.果然,在渲染时查看当前上下文中的所有对象时,没有看到单个 VAO,但所有使用 VAO 生成的 VBO AT THESAME TIME在场.如果我在主线程上加载 VAO,它工作正常.非常令人沮丧.

Debugging EXC_BAD_ACCESS is a pain, especially when NSZombies won't help (which they obviously won't), but after some time of analyzing captured OpenGL frames, I realized that, while the creation of the VAO on the background thread went fine (no GL_ERROR, and a non-zero id), when the time came to bind to the VAO on the main thread, I would get a GL_INVALID_OPERATION, which the docs state will happen when attempting to bind to a non-existent VAO. And sure enough, when looking at all the objects in the current context at the time of rendering, there isn't a single VAO to be seen, but all of the VBOs that were generated with the VAO AT THE SAME TIME are present. If I load the VAO on the main thread it works fine. Very frustrating.

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

I distilled the loading code to a more atomic form:

- (void)generate {

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

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

当上述在后台线程上执行时,具有与主上下文相同的 shareGroup 的有效 EAGLContext,主上下文将有 4 个 VBO,但没有华奥.如果我在主线程上使用主上下文执行它,它将有 4 个 VBO 和 VAO.这使我得出结论,在处理 VAO 时,EAGLContexts 的对象共享性质存在一些奇怪的异常.如果情况确实如此,我真的希望 Apple 文档在某处注意到这一点.不得不手动发现这样的小花絮非常不方便.是这样吗,还是我错过了什么?

When the above is executed on a background thread, with a valid EAGLContext with the same shareGroupas the main context, the main context will have 4 VBOs, but no VAO. If I execute it on the main thread, with the main context, it will have 4 VBOs, and the VAO. This leads me to the conclusion that there is some weird exception to the object-sharing nature of EAGLContexts when dealing with VAOs. If that were actually the case, I would have really expected the Apple docs to note that somewhere. It's very inconvenient to have to discover little tidbits like that by hand. Is this the case, or am I missing something?

推荐答案

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

According to this, OpenGL-ES explicitly disallows sharing of VAO objects:

顶点数组对象是否可以在多个 OpenGL ES 之间共享上下文?

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

已解决:否.OpenGL ES 工作组进行了一次投票,并同意与 OpenGL 的兼容性和易于实施比创建第一个非共享命名对象更重要在 OpenGL ES 中.

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 仍然是可共享的,因此您只需为绑定共享 VBO 的每个上下文创建一个 VAO.

As you noted, VBOs are still shareable, so you just have to create a VAO for each context that binds the shared VBO.

这篇关于顶点数组对象 (VAO) 可以在 OpenGL ES 中跨 EAGLContext 共享吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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