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.