iOS和多个OpenGL视图

时间:2011-11-13 11:58:20

标签: ios opengl-es opengl-es-2.0

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

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

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

  • 缓冲区分配似乎没问题
  • 所有资源都在dealloc上释放
  • 这些乐器显示了一些警告,但没有任何相关内容

我认为这可能与我同时绘制多个视图有关,所以我应该在那里做任何已知的事情吗?每个视图都有自己的上下文,但也许我做错了......

另外,我只是注意到在模拟器中,受影响的视图在右图和所有顶点之间闪烁,而错误的绘图只有少数几个。

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

2 个答案:

答案 0 :(得分:9)

好的,我会回答我自己的问题,因为我终于找到了正在发生的事情。这是一个引起所有这些问题的小缺失线。

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

  • ,每个视图的相同上下文。在这里,你必须注意不要同时绘制多个线程(即以某种方式锁定上下文,如this answer所述。并且你必须每次重新绑定帧和渲染缓冲区每一帧。
  • ,您可以为每个视图使用不同的上下文。然后,您必须重新设置> 每个框架上下文,因为其他显示链接可能(并且会像我的情况一样)导致您的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帧,并且运行循环有时间调用所有渲染方法。

这仅适用于在设备上运行的应用程序。模拟器非常快,不关心这些事情。

答案 1 :(得分:0)

当你想要多个OpenGLViews的UIViews时,它会变得棘手,

在此网站上,您应该能够阅读所有相关信息:Using multiple openGL Views and uikit