iOS和多个OpenGL视图

我目前正在开发一个iPad应用程序,使用OpenGL在多个OpenGL视图中绘制一些非常简单的 (不超过1000或2000个顶点)旋转模型。 网格中有6个视图,每个视图运行自己的显示链接来更新graphics。 由于模型的简单性,它是迄今为止最简单的方法,我没有时间编写完整的OpenGL接口。

目前,它在性能方面做得很好,但也有一些恼人的故障。 前3个OpenGL视图显示没有问题,最后3个只显示几个三angular形 (同时仍然保留旋转模型的能力)。 还有一些情况下,glDrawArrays调用直接进入EXC_BAD_ACCESS (特别是在模拟器上),这告诉我缓冲区有问题。

我检查(以及双重和三重检查)是:

  • 缓冲区分配似乎还行
  • 所有资源都释放dealloc
  • 仪器显示一些警告,但似乎没有任何关系

我想这可能与我同时画多个视图有关,那么在那里我应该做什么已知的事情? 每个视图都有自己的上下文,但也许我做错了那个…

另外,我刚刚注意到,在模拟器中,受影响的视图在右图与所有顶点之间闪烁,而错误的绘图仅在less量之间闪烁。

无论如何,如果您有任何想法,谢谢分享!

好吧,自从我终于find了发生的事情之后,我会回答自己的问题。 这是造成所有这些问题的一个小小的缺失线。

基本上,要同时显示多个OpenGL视图,您需要:

  • 要么每个视图都有相同的上下文 。 在这里,你必须注意不要同时使用多个线程来绘制(就像在这个答案中解释的那样,以某种方式locking上下文),而且你必须在每一帧上重新绑定帧缓冲和渲染缓冲。
  • 或者 ,您可以为每个视图使用不同的上下文 。 然后,你必须重新设置 每个框架的上下文,因为其他显示链接,可能(并且会,在我的情况下)导致您的OpenGL调用使用错误的数据。 此外,由于您的上下文被保留,因此不需要重新绑定帧和渲染缓冲区。

另外,在每帧之后调用glFlush() ,告诉GPU完成每帧的渲染。

在我的情况下(第二个),渲染每一帧(iOS)的代码如下所示:

- (void) drawFrame:(CADisplayLink*)displayLink { // Set current context, assuming _context // is the class ivar for the OpenGL Context [EAGLContext setCurrentContext:_context] // Clear whatever you want glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // Do matrix stuff ... glUniformMatrix4fv (...); // Set your viewport glViewport (0, 0, self.frame.size.width, self.frame.size.height); // Bind object buffers glBindBuffer (GL_ARRAY_BUFFER, _vertexBuffer); glVertexAttribPointer (_glVertexPositionSlot, 3, ...); // Draw elements glDrawArrays (GL_TRIANGLES, 0, _currentVertexCount); // Discard unneeded depth buffer const GLenum discard[] = {GL_DEPTH_ATTACHMENT}; glDiscardFramebufferEXT (GL_FRAMEBUFFER, 1, discard); // Present render buffer [_context presentRenderbuffer:GL_RENDERBUFFER]; // Unbind and flush glBindBuffer (GL_ARRAY_BUFFER, 0); glFlush(); } 

编辑

我要编辑这个答案,因为我发现运行多个CADisplayLinks可能会导致一些问题。 您必须确保将您的CADisplayLink实例的frameInterval属性设置为0或1以外的值。否则,运行循环将只有时间调用第一个渲染方法,然后再次调用它。 就我而言,这就是为什么只有一个对象在移动。 现在,它被设置为3或4帧 ,运行循环有时间调用所有的渲染方法。

这仅适用于在设备上运行的应用程序。 模拟器速度很快,并不关心这样的事情。

当你需要多个openGLView的UIView时,

在这个网站上,你应该能够阅读所有关于它: 使用多个OpenGL视图和uikit