2013-10-29 129 views
4

我对FrameBuffers有点困惑。 目前,为了在屏幕上绘制,我使用此代码为GL_COLOR_ATTACHMENT0生成了一个带有渲染缓冲区的帧缓冲区。OpenGL ES 2.0和iOS中的默认FrameBuffer

-(void)initializeBuffers{ 

    //Build the main FrameBuffer 
    glGenFramebuffers(1, &frameBuffer); 
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer); 

    //Build the color Buffer 
    glGenRenderbuffers(1, &colorBuffer); 
    glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer); 

    //setup the color buffer with the EAGLLayer (it automatically defines width and height of the buffer) 
    [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:EAGLLayer]; 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &bufferWidth); 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &bufferHeight); 

    //Attach the colorbuffer to the framebuffer 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer); 

    //Check the Framebuffer status 
    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 

    NSAssert(status == GL_FRAMEBUFFER_COMPLETE, ERROR_FRAMEBUFFER_FAIL); 

} 

我显示了使用

[context presentRenderbuffer:GL_RENDERBUFFER]; 

阅读this question缓冲区的内容,我看到Arttu Peltonen的谁说注释:

默认帧缓冲区是你默认渲染,你没有 做任何事情来获得。 Framebuffer对象是您可以渲染到的东西,而这被称为“离屏渲染”。 如果你这样做,你最终得到的是你的图像纹理,而不是 默认帧缓冲区(显示在屏幕上)。您可以将 图像从该纹理复制到默认帧缓冲区(屏幕上),即 通常使用blitting完成(但它仅在OpenGL ES 3.0中提供)。 但是,如果你只是想在屏幕上显示图像,你可能 首先不会使用FBO。

所以我不知道我的方法是否只是用于离屏渲染。 在那种情况下,我必须做什么才能在默认缓冲区上呈现?! (注意,我不想使用GLKView ...)

回答

10

OpenGL ES规范提供了两种帧缓冲区:window-system-provided和framebuffer对象。默认帧缓冲区将是窗口系统提供的类型。但该规范并不要求窗口系统提供的帧缓冲区或默认帧缓冲区存在。

在iOS中,没有窗口系统提供的帧缓冲区,也没有默认帧缓冲区 - 所有的绘图都是通过帧缓冲区对象完成的。要渲染到屏幕上,您将创建一个渲染缓冲区,其存储来自CAEAGLLayer对象(或者您使用代表您创建的渲染缓冲区,就像使用GLKView类时一样)。这正是你的代码正在做的。

要进行离线渲染,您需要创建一个渲染缓冲区并调用glRenderbufferStorage为其分配存储空间。所述存储不与CAEAGLLayer相关联,以便渲染缓冲器不能(直接)出现在屏幕上。 (它也不是纹理 - 设置纹理作为渲染目标的工作方式不同 - 它只是一个离屏缓冲区。)

有关Apple的OpenGL ES Programming Guide for iOS中的每种方法的所有示例代码和示例代码的更多信息。