package gbuffer import ( "errors" "github.com/go-gl/gl/v4.6-core/gl" ) type GBuffer struct { framebuffer uint32 depth uint32 colorAttachments [4]uint32 // albedo, normal, material, position } var attachments = [...]uint32{ gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3, } func (b *GBuffer) Bind() { gl.BindFramebuffer(gl.FRAMEBUFFER, b.framebuffer) gl.DrawBuffers(int32(len(b.colorAttachments)), &attachments[0]) } func (b *GBuffer) BindTextures() { // albedo gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, b.colorAttachments[0]) // depth gl.ActiveTexture(gl.TEXTURE1) gl.BindTexture(gl.TEXTURE_2D, b.depth) // normal gl.ActiveTexture(gl.TEXTURE2) gl.BindTexture(gl.TEXTURE_2D, b.colorAttachments[1]) // material gl.ActiveTexture(gl.TEXTURE3) gl.BindTexture(gl.TEXTURE_2D, b.colorAttachments[2]) // position gl.ActiveTexture(gl.TEXTURE4) gl.BindTexture(gl.TEXTURE_2D, b.colorAttachments[3]) } func (b *GBuffer) Delete() { gl.DeleteFramebuffers(1, &b.framebuffer) for i, _ := range b.colorAttachments { gl.DeleteTextures(1, &b.colorAttachments[i]) } gl.DeleteTextures(1, &b.depth) } func New(width int, height int) (buffer GBuffer, _ error) { gl.GenFramebuffers(1, &buffer.framebuffer) gl.BindFramebuffer(gl.FRAMEBUFFER, buffer.framebuffer) var i uint32 = 0 // albedo gl.GenTextures(1, &buffer.colorAttachments[i]) gl.BindTexture(gl.TEXTURE_2D, buffer.colorAttachments[i]) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGB, int32(width), int32(height), 0, gl.RGB, gl.FLOAT, nil) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.BindTexture(gl.TEXTURE_2D, 0) gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0+i, gl.TEXTURE_2D, buffer.colorAttachments[i], 0) i++ // depth gl.GenTextures(1, &buffer.depth) gl.BindTexture(gl.TEXTURE_2D, buffer.depth) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, int32(width), int32(height), 0, gl.DEPTH_COMPONENT, gl.FLOAT, nil) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.BindTexture(gl.TEXTURE_2D, 0) gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, buffer.depth, 0) // normal gl.GenTextures(1, &buffer.colorAttachments[i]) gl.BindTexture(gl.TEXTURE_2D, buffer.colorAttachments[i]) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGB, int32(width), int32(height), 0, gl.RGB, gl.FLOAT, nil) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.BindTexture(gl.TEXTURE_2D, 0) gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0+i, gl.TEXTURE_2D, buffer.colorAttachments[i], 0) i++ // material gl.GenTextures(1, &buffer.colorAttachments[i]) gl.BindTexture(gl.TEXTURE_2D, buffer.colorAttachments[i]) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGB, int32(width), int32(height), 0, gl.RGB, gl.FLOAT, nil) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.BindTexture(gl.TEXTURE_2D, 0) gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0+i, gl.TEXTURE_2D, buffer.colorAttachments[i], 0) i++ // position gl.GenTextures(1, &buffer.colorAttachments[i]) gl.BindTexture(gl.TEXTURE_2D, buffer.colorAttachments[i]) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGB, int32(width), int32(height), 0, gl.RGB, gl.FLOAT, nil) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.BindTexture(gl.TEXTURE_2D, 0) gl.FramebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0+i, gl.TEXTURE_2D, buffer.colorAttachments[i], 0) i++ if gl.CheckFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE { return buffer, errors.New("failed to create framebuffer") } gl.BindFramebuffer(gl.FRAMEBUFFER, 0) return buffer, nil }