iOS和多个OpenGL视图

问题描述:

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

目前,它的表现不俗表现明智的,但也有一些恼人的毛刺。第3个OpenGL的视图显示没有问题,最后3 只显示几个三角形(同时仍可以旋转模型的能力)。也有一些情况下调用glDrawArrays调用会直接进入EXC_BAD_ACCESS(尤其是在模拟器上),它告诉我有什么毛病缓冲区。

我查什么(以及双和三选中):

  • 缓冲区分配似乎OK
  • 所有资源都被释放的dealloc上
  • 的仪器显示一些警告,但没有这似乎有关

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

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

无论如何,如果您有任何意见,谢谢你的分享!

好吧,我会回答我的问题,因为我终于找到了发生的事情。这是导致所有这些问题的一条小缺失线。

基本上,具有同时显示多个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帧,并且运行循环有时间调用所有渲染方法。

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

当你想多UIViews是openGLViews它变得非常棘手,

在这个网站,你应该能够阅读所有关于它:Using multiple openGL Views and uikit

+0

感谢您的链接;)但是,我为每个视图使用了不同的上下文,因为除了着色器之外,我没有使用任何共享的东西。我试图在每帧的开头重新绑定帧和渲染缓冲区,但问题仍然存在...... –