iOS 和多个 OpenGL View

标签 ios opengl-es opengl-es-2.0

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

目前,它在性能方面表现良好,但存在一些恼人的故障。前 3 个 OpenGL View 显示没有问题,后 3 个只显示几个三角形(同时仍保留旋转模型的能力)。在某些情况下,glDrawArrays 调用会直接进入 EXC_BAD_ACCESS(尤其是在模拟器上),这告诉我缓冲区有问题。

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

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

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

此外,我刚刚注意到在模拟器中,受影响的 View 在包含所有顶点的正确绘图和只有少数顶点的错误绘图之间闪烁。

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

最佳答案

好吧,我要回答我自己的问题,因为我终于找到了发生了什么。这是导致所有这些问题的一个小缺失线。

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

  • Either,每个 View 的相同上下文。在这里,您必须注意不要同时使用多个线程进行绘制(即以某种方式锁定上下文,如 this answer 中所述。并且您必须每次在每一帧上重新绑定(bind)帧缓冲区和渲染缓冲区.
  • 或者,您可以为每个 View 使用不同的上下文。然后,您必须重新设置每一帧的上下文,因为其他显示链接可能(并且会像我的情况一样)导致您的 OpenGL 调用使用错误的数据。此外,由于您的上下文已保留,因此无需重新绑定(bind)帧缓冲区和渲染缓冲区。

此外,在每一帧之后调用 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 帧,运行循环有时间调用所有渲染方法。

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

关于iOS 和多个 OpenGL View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8111345/

相关文章:

ios - 警报 View 中的 TextField 未在 iOS 7 上显示

ios - SQLite 数据库安全和篡改

ios - 如何在 OpenGl ES Xcode 中以编程方式使用抗锯齿?

android - 如何将 SurfaceTexture 保存为位图

ios - 迦太基在特定平台更新后构建

android - android中的opengl es透明雾

android - AIDE OpenGL es 2.0 三角形无法渲染

android - 在 OpenGL 中同时使用多个渲染器

android - Nexus S 上的 OpenGL ES 黑色纹理

ios - 使用 iPad Pro 9.7"上的前置摄像头以 60 FPS 捕捉视频