3

I'm trying to figure out how to create a framebuffer object that handles multisampling. Below is my attempt to get it working, but I keep getting GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT erros whenever I check my framebuffer status. I'm also getting this error even if I only attach the color buffer or only the depth/stencil buffer.

I've adapted this code from an older version without multisampling and which is able to create a complete framebuffer. I've left in those old calls but commented them out.

How do I set this up correctly?

void DocumentPanel::setupFramebuffer()
{
    QOpenGLFunctions_3_3_Core *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();

    int w = width();
    int h = height();
    int samples = 16;

    if (_frameBufferID == 0)
    {
        f->glGenFramebuffers(1, &_frameBufferID);
        f->glBindFramebuffer(GL_FRAMEBUFFER, _frameBufferID);
    }

    if (_texBufferColor == 0)
    {
        // generate texture
        f->glGenTextures(1, &_texBufferColor);
        f->glBindTexture(GL_TEXTURE_2D, _texBufferColor);
        f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        f->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        f->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//        f->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
        f->glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, w, h, false);
        f->glBindTexture(GL_TEXTURE_2D, 0);

        // attach it to currently bound framebuffer object
//        f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texBufferColor, 0);
        f->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, _texBufferColor, 0);
    }

    if (_renderBufferDepthStencilID == 0)
    {
        f->glGenRenderbuffers(1, &_renderBufferDepthStencilID);
        f->glBindRenderbuffer(GL_RENDERBUFFER, _renderBufferDepthStencilID);
//        f->glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, w, h);
        f->glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH24_STENCIL8, w, h);
        f->glBindRenderbuffer(GL_RENDERBUFFER, 0);

        f->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _renderBufferDepthStencilID);
    }

    GLenum status = f->glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (status != GL_FRAMEBUFFER_COMPLETE)
    {
        //error
        QString err;

        switch (status)
        {
        case GL_FRAMEBUFFER_UNDEFINED:
            err = "GL_FRAMEBUFFER_UNDEFINED";
        break;
        case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
            err = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
        break;
        case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT :
            err = "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT ";
        break;
        case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER :
            err = "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER ";
        break;
        case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER :
            err = "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER ";
        break;
        case GL_FRAMEBUFFER_UNSUPPORTED :
            err = "GL_FRAMEBUFFER_UNSUPPORTED ";
        break;
        case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE :
            err = "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE ";
        break;
        case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS  :
            err = "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS  ";
        break;
        }

        f->glBindFramebuffer(GL_FRAMEBUFFER, 0);

        qDebug() << "Error building frambuffer: " << err;
        return;
    }

    //Rendering to window again
    f->glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

1 Answer 1

3

GL_TEXTURE_2D and GL_TEXTURE_2D_MULTISAMPLE are different texture targets. Your code binds the texture to GL_TEXTURE_2D, but then tries to operate on it through GL_TEXTURE_2D_MULTISAMPLE, which cannot work.

Instead you should change ALL the targets to GL_TEXTURE_2D_MULTISAMPLE:

    f->glGenTextures(1, &_texBufferColor);
    f->glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _texBufferColor);
    f->glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, w, h, false);
    f->glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.