首页 > 解决方案 > 创建多个帧缓冲区

问题描述

我已经能够创建单个帧缓冲区并将其渲染为纹理。但是,当我尝试创建另一个时,我开始得到非常奇怪的结果。

我了解到,首先生成帧缓冲区,然后生成纹理应该会给我正确的结果。但是在我的情况下,我有一个在第一个和第二个帧缓冲区之间“共享”的纹理。见代码:

func (o *OpenGL) Init() {
    o.opaqueFBO = newFramebuffer()
    o.transparentFBO = newFramebuffer()

    // OPAQUE FBO
    gl.BindFramebuffer(gl.FRAMEBUFFER, o.opaqueFBO)
    opaqueFBOAttachments := []attachment{
        attachment{&o.opaqueTex0, gl.RGBA, gl.RGBA, gl.FLOAT, gl.COLOR_ATTACHMENT0},
        attachment{&o.sharedDepthBuffer, gl.DEPTH_COMPONENT, gl.DEPTH_COMPONENT, gl.FLOAT, gl.DEPTH_ATTACHMENT},
    }
    o.attachFramebufferTextures(o.opaqueFBO, opaqueFBOAttachments)
    gl.BindFramebuffer(gl.FRAMEBUFFER, 0)

    // TRANSPARENT FBO
    gl.BindFramebuffer(gl.FRAMEBUFFER, o.transparentFBO)
    transparentFBOAttachments := []attachment{
        attachment{&o.transparentTex0, gl.RGB, gl.RGB, gl.FLOAT, gl.COLOR_ATTACHMENT0},
        attachment{&o.transparentTex1, gl.RGBA, gl.RGBA, gl.FLOAT, gl.COLOR_ATTACHMENT1},
        attachment{&o.sharedDepthBuffer, gl.DEPTH_COMPONENT, gl.DEPTH_COMPONENT, gl.FLOAT, gl.DEPTH_ATTACHMENT},
    }
    o.attachFramebufferTextures(o.transparentFBO, transparentFBOAttachments)
    gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
}

// attachFramebufferTextures attaches textures to an existing framebuffer. Has a check to reuse one if it already has a value
func (o *OpenGL) attachFramebufferTextures(fib uint32, a []attachment) {
    for _, att := range a {
        if *att.textureID <= 0 {
            gl.GenTextures(1, att.textureID)
            gl.BindTexture(gl.TEXTURE_2D, *att.textureID)
            gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT)
            gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT)
            gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
            gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
            gl.TexImage2D(gl.TEXTURE_2D, 0, att.internalFormat, int32(o.screenWidth), int32(o.screenHeight), 0, att.format, att.typ, nil)
        } else {
            log.Printf("> DEBUG: Texture %v seems to be shared with another framebuffers", *att.textureID)
            gl.BindTexture(gl.TEXTURE_2D, *att.textureID)
        }

        gl.FramebufferTexture2D(gl.FRAMEBUFFER, att.point, gl.TEXTURE_2D, *att.textureID, 0)
        // gl.BindTexture(gl.TEXTURE_2D, 0)
    }

    if gl.CheckFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE {
        log.Fatalf("Framebuffer Error Hex: 0x%x\nNow go look it up here: https://raw.githubusercontent.com/go-gl/gl/master/v4.5-core/gl/package.go", gl.CheckFramebufferStatus(gl.FRAMEBUFFER))
    }
}

// newFramebuffer generates and returns a new framebuffer
func newFramebuffer() uint32 {
    var fid uint32
    gl.GenFramebuffers(1, &fid)
    return fid
}

type attachment struct {
    textureID      *uint32
    internalFormat int32
    format         uint32
    typ            uint32
    point          uint32
}

所以我从测试中注意到的一些事情如下:

-更改“OPAQUE FBO”和“TRANSPARENT FBO”代码块的顺序会产生不同的结果。为什么?当我使用 then 时它们都被绑定,然后在我完成后解除绑定。

- 当我单独渲染每个帧缓冲区时,结果是我所期望的。但是,当我最终将它们作为纹理渲染到默认帧缓冲区时,我只是得到一个黑屏。我认为黑色可能与以下代码有关

bindFramebuffer(o.transparentFBO)
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
gl.DrawBuffers(2, &[]uint32{gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1}[0])
gl.ClearBufferfv(gl.COLOR, 0, &[]float32{0, 0, 0, 1}[0])
gl.ClearBufferfv(gl.COLOR, 1, &[]float32{1, 1, 1, 1}[0])

更新

所以黑屏必须完成我如何将纹理绑定到着色器。我必须在运行gl.ActiveTexture(gl.TEXTURE0 + n) 之前先执行gl.BindTexture(...)。非常扼杀,但它就是这样。

我现在唯一的问题是以某种方式在两个 FBO 之间“共享”深度缓冲区。我什至不确定这是否是我应该做的,但我引用的代码似乎暗示了这一点。

标签: openglgoframebuffer

解决方案


推荐阅读