4

我对 FrameBuffers 有点困惑。目前,为了在屏幕上绘图,我生成了一个带有 Renderbuffer 的帧缓冲区,以GL_COLOR_ATTACHMENT0使用此代码。

-(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];

阅读这个问题,我看到了 Arttu Peltonen 的评论,他说:

默认帧缓冲区是您默认渲染到的位置,您无需执行任何操作即可获得它。帧缓冲区对象是您可以渲染的对象,某些人将其称为“屏幕外渲染”。如果你这样做,你的图像最终会出现在纹理中,而不是默认的帧缓冲区(显示在屏幕上)。您可以将图像从该纹理复制到默认帧缓冲区(在屏幕上),这通常通过 blitting 完成(但它仅在 OpenGL ES 3.0 中可用)。但如果您只想在屏幕上显示图像,您可能一开始就不会使用 FBO。

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

4

1 回答 1

13

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

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

要进行离屏渲染,您需要创建一个渲染缓冲区并调用glRenderbufferStorage为它分配存储空间。所述存储与 a 无关CAEAGLLayer,因此渲染缓冲区不能(直接)呈现在屏幕上。(它也不是纹理——将纹理设置为渲染目标的工作方式不同——它只是一个屏幕外缓冲区。)

Apple 的OpenGL ES Programming Guide for iOS中提供了有关所有这些内容和每种方法的示例代码的更多信息。

于 2013-10-29T18:30:22.480 回答