顶点数组对象(VAO)可以在OpenGL ES的EAGLContext中共享吗?
扰stream板:我相当有信心,答案是NO
,但这只是一个非常沮丧的debugging后一天。 现在我想知道这是否确实如此(如果是这样,我可能已经知道了),或者我只是在做一些完全错误的事情。
这是情况。 我正在使用OpenGL ES 2.0来呈现从各种文件(.obj,.md2等)加载的一些网格。 为了性能和用户体验,我使用GCD将这些网格及其关联纹理的实际加载委托给后台线程。
根据Apple的 说明 ,在每个后台线程上,我使用与主渲染上下文相同的shareGroup
创build并设置了一个新的EAGLContext。 这允许在后台线程上创build的OpenGL对象,如纹理和缓冲区对象,被主线程上下文立即使用。
这一直是出色的。 现在,我最近了解到顶点数组对象是一种caching与渲染某些缓冲区内容相关的OpenGL状态的方法。 它看起来不错,并减less了样板状态检查和设置渲染每个网格所需的代码。 最重要的是,苹果公司还build议在“ 使用顶点数据的最佳实践指南”中使用它们。
但是我有严重的问题让VAO为我工作。 就像我所有的加载,我会加载网格从一个文件到后台线程的内存,然后生成所有相关的OpenGL对象。 没有失败,我第一次尝试使用VAO调用glDrawElements()
,该应用程序崩溃与EXC_BAD_ACCESS
。 没有VAO,它渲染罚款。
debuggingEXC_BAD_ACCESS
是一件很痛苦的EXC_BAD_ACCESS
,特别是当NSZombies不会帮助的时候(他们显然不会这么做),但是在分析捕获的OpenGL帧之后,我意识到,在后台线程创buildVAO的时候没有问题GL_ERROR
和一个非零的id),当时间绑定到主线程上的VAO,我会得到一个GL_INVALID_OPERATION
,当试图绑定到一个不存在的VAO时,文档状态将会发生。 当然,在渲染时查看当前上下文中的所有对象时,不会看到单个VAO, 但是所有在同一时间内由VAO生成的VBO都存在 。 如果我在主线程加载VAO,它工作正常。 非常令人沮丧。
我将加载代码提炼成更primefaces的forms:
- (void)generate { glGenVertexArraysOES(1, &_vao); glBindVertexArrayOES(_vao); _vbos = malloc(sizeof(GLuint) * 4); glGenBuffers(4, vbos); }
当在后台线程上执行上述操作时,使用与主要上下文具有相同shareGroup
的有效EAGLContext
,主要上下文将有4个VBO,但不包含VAO。 如果我在主线上执行它,主要内容是4个VBO和VAO。 这使我得出这样的结论:在处理VAO时,EAGLContext的对象共享特性存在一些奇怪的例外。 如果真的是这样的话,我真的希望苹果的文档在某处注意到。 手工发现这些小花絮是非常不方便的。 这是这种情况,还是我错过了什么?
据此,OpenGL-ES明确禁止共享VAO对象:
顶点数组对象是否可以在多个OpenGL ES上下文中共享?
解决scheme:否。OpenGL ES工作组进行了一次稻草民意调查,并同意与OpenGL的兼容性和易于实现比在OpenGL ES中创build第一个非共享命名对象更重要。
正如你所提到的,VBOs仍然是可共享的,所以你只需要为绑定共享VBO的每个上下文创build一个VAO。