I've been able to create a single framebuffer and render it to a texture. However when I try to create another one I start getting very strange results.
I've learned that generating a framebuffer first and then it's textures should give me the correct results. However in my case I have a texture that is "shared" between the first and second framebuffer. See code:
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
Now 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
}
So a few things that I've noted from testing is as follows:
-Changing the order of the "OPAQUE FBO" and "TRANSPARENT FBO" code blocks give different results. Why? They are both bound when I use then, and then unbound once I'm done.
-When I render out each framebuffer alone, the results are what I expect. However when I eventually render them to the default framebuffer as textures, I just get a black screen. The black I think might have to do with the following code
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])
Update
So the black screen had to do how I bind textures to the shaders. I had to first execute gl.ActiveTexture(gl.TEXTURE0 + n)
BEFORE running gl.BindTexture(...)
. Very strangle but it is what it is.
The only problem I still have now is somehow "sharing" that depth buffer between the two FBOs. I'm not even sure anymore if it is what I'm supposed to do but the code I'm referencing seems to suggest it.