OpenGL, как использовать depthbuffer из framebuffer как обычный буфер глубины

У меня есть буфер кадров, с компонентом глубины и 4 цветными вложениями с 4 текстурами

Я рисую в него некоторые вещи и разматываю буфер после этого, используя 4 текстуры для шейдера фрагментов (отложенное освещение). Позже я хочу нарисовать еще несколько вещей на экране, используя буфер глубины из моего фреймбуфера, возможно ли это?

Я снова попытался привязать фреймбуффер и указать glDrawBuffer (GL_FRONT), но он не работает.

3 ответов


Как уже сказал Николь, вы не можете использовать буфер глубины FBOs в качестве буфера глубины фреймбуффера по умолчанию напрямую.

но вы можете скопировать буфер глубины FBO в буфер кадров по умолчанию, используя EXT_framebuffer_blit расширение (которое должно быть ядром с GL 3):

glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, 
                  GL_DEPTH_BUFFER_BIT, GL_NEAREST);

Если это расширение не поддерживается (в чем я сомневаюсь, когда у вас уже есть FBOs), вы можете использовать текстуру глубины для вложения глубины FBO и отобразить это в фреймбуфер по умолчанию с использованием текстурированного квадрата и простого прохода через шейдер фрагментов, который записывает в gl_FragDepth. Хотя это может быть медленнее, чем просто выбросить все из головы.


Я только что испытал, что копирование буфера глубины из renderbuffer в основной (контекстный) буфер глубины очень ненадежно при использовании glBlitFramebuffer. Просто потому, что вы не можете гарантировать, что формат соответствует. Использование GL_DEPTH_COMPONENT24 в качестве внутреннего формата текстуры глубины просто не работало на моем AMD Radeon 6950 (последний драйвер), потому что Windows (или драйвер) решила использовать эквивалент GL_DEPTH24_STENCIL8 в качестве формата глубины для моего переднего / заднего буфера, хотя я этого не делал запросите любую точность трафарета (stencil-bits, установленные в 0 в дескрипторе формата пикселей). При использовании GL_DEPTH24_STENCIL8 для глубины текстуры моего фреймбуфера Blitting работал, как ожидалось, но у меня были другие проблемы с этим форматом. Первая попытка отлично работала на картах NVIDIA, поэтому я уверен, что ничего не испортил.

лучше всего (по моему опыту) работает копирование через шейдер:

фрагмент-программа (он же пиксель-шейдер) [GLSL]

#version 150

uniform sampler2D depthTexture;
in vec2 texCoords; //texture coordinates from vertex-shader

void main( void )
{
    gl_FragDepth = texture(depthTexture, texCoords).r;
}

код C++ для копирования выглядит так:

glDepthMask(GL_TRUE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glEnable(GL_DEPTH_TEST); //has to be enabled for some reason
glBindFramebuffer(GL_FRAMEBUFFER, 0);
depthCopyShader->Enable();
DrawFullscreenQuad(depthTextureIndex);

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


вы не можете прикрепить изображения (цвет или глубина) в буфер кадра по умолчанию. Аналогично, вы не можете взять изображения из фреймбуфера по умолчанию и прикрепить их к FBO.