OpenGL glBlitFramebuffer некорректно отбрасывает буфер цвета и глубины. Результаты проверены на glReadPixel

Я борюсь с функцией OpenGL glBlitFramebuffer. В документе говорится, что он поддерживает блиттинг как буфера цвета, так и буфера глубины. Однако на практике это не так. Я на MacBook AIR 13 дюймов, с Intel HD Graphics 5000 1536 МБ.

Мне нужно сделать мультисэмплинг из http://ake.in.th/2013/04/02/offscreening-and-multisampling-with-opengl/

Мой уровень мультисэмплинга 4 (AA_LEVEL = 4), моя версия OpenGL: 3.2 профиля ядра. Вот что я делаю:

  1. Создайте мультисэмпловый буфер кадра AA.

    glGenFramebuffers( 1, &_offscreenBufferHandle );
    glBindFramebuffer( GL_FRAMEBUFFER, _offscreenBufferHandle );
    
    glGenRenderbuffers(1, &_depthRenderbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderbuffer);
    glRenderbufferStorageMultisample(GL_RENDERBUFFER, AA_LEVEL, GL_DEPTH_COMPONENT16, srcWidth_, srcHeight_);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);
    
    glGenRenderbuffers(1, &_aaColorbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, _aaColorbuffer);
    glRenderbufferStorageMultisample(GL_RENDERBUFFER, AA_LEVEL, GL_RGBA, srcWidth_, srcHeight_);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);
    
  2. Создать целевой буфер кадров

    glGenFramebuffers( 1, &_outputBufferHandle );
    glBindFramebuffer( GL_FRAMEBUFFER, _outputBufferHandle );
    
    glGenRenderbuffers(1, &_outputColorbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, _outputColorbuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, srcWidth_, srcHeight_);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);
    
    glGenRenderbuffers(1, &_outputDepthbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, _outputDepthbuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, srcWidth_, srcHeight_);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);
    
  3. Нарисуйте материал с буфером цвета и глубины

    glBindFramebuffer( GL_DRAW_FRAMEBUFFER, _offscreenBufferHandle );
    glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _aaColorbuffer);
    glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderbuffer);
    //next
    DrawStuff();
    
  4. Поместите мультисэмпловый буфер кадра AA в буфер целевого кадра.

    glBindFramebuffer( GL_READ_FRAMEBUFFER, _offscreenBufferHandle );
    glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _aaColorbuffer);
    glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderbuffer);
    
    glBindFramebuffer( GL_DRAW_FRAMEBUFFER, _outputBufferHandle );
    glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _outputColorbuffer);
    glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _outputDepthbuffer);
    
    if( glCheckFramebufferStatus(GL_READ_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE &&
    glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE ) {
    //do blitting here
    glBlitFramebuffer(0, 0, srcWidth_, srcHeight_, 0, 0, srcWidth_, srcHeight_, GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT, GL_NEAREST);
    }
    
  5. Считайте пиксели из буфера целевого кадра и выполните некоторую постобработку

    //then blit it to pixels buffer
    glBindFramebuffer(GL_READ_FRAMEBUFFER, _outputBufferHandle);
    glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _outputColorbuffer);
    glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _outputDepthbuffer);
    readParam("temp");
    
    GLenum framebufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if( framebufferStatus == GL_FRAMEBUFFER_COMPLETE ) {
    glReadBuffer(GL_COLOR_ATTACHMENT0);
    //getGLErr("GL_COLOR_ATTACHMENT0");
    glReadPixels(0, 0, srcWidth_, srcHeight_, GL_BGR, GL_UNSIGNED_BYTE, pixels);
    }
    

Однако в результате ТОЛЬКО удаляется цветовой буфер, без буфера глубины.

Если я отключу мультисэмплинг, изменив значение AA_LEVEL = 0 и заменив этап удаления 4, замените шаг 5 следующим кодом для чтения непосредственно из _offscreenBufferHandle, результат будет выглядеть правильно.

glBindFramebuffer(GL_READ_FRAMEBUFFER, _offscreenBufferHandle);
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _aaColorbuffer);
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderbuffer);
GLenum framebufferStatus = glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
if( framebufferStatus == GL_FRAMEBUFFER_COMPLETE ) {
glReadPixels(0, 0, srcWidth_, srcHeight_, GL_BGR, GL_UNSIGNED_BYTE, pixels);
}

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

https://gamedev.stackexchange.com/questions/68290/fbo-blit-depth-buffer-to-screen

https://www.opengl.org/discussion_boards/showthread.php/176317-Framebuffer-not-bliting-depth-buffer

В этих статьях это означает, что мне нужно нарисовать текстурированный квад, чем сделать блиц из буфера чтения в буфер рисования. Это слишком много проблем.

0

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]