GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT пытается создать мультисэмпловый буфер кадра

Я пытаюсь понять, как создать объект фреймбуфера, который обрабатывает мультисэмплинг. Ниже представлена ​​моя попытка заставить его работать, но я продолжаю получать ошибки GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT всякий раз, когда проверяю статус своего фреймбуфера. Я также получаю эту ошибку, даже если я присоединяю только буфер цвета или только буфер глубины / трафарета.

Я адаптировал этот код из более старой версии без мультисэмплинга, который позволяет создать полный кадровый буфер. Я оставил те старые звонки, но закомментировал их.

Как мне это правильно настроить?

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

person kitfox    schedule 24.01.2021    source источник


Ответы (1)


GL_TEXTURE_2D и GL_TEXTURE_2D_MULTISAMPLE - разные объекты текстуры. Ваш код привязывает текстуру к GL_TEXTURE_2D, но затем пытается работать с ней через GL_TEXTURE_2D_MULTISAMPLE, что не может работать.

Вместо этого вам следует изменить ВСЕ цели на 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);
person Yakov Galka    schedule 24.01.2021