Spoiler:我非常有信心答案是NO
,但这只是经过一天非常沮丧的调试之后。现在,我想知道是否确实如此(如果可以,我可能是怎么知道的),或者我是否只是在做完全错误的事情。
这是情况。我正在使用OpenGL ES 2.0渲染一些我从各种文件(.obj,.md2等)加载的网格。出于性能和用户体验的考虑,我使用GCD将这些网格及其相关纹理的实际加载委托(delegate)给背景线程。
在每个后台线程上,对于Apple's instructions,我创建并设置一个新的EAGLContext,该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
,当尝试绑定(bind)到不存在的VAO时会出现the docs状态。可以肯定的是,在渲染时查看当前上下文中的所有对象时,没有一个VAO可以看到,但是存在用VAO 在同一时间生成的所有VBO。 。如果我将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)。如果真的是这样,我真的希望苹果公司的文档能够在某个地方注意到这一点。不得不手工发现这样的小花絮是非常不便的。是这种情况,还是我错过了什么? 最佳答案
根据this,OpenGL-ES明确禁止共享VAO对象:
如您所述,VBO仍然是可共享的,因此您只需为绑定(bind)共享VBO的每个上下文创建一个VAO。
关于objective-c - OpenGL ES中的EAGLContext之间可以共享顶点数组对象(VAO)吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7125257/