I've started updating my code to allow for multipass rendering. I'm fairly certain I'm doing framebuffers right but somehow I'm not getting the results I want. The code I'm using is based off the following tutorial: https://learnopengl.com/Advanced-OpenGL/Framebuffers
When I render to the default buffer I get exactly what I expect:
However when I render that to a non-default framebuffer texture and place it on a quad, I get this very puzzling result:
So my initial thinking is that there is something wrong with how I'm drawing the quad that my non-default framebuffer texture is placed on (the one spanning to all four corners of the window). But when rendering only that, with wireframes enabled, I getting exactly what I expect (and what the tutorial confirms I will get):
So that leaves me thinking there are two possible issues with my code:
When the non-default framebuffer draws everything to the texture, it is in some strange orientation and scale that results in everything rendering completely wrong (even though everything is perfect when rendered to the default framebuffer). Perhaps some previous buffer isn't cleared or there is something in the configuration that adjusts how the framebuffer renders onto the texture.
The texture is too small and when wrapped on the quad that is much bigger, it repeats the output and apparently somehow rotates... Notice how the objects are pulled skew when it crosses the diagonal line to the top-right triangle of the quad. This must be related to some issue...
framebuffer configuration
gl.GenFramebuffers(1, &o.fbo)
gl.BindFramebuffer(gl.FRAMEBUFFER, o.fbo)
gl.GenTextures(1, &o.cbo)
gl.BindTexture(gl.TEXTURE_2D, o.cbo)
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGB, int32(o.screenWidth), int32(o.screenHeight), 0, gl.RGB, gl.UNSIGNED_BYTE, nil)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, o.cbo, 0)
gl.GenRenderbuffers(1, &o.rbo)
gl.BindRenderbuffer(gl.RENDERBUFFER, o.rbo)
gl.RenderbufferStorage(gl.RENDERBUFFER, gl.DEPTH24_STENCIL8, int32(o.screenWidth), int32(o.screenHeight))
gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, o.rbo)
if gl.CheckFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE {
log.Fatal("Framebuffer incomplete")
}
gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
...
first pass draw
gl.BindFramebuffer(gl.FRAMEBUFFER, o.fbo)
gl.Enable(gl.DEPTH_TEST)
gl.ClearColor(clearColor.R, clearColor.G, clearColor.B, clearColor.A)
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
gl.UseProgram(o.shaderProgram)
...
draw each object
gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, gl.PtrOffset(0))
gl.UniformMatrix4fv(model_uni, 1, false, &model[0])
gl.BindVertexArray(0)
...
second pass draw
gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
gl.Disable(gl.DEPTH_TEST)
gl.ClearColor(1, 1, 1, 1)
gl.Clear(gl.COLOR_BUFFER_BIT)
gl.UseProgram(o.screenShaderProgram)
gl.BindVertexArray(o.quadVAO)
gl.BindTexture(gl.TEXTURE_2D, o.cbo)
gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, gl.PtrOffset(0))
o.window.SwapBuffers()
glfw32.PollEvents()
quad vao
vertices := []float32{
1.0, 1.0, 1.0, 1.0, // 0 top right
1.0, -1.0, 1.0, 0.0, // 1 bot right
-1.0, -1.0, 0.0, 0.0, // 2 bot left
-1.0, 1.0, 0.0, 1.0, // 3 top left
}
indicies := []uint8{
0, 1, 3,
1, 2, 3,
}
var vertexArrayID uint32
gl.GenVertexArrays(1, &vertexArrayID)
gl.BindVertexArray(vertexArrayID)
// Vertex buffer
var vertexBuffer uint32
gl.GenBuffers(1, &vertexBuffer)
gl.BindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW)
// Element buffer
var elementBuffer uint32
gl.GenBuffers(1, &elementBuffer)
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementBuffer)
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indicies)*4, gl.Ptr(indicies), gl.STATIC_DRAW)
// Linking vertex attributes
gl.VertexAttribPointer(0, 2, gl.FLOAT, false, 4*4, gl.PtrOffset(0))
gl.EnableVertexAttribArray(0)
// Linking texture attributes
gl.VertexAttribPointer(1, 2, gl.FLOAT, false, 3*4, gl.PtrOffset(2*4))
gl.EnableVertexAttribArray(1)
o.quadVAO = vertexArrayID
// Unbind Vertex array object
gl.BindVertexArray(0)
The stride of the texture coordinate pointer is wrong. It should be 4*4 instead of 3*4 since the start of two consecutive vertices is 4 floats away from each other.