【发布时间】:2014-03-10 18:55:13
【问题描述】:
我正在尝试创建一个用于绘制 3D 场景的 FBO 和另一个用于绘制 HUD 的 FBO。然后,我尝试通过将 3D 场景blitting 到默认FBO,然后将HUD blitting 到默认FBO 来组合这两个FBO。
创建的每个 FBO 都具有与窗口相同的尺寸,并且具有用于颜色附件和深度附件的 RBO。
我期望发生的是,在绘制 3D 彩色 RBO 的内容时,3D FBO 的 blit 将使用来自 3D 深度 RBO 的数据填充默认 FBO 的深度缓冲区。然后第二个 blit,HUD,会将 HUD 颜色 RBO 数据绘制到默认 FBO 中,其中 HUD 深度 RBO 为 GL_LEQUAL,即默认 FBO 的深度数据。
旁注
我知道我可能想要的是用没有 alpha 的颜色清除 HUD(目前我用 清除)然后禁用深度测试并对 HUD 进行 blit到默认的 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
位代码
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);
}
}
}
【问题讨论】:
-
我想纠正您代码 cmets 中的一些问题:
glDepthMask (GL_TRUE)不启用深度测试,而是启用深度写入。您可以在禁用深度写入的同时启用深度测试。另一方面(这与你的问题无关),你不能在没有启用深度测试的情况下写入深度缓冲区(如果你想无条件地写入,你需要设置一个深度函数@987654324 @)。 -
你是对的。我添加了 glEnable(GL_DEPTH_TEST) 和 glDisable(GL_DEPTH_TEST) 调用。现在这会导致绘图区域中不显示任何内容。我将对此进行进一步测试并发布后续消息。
-
同样重要的是要指出
glBlitFramebuffer (...)不执行任何类型的像素测试。启用或禁用深度测试毫无意义,现在我更好地了解您实际期望发生的事情。 Blitting 只是将一个或多个缓冲区从源帧缓冲区复制到目标,它可以执行过滤但不进行深度/模板测试。
标签: opengl framebuffer