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

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

问题描述

Spoiler:我相当肯定答案是 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.

Per Apple的 说明,在每个后台线程上,我使用相同的创建并设置一个新的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 ,其中文档状态将在尝试绑定到不存在的VAO时发生。当然,在渲染时查看当前上下文中的所有对象时,没有一个VAO可以看到,但是所有使用VAO生成的VBO AT THE存在相同时间 。如果我在主线程上加载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);
}

如果在后台线程上执行上述操作,则有效 EAGLContext 使用相同的 shareGroup 作为主要上下文,主要上下文将有4个VBO,但没有VAO。如果我在主线程上执行它,使用主上下文,它将有4个VBO和VAO。这使我得出结论,在处理VAO时, EAGLContext 的对象共享性质存在一些奇怪的例外。如果确实如此,我真的希望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?

推荐答案

根据这个,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.

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

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