Search code examples
openglframefbo

How to render to frame buffer without displaying on screen with OpenGL?


I knew it is possible to render offline without displaying it on screen.

How to do it, maybe

create an invisible window then draw.

Can I use specific fbo when render?


Solution

  • You can create a framebuffer object using something like:

    GLint fbo, tex; // "handles" for framebuffer and it's texture
    glGenFramebuffersEXT(1, &fbo);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
    
    // setup texture for colour attachment
    glGenTextures(1, &tex);
    glEnable(GL_TEXTURE_2D);
    glDisable(GL_COLOR_MATERIAL);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    // set a size fotr the texture, but not any initial data
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, fbo_resX, fbo_resY, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
    // You might want a depth attachment here too perhaps?
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, 0);
    
    const GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    assert(status == GL_FRAMEBUFFER_COMPLETE_EXT);
    
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    

    You then use it like:

    // specify which FBO to use
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
    // glDraw...
    
    // return to the default
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    

    You can create multiple framebuffers as you like and bind to them when you please. (Give or take). You'll need a valid OpenGL context to use this, which usually approximates to creating a window on most platforms, but you don't ever have to draw anything into that window.