我有两个FBOs+MRT,它们具有相同的附件(每个4个颜色附件)。使用glBlitFrameBuffer对于深度缓冲区和一个颜色附件按预期工作。然而,当我复制多个颜色附件时,情况变得糟糕。我做了很多研究并尝试了许多不同的方法,但都没有奏效。我没有使用renderBufferStorage,因为我的纹理具有不同的内部格式(RGBA和RGB16F)。这听起来像是一个类似的问题,只是我没有使用多重采样,只有MRT。
OpenGL版本为4.3
为什么:我想创建地形在光照计算之前的状态,这样只需要在有更改(例如相机移动)时渲染地形,然后将这些颜色附件复制到下一个FBO。这是用于延迟着色,FBOs非常类似于gBuffer。
起初我期望应该使用glDrawBuffers,因为我在初始设置中正在使用它,但是没有glReadBuffers,因此我认为我无法将它们链接起来。我可能在这里错了,还不是专家=)
原始代码是用Golang编写的,应该很容易转换为C++(如果需要,我会翻译)。
更新/解决:对于任何遇到此问题的人,请注意。当您使用glDrawBuffers()并使用对glDrawBuffer()的调用时,您正在覆盖glDrawBuffers()状态。它需要重置为其原始的glDrawBuffers()状态。
更新2:对于那些对此方法感兴趣的人,我可以确认它具有令人难以置信的性能结果,如果您拥有一个非动画世界,并且摄像机不经常移动。对于我的目的来说很棒(RTS),但对于像CS这样的FPS游戏来说,这将是一种非常糟糕的方法。
在blitting之后添加以下内容(特定情况):
FBO设置
OpenGL版本为4.3
为什么:我想创建地形在光照计算之前的状态,这样只需要在有更改(例如相机移动)时渲染地形,然后将这些颜色附件复制到下一个FBO。这是用于延迟着色,FBOs非常类似于gBuffer。
起初我期望应该使用glDrawBuffers,因为我在初始设置中正在使用它,但是没有glReadBuffers,因此我认为我无法将它们链接起来。我可能在这里错了,还不是专家=)
原始代码是用Golang编写的,应该很容易转换为C++(如果需要,我会翻译)。
更新/解决:对于任何遇到此问题的人,请注意。当您使用glDrawBuffers()并使用对glDrawBuffer()的调用时,您正在覆盖glDrawBuffers()状态。它需要重置为其原始的glDrawBuffers()状态。
更新2:对于那些对此方法感兴趣的人,我可以确认它具有令人难以置信的性能结果,如果您拥有一个非动画世界,并且摄像机不经常移动。对于我的目的来说很棒(RTS),但对于像CS这样的FPS游戏来说,这将是一种非常糟糕的方法。
在blitting之后添加以下内容(特定情况):
var attachments = [4]uint32{gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3}
gl.DrawBuffers(4, &attachments[0])
FBO设置
gl.GenFramebuffers(1, &fbo.ID)
gl.BindFramebuffer(gl.FRAMEBUFFER, fbo.ID)
//setting up color attachments
gl.GenTextures(1, &fbo.Position)
gl.BindTexture(gl.TEXTURE_2D, fbo.Position)
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGB16F, windowWidth, windowHeight, 0, gl.RGB, gl.FLOAT, nil)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fbo.Position, 0)
//repeated 3 times for the additional color attachments
var attachments = [4]uint32{gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3}
gl.DrawBuffers(4, &attachments[0])
gl.GenRenderbuffers(1, &fbo.DepthBuffer)
gl.BindRenderbuffer(gl.RENDERBUFFER, fbo.DepthBuffer)
gl.RenderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT, windowWidth, windowHeight)
gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, fbo.DepthBuffer)
gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
现在进入blitting部分。
gl.BindFramebuffer(gl.READ_FRAMEBUFFER, fboIn.ID)
gl.BindFramebuffer(gl.DRAW_FRAMEBUFFER, fboOut.ID)
//works as expected
gl.BlitFramebuffer(0, 0, windowWidth, windowHeight, 0, 0, windowWidth, windowHeight, gl.DEPTH_BUFFER_BIT, gl.NEAREST)
//works as expected
gl.ReadBuffer(gl.COLOR_ATTACHMENT0)
gl.DrawBuffer(gl.COLOR_ATTACHMENT0)
gl.BlitFramebuffer(0, 0, windowWidth, windowHeight, 0, 0, windowWidth, windowHeight, gl.COLOR_BUFFER_BIT, gl.LINEAR)
//fails - no errors but produces some weird occurrences.
gl.ReadBuffer(gl.COLOR_ATTACHMENT1)
gl.DrawBuffer(gl.COLOR_ATTACHMENT1)
gl.BlitFramebuffer(0, 0, windowWidth, windowHeight, 0, 0, windowWidth, windowHeight, gl.COLOR_BUFFER_BIT, gl.LINEAR)
gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
glDrawBuffer()
基本上撤销了你在FBO设置部分使用glDrawBuffers()
所设置的内容。绘制缓冲区状态是按FBO存储的,并且你在blitting时修改了它,但没有恢复它(至少在目前发布的代码片段中没有)。 - derhass