Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL ES 2.0 and default FrameBuffer in iOS

Tags:

ios

opengl-es

I'm a bit confused about FrameBuffers. Currently, to draw on screen, I generate a framebuffer with a Renderbuffer for the GL_COLOR_ATTACHMENT0 using this code.

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

}

And I show the buffer content using

[context presentRenderbuffer:GL_RENDERBUFFER];

Reading this question, I saw the comment of Arttu Peltonen who says:

Default framebuffer is where you render to by default, you don't have to do anything to get that. Framebuffer objects are what you can render to instead, and that's called "off-screen rendering" by some. If you do that, you end up with your image in a texture instead of the default framebuffer (that gets displayed on-screen). You can copy the image from that texture to the default framebuffer (on-screen), that's usually done with blitting (but it's only available in OpenGL ES 3.0). But if you only wanted to show the image on-screen, you probably wouldn't use a FBO in the first place.

So I wonder if my method is just to be used for off-screen rendering. And in that case, what I have to do to render on the default buffer?! (Note, I don't want to use a GLKView...)

like image 946
MatterGoal Avatar asked Dec 12 '22 10:12

MatterGoal


1 Answers

The OpenGL ES spec provides for two kinds of framebuffers: window-system-provided and framebuffer objects. The default framebuffer would be the window-system-provided kind. But the spec doesn't require that window-system-provided framebuffers or a default framebuffer exist.

In iOS, there are no window-system-provided framebuffers, and no default framebuffer -- all drawing is done with framebuffer objects. To render to the screen, you create a renderbuffer whose storage comes from a CAEAGLLayer object (or you use one that's created on your behalf, as when using the GLKView class). That's exactly what your code is doing.

To do offscreen rendering, you create a renderbuffer and call glRenderbufferStorage to allocate storage for it. Said storage is not associated with a CAEAGLLayer, so that renderbuffer can't be (directly) presented on the screen. (It's not a texture either -- setting up a texture as a render target works differently -- it's just an offscreen buffer.)

There's more information about all of this and example code for each approach in Apple's OpenGL ES Programming Guide for iOS.

like image 61
rickster Avatar answered Dec 26 '22 00:12

rickster