mirror of
https://github.com/bloeys/nmage.git
synced 2025-12-29 13:28:20 +00:00
Cubemap depth fbo attachments
This commit is contained in:
@ -11,6 +11,7 @@ const (
|
|||||||
FramebufferAttachmentType_Unknown FramebufferAttachmentType = iota
|
FramebufferAttachmentType_Unknown FramebufferAttachmentType = iota
|
||||||
FramebufferAttachmentType_Texture
|
FramebufferAttachmentType_Texture
|
||||||
FramebufferAttachmentType_Renderbuffer
|
FramebufferAttachmentType_Renderbuffer
|
||||||
|
FramebufferAttachmentType_Cubemap
|
||||||
)
|
)
|
||||||
|
|
||||||
func (f FramebufferAttachmentType) IsValid() bool {
|
func (f FramebufferAttachmentType) IsValid() bool {
|
||||||
@ -19,6 +20,8 @@ func (f FramebufferAttachmentType) IsValid() bool {
|
|||||||
case FramebufferAttachmentType_Texture:
|
case FramebufferAttachmentType_Texture:
|
||||||
fallthrough
|
fallthrough
|
||||||
case FramebufferAttachmentType_Renderbuffer:
|
case FramebufferAttachmentType_Renderbuffer:
|
||||||
|
fallthrough
|
||||||
|
case FramebufferAttachmentType_Cubemap:
|
||||||
return true
|
return true
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -169,6 +172,10 @@ func (fbo *Framebuffer) NewColorAttachment(
|
|||||||
logging.ErrLog.Fatalf("failed creating color attachment for framebuffer due to unknown attachment type. Type=%d\n", attachType)
|
logging.ErrLog.Fatalf("failed creating color attachment for framebuffer due to unknown attachment type. Type=%d\n", attachType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if attachType == FramebufferAttachmentType_Cubemap {
|
||||||
|
logging.ErrLog.Fatalf("failed creating color attachment because cubemaps can not be color attachments (at least in this implementation. You might be able to do it manually)\n")
|
||||||
|
}
|
||||||
|
|
||||||
if !attachFormat.IsColorFormat() {
|
if !attachFormat.IsColorFormat() {
|
||||||
logging.ErrLog.Fatalf("failed creating color attachment for framebuffer due to attachment data format not being a valid color type. Data format=%d\n", attachFormat)
|
logging.ErrLog.Fatalf("failed creating color attachment for framebuffer due to attachment data format not being a valid color type. Data format=%d\n", attachFormat)
|
||||||
}
|
}
|
||||||
@ -304,6 +311,30 @@ func (fbo *Framebuffer) NewDepthAttachment(
|
|||||||
|
|
||||||
// Attach to fbo
|
// Attach to fbo
|
||||||
gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, a.Id)
|
gl.FramebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, a.Id)
|
||||||
|
|
||||||
|
} else if attachType == FramebufferAttachmentType_Cubemap {
|
||||||
|
|
||||||
|
// Create cubemap
|
||||||
|
gl.GenTextures(1, &a.Id)
|
||||||
|
if a.Id == 0 {
|
||||||
|
logging.ErrLog.Fatalf("failed to generate texture for framebuffer. GlError=%d\n", gl.GetError())
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.BindTexture(gl.TEXTURE_CUBE_MAP, a.Id)
|
||||||
|
for i := 0; i < 6; i++ {
|
||||||
|
gl.TexImage2D(uint32(gl.TEXTURE_CUBE_MAP_POSITIVE_X+i), 0, attachFormat.GlInternalFormat(), int32(fbo.Width), int32(fbo.Height), 0, attachFormat.GlFormat(), gl.FLOAT, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
|
||||||
|
gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
||||||
|
gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
|
||||||
|
gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
|
||||||
|
gl.TexParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE)
|
||||||
|
|
||||||
|
gl.BindTexture(gl.TEXTURE_2D, 0)
|
||||||
|
|
||||||
|
// Attach to fbo
|
||||||
|
gl.FramebufferTexture(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, a.Id, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fbo.UnBind()
|
fbo.UnBind()
|
||||||
|
|||||||
64
main.go
64
main.go
@ -127,10 +127,10 @@ var (
|
|||||||
demoFboOffset = gglm.NewVec2(0.75, -0.75)
|
demoFboOffset = gglm.NewVec2(0.75, -0.75)
|
||||||
demoFbo buffers.Framebuffer
|
demoFbo buffers.Framebuffer
|
||||||
|
|
||||||
renderToDepthMapFbo = true
|
showDirLightDepthMapFbo = true
|
||||||
depthMapFboScale = gglm.NewVec2(0.25, 0.25)
|
dirLightDepthMapFboScale = gglm.NewVec2(0.25, 0.25)
|
||||||
depthMapFboOffset = gglm.NewVec2(0.75, -0.2)
|
dirLightDepthMapFboOffset = gglm.NewVec2(0.75, -0.2)
|
||||||
depthMapFbo buffers.Framebuffer
|
dirLightDepthMapFbo buffers.Framebuffer
|
||||||
|
|
||||||
screenQuadVao buffers.VertexArray
|
screenQuadVao buffers.VertexArray
|
||||||
screenQuadMat *materials.Material
|
screenQuadMat *materials.Material
|
||||||
@ -140,7 +140,7 @@ var (
|
|||||||
containerMat *materials.Material
|
containerMat *materials.Material
|
||||||
palleteMat *materials.Material
|
palleteMat *materials.Material
|
||||||
skyboxMat *materials.Material
|
skyboxMat *materials.Material
|
||||||
depthMapMat *materials.Material
|
dirLightDepthMapMat *materials.Material
|
||||||
debugDepthMat *materials.Material
|
debugDepthMat *materials.Material
|
||||||
|
|
||||||
cubeMesh *meshes.Mesh
|
cubeMesh *meshes.Mesh
|
||||||
@ -437,7 +437,7 @@ func (g *Game) Init() {
|
|||||||
|
|
||||||
debugDepthMat = materials.NewMaterial("Debug depth mat", "./res/shaders/debug-depth.glsl")
|
debugDepthMat = materials.NewMaterial("Debug depth mat", "./res/shaders/debug-depth.glsl")
|
||||||
|
|
||||||
depthMapMat = materials.NewMaterial("Depth Map mat", "./res/shaders/depth-map.glsl")
|
dirLightDepthMapMat = materials.NewMaterial("Depth Map mat", "./res/shaders/depth-map.glsl")
|
||||||
|
|
||||||
skyboxMat = materials.NewMaterial("Skybox mat", "./res/shaders/skybox.glsl")
|
skyboxMat = materials.NewMaterial("Skybox mat", "./res/shaders/skybox.glsl")
|
||||||
skyboxMat.CubemapTex = skyboxCmap.TexID
|
skyboxMat.CubemapTex = skyboxCmap.TexID
|
||||||
@ -484,22 +484,32 @@ func (g *Game) initFbos() {
|
|||||||
assert.T(demoFbo.IsComplete(), "Demo fbo is not complete after init")
|
assert.T(demoFbo.IsComplete(), "Demo fbo is not complete after init")
|
||||||
|
|
||||||
// Depth map fbo
|
// Depth map fbo
|
||||||
depthMapFbo = buffers.NewFramebuffer(1024, 1024)
|
dirLightDepthMapFbo = buffers.NewFramebuffer(1024, 1024)
|
||||||
depthMapFbo.SetNoColorBuffer()
|
dirLightDepthMapFbo.SetNoColorBuffer()
|
||||||
depthMapFbo.NewDepthAttachment(
|
dirLightDepthMapFbo.NewDepthAttachment(
|
||||||
buffers.FramebufferAttachmentType_Texture,
|
buffers.FramebufferAttachmentType_Texture,
|
||||||
buffers.FramebufferAttachmentDataFormat_DepthF32,
|
buffers.FramebufferAttachmentDataFormat_DepthF32,
|
||||||
)
|
)
|
||||||
|
|
||||||
assert.T(depthMapFbo.IsComplete(), "Depth map fbo is not complete after init")
|
assert.T(dirLightDepthMapFbo.IsComplete(), "Depth map fbo is not complete after init")
|
||||||
|
|
||||||
|
// Cubemap fbo
|
||||||
|
cubemapFbo := buffers.NewFramebuffer(1024, 1024)
|
||||||
|
cubemapFbo.SetNoColorBuffer()
|
||||||
|
cubemapFbo.NewDepthAttachment(
|
||||||
|
buffers.FramebufferAttachmentType_Cubemap,
|
||||||
|
buffers.FramebufferAttachmentDataFormat_DepthF32,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert.T(cubemapFbo.IsComplete(), "Cubemap fbo is not complete after init")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Game) updateLights() {
|
func (g *Game) updateLights() {
|
||||||
|
|
||||||
// Directional light
|
// Directional light
|
||||||
whiteMat.ShadowMap = depthMapFbo.Attachments[0].Id
|
whiteMat.ShadowMap = dirLightDepthMapFbo.Attachments[0].Id
|
||||||
containerMat.ShadowMap = depthMapFbo.Attachments[0].Id
|
containerMat.ShadowMap = dirLightDepthMapFbo.Attachments[0].Id
|
||||||
palleteMat.ShadowMap = depthMapFbo.Attachments[0].Id
|
palleteMat.ShadowMap = dirLightDepthMapFbo.Attachments[0].Id
|
||||||
|
|
||||||
// Point lights
|
// Point lights
|
||||||
for i := 0; i < len(pointLights); i++ {
|
for i := 0; i < len(pointLights); i++ {
|
||||||
@ -752,15 +762,15 @@ func (g *Game) showDebugWindow() {
|
|||||||
|
|
||||||
// Demo fbo
|
// Demo fbo
|
||||||
imgui.Text("Demo Framebuffer")
|
imgui.Text("Demo Framebuffer")
|
||||||
imgui.Checkbox("Render to demo FBO", &renderToDemoFbo)
|
imgui.Checkbox("Show FBO##0", &renderToDemoFbo)
|
||||||
imgui.DragFloat2("Scale##0", &demoFboScale.Data)
|
imgui.DragFloat2("Scale##0", &demoFboScale.Data)
|
||||||
imgui.DragFloat2("Offset##0", &demoFboOffset.Data)
|
imgui.DragFloat2("Offset##0", &demoFboOffset.Data)
|
||||||
|
|
||||||
// Depth map fbo
|
// Depth map fbo
|
||||||
imgui.Text("Depth Map Framebuffer")
|
imgui.Text("Directional Light Depth Map Framebuffer")
|
||||||
imgui.Checkbox("Render to depth map FBO", &renderToDepthMapFbo)
|
imgui.Checkbox("Show FBO##1", &showDirLightDepthMapFbo)
|
||||||
imgui.DragFloat2("Scale##1", &depthMapFboScale.Data)
|
imgui.DragFloat2("Scale##1", &dirLightDepthMapFboScale.Data)
|
||||||
imgui.DragFloat2("Offset##1", &depthMapFboOffset.Data)
|
imgui.DragFloat2("Offset##1", &dirLightDepthMapFboOffset.Data)
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
imgui.Text("Other Settings")
|
imgui.Text("Other Settings")
|
||||||
@ -845,13 +855,13 @@ func (g *Game) Render() {
|
|||||||
palleteMat.SetUnifVec3("camPos", &cam.Pos)
|
palleteMat.SetUnifVec3("camPos", &cam.Pos)
|
||||||
palleteMat.SetUnifMat4("dirLightProjViewMat", &dirLightProjViewMat)
|
palleteMat.SetUnifMat4("dirLightProjViewMat", &dirLightProjViewMat)
|
||||||
|
|
||||||
depthMapMat.SetUnifMat4("projViewMat", &dirLightProjViewMat)
|
dirLightDepthMapMat.SetUnifMat4("projViewMat", &dirLightProjViewMat)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Render depth map for shadows
|
// Render depth map for shadows
|
||||||
//
|
//
|
||||||
depthMapFbo.BindWithViewport()
|
dirLightDepthMapFbo.BindWithViewport()
|
||||||
depthMapFbo.Clear()
|
dirLightDepthMapFbo.Clear()
|
||||||
|
|
||||||
// Culling front faces helps 'peter panning' when
|
// Culling front faces helps 'peter panning' when
|
||||||
// drawing shadow maps, but works only for solids with a back face (i.e. quads won't cast shadows).
|
// drawing shadow maps, but works only for solids with a back face (i.e. quads won't cast shadows).
|
||||||
@ -859,15 +869,15 @@ func (g *Game) Render() {
|
|||||||
//
|
//
|
||||||
// Some note that this is too troublesome and fails in many cases. Might be better to remove.
|
// Some note that this is too troublesome and fails in many cases. Might be better to remove.
|
||||||
gl.CullFace(gl.FRONT)
|
gl.CullFace(gl.FRONT)
|
||||||
g.RenderScene(depthMapMat)
|
g.RenderScene(dirLightDepthMapMat)
|
||||||
gl.CullFace(gl.BACK)
|
gl.CullFace(gl.BACK)
|
||||||
|
|
||||||
depthMapFbo.UnBindWithViewport(uint32(g.WinWidth), uint32(g.WinHeight))
|
dirLightDepthMapFbo.UnBindWithViewport(uint32(g.WinWidth), uint32(g.WinHeight))
|
||||||
|
|
||||||
if renderToDepthMapFbo {
|
if showDirLightDepthMapFbo {
|
||||||
screenQuadMat.DiffuseTex = depthMapFbo.Attachments[0].Id
|
screenQuadMat.DiffuseTex = dirLightDepthMapFbo.Attachments[0].Id
|
||||||
screenQuadMat.SetUnifVec2("offset", depthMapFboOffset)
|
screenQuadMat.SetUnifVec2("offset", dirLightDepthMapFboOffset)
|
||||||
screenQuadMat.SetUnifVec2("scale", depthMapFboScale)
|
screenQuadMat.SetUnifVec2("scale", dirLightDepthMapFboScale)
|
||||||
screenQuadMat.Bind()
|
screenQuadMat.Bind()
|
||||||
window.Rend.DrawVertexArray(screenQuadMat, &screenQuadVao, 0, 6)
|
window.Rend.DrawVertexArray(screenQuadMat, &screenQuadVao, 0, 6)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user