OpenGL FBO没有blitting深度缓冲区

时间:2014-03-10 18:55:14

标签: opengl framebuffer

我正在尝试创建一个FBO来绘制3D场景,另一个FBO用于绘制HUD。然后我尝试通过将3D场景blitting到默认FBO然后将HUD blit到默认FBO来组合这两个FBO。

创建的每个FBO都具有与窗口相同的尺寸,并且颜色附件和深度附件都具有RBO。

我期望发生的是3D FBO的blit将使用来自3D深度RBO的数据填充默认FBO的深度缓冲区,同时绘制3D颜色RBO的内容。然后第二个blit,即HUD,将HUD颜色RBO数据绘制到默认FBO中,其中HUD深度RBO是GL_LEQUAL默认FBO的深度数据。

  

旁注

     

我明白我可能想要的是用没有alpha的颜色清除HUD(目前我用< 1.0f,0.0f,1.0f,0.0f>清除)然后禁用深度测试和blit HUD到默认的FBO。这将确保HUD始终位于顶部。我打算这样做,但我需要先让深度检查版本工作。

目前正在发生的事情是3D FBO正在绘制到场景,然后HUD FBO完全覆盖它。对于背景应该具有透明清晰颜色的斑点也不清楚。他们完全覆盖了3D场景。

我错过了什么或不理解FBO blitting?深度检查是否可以正常工作,但是没有混合清晰的颜色alpha通道?

可以在此处找到单帧的OpenGL通话记录:
http://fpaste.org/84040/

计划详情

  • OpenGL上下文版本:4.0
  • GLX窗口颜色空间:RGBA8
  • GLX窗口深度尺寸:24
  • GLX窗口模板尺寸:8

开发系统详细信息

  • 操作系统:Ubuntu 12.04 LTS
  • 显卡:ATI Radeon HD 5750
  • 驱动程序版本:13.25.5

Blit Code

public void blit(int dstX = 0, int dstY = 0,
                 int dstWidth = 0, int dstHeight = 0,
                 uint targetFrameBuffer = 0)
{
   int mask;

   // Start out with nothing set.
   mask = 0;

   // See if we should blit the color buffer.
   if (color_buffer != null)
   {
      mask |= GL_COLOR_BUFFER_BIT;
   }

   // See if we should blit the depth buffer.
   if (depth_buffer != null)
   {
      mask |= GL_DEPTH_BUFFER_BIT;
   }

   // See if we should blit the stencil buffer.
   if (stencil_buffer != null)
   {
      mask |= GL_STENCIL_BUFFER_BIT;
   }

   // Make sure some mask was set before anything is done.
   if (mask != 0)
   {
      // Enable depth writing if a depth buffer is available.
      if (depth_buffer != null)
      {
         // Enable depth writing.
         glDepthMask(GL_TRUE);
      }

      // Bind the reading and drawing buffers.
      glBindFramebuffer(GL_READ_FRAMEBUFFER, reference);
      glReadBuffer(GL_COLOR_ATTACHMENT0);
      glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFrameBuffer);

      // If the target buffer is the default FBO,
      // then render to the back one.
      if (targetFrameBuffer == 0)
      {
         glDrawBuffer(GL_BACK);
      }

      glBlitFramebuffer(0, 0, width, height,
                        dstX, dstY, dstWidth, dstHeight,
                        mask, GL_NEAREST);

      // Unbind the buffers.
      glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
      glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

      // Disable depth writing if it was enabled earlier.
      if (depth_buffer != null)
      {
         // Disable depth writing.
         glDepthMask(GL_FALSE);
      }
   }
}

1 个答案:

答案 0 :(得分:4)

glBlitFramebuffer只是将一个像素块从一个缓冲区复制到另一个缓冲区。它没有使用深度缓冲区来接受或拒绝来自源缓冲区的像素。

您可以使用HUD纹理和深度缓冲区绘制四边形(假设您将深度纹理绑定到HUD FBO),从而实现您想要的效果。您需要在片段着色器中将深度纹理的值写入gl_FragDepth。

如果您使用alpha(正如您所说的那样),同样的事情也是如此,除非您只是使用HUD FBO的alpha值进行混合。这是更好的解决方案,因为它消除了HUD深度缓冲区。