Mat*_*ing 19 multithreading opengl-es objective-c eaglcontext ios
剧透:我对答案很有信心NO,但这只是经过一天非常沮丧的调试之后.现在我想知道是否确实如此(如果是这样,我可能知道的话),或者我是否只是做了一些完全错误的事情.
这是情况.我正在使用OpenGL ES 2.0来渲染我从各种文件(.obj,.md2等)加载的一些网格物体.为了性能和用户体验,我使用GCD将这些网格及其相关纹理的实际加载委托给后台线程.
根据Apple的 说明,在每个后台线程上,我创建并设置一个与shareGroup主渲染上下文相同的新EAGLContext .这允许在后台线程上创建的OpenGL对象(如纹理和缓冲区对象)立即被主线程上下文使用.
这一直在努力.现在,我最近了解到顶点数组对象是一种缓存与渲染某些缓冲区内容相关的OpenGL状态的方法.它看起来不错,并减少了样板状态检查和设置渲染每个网格所需的代码.最重要的是,Apple还建议在他们使用顶点数据的最佳实践指南中使用它们.
但是我在让VAO为我工作时遇到了严重的问题.就像我对所有加载一样,我会将网格从文件加载到后台线程的内存中,然后生成所有关联的OpenGL对象.没有失败,我第一次尝试glDrawElements()使用VAO 调用时,应用程序崩溃了EXC_BAD_ACCESS.没有VAO,它就会很好.
调试EXC_BAD_ACCESS是一种痛苦,特别是当NSZombies无法帮助时(他们显然不会这样做),但经过一段时间分析捕获的OpenGL帧后,我意识到,虽然在后台线程上创建VAO很顺利(不GL_ERROR,当一个时间来到主线程上的VAO时,我会得到一个GL_INVALID_OPERATION,当尝试绑定到一个不存在的VAO时,文档状态会发生.果然,看着在渲染时当前上下文中的所有对象的时候,没有一个单一的VAO待观察,但都与VAO生成的维也纳各组织在同一时间存在.如果我在主线程上加载VAO它可以正常工作.很沮丧.
我将加载代码提炼为更原子的形式:
- (void)generate {
glGenVertexArraysOES(1, &_vao);
glBindVertexArrayOES(_vao);
_vbos = malloc(sizeof(GLuint) * 4);
glGenBuffers(4, vbos);
}
Run Code Online (Sandbox Code Playgroud)
当在后台线程上执行上述操作时,如果有效EAGLContext与shareGroup主上下文相同,则主上下文将有4个VBO,但没有VAO.如果我在主线程上执行它,使用主上下文,它将有4个VBO和VAO.这使我得出结论,EAGLContext在处理VAO时,s 的对象共享性质存在一些奇怪的例外.如果确实如此,我真的希望Apple文档能够在某处注明.不得不手动发现这样的小花絮是非常不方便的.是这样的,还是我错过了什么?