Example #1
0
func main() {
	app := example.Open()
	defer app.Close()
	bgfx.Init()
	defer bgfx.Shutdown()

	bgfx.Reset(app.Width, app.Height, bgfx.ResetVSync)
	bgfx.SetDebug(bgfx.DebugText)
	bgfx.SetViewClear(
		0,
		bgfx.ClearColor|bgfx.ClearDepth,
		0x303030ff,
		1.0,
		0,
	)

	caps := bgfx.Caps()
	originBottomLeft := false
	switch caps.RendererType {
	case bgfx.RendererTypeDirect3D9:
		texelHalf = 0.5
	case bgfx.RendererTypeOpenGL, bgfx.RendererTypeOpenGLES:
		originBottomLeft = true
	}

	var decl bgfx.VertexDecl
	decl.Begin()
	decl.Add(bgfx.AttribPosition, 3, bgfx.AttribTypeFloat, false, false)
	decl.Add(bgfx.AttribColor0, 4, bgfx.AttribTypeUint8, true, false)
	decl.Add(bgfx.AttribTexcoord0, 2, bgfx.AttribTypeFloat, false, false)
	decl.End()

	var (
		skyProg     = assets.LoadProgram("vs_hdr_skybox", "fs_hdr_skybox")
		lumProg     = assets.LoadProgram("vs_hdr_lum", "fs_hdr_lum")
		lumAvgProg  = assets.LoadProgram("vs_hdr_lumavg", "fs_hdr_lumavg")
		blurProg    = assets.LoadProgram("vs_hdr_blur", "fs_hdr_blur")
		brightProg  = assets.LoadProgram("vs_hdr_bright", "fs_hdr_bright")
		meshProg    = assets.LoadProgram("vs_hdr_mesh", "fs_hdr_mesh")
		tonemapProg = assets.LoadProgram("vs_hdr_tonemap", "fs_hdr_tonemap")
	)
	defer bgfx.DestroyProgram(skyProg)
	defer bgfx.DestroyProgram(lumProg)
	defer bgfx.DestroyProgram(lumAvgProg)
	defer bgfx.DestroyProgram(blurProg)
	defer bgfx.DestroyProgram(brightProg)
	defer bgfx.DestroyProgram(meshProg)
	defer bgfx.DestroyProgram(tonemapProg)

	var (
		uTime     = bgfx.CreateUniform("u_time", bgfx.Uniform1f, 1)
		uTexCube  = bgfx.CreateUniform("u_texCube", bgfx.Uniform1i, 1)
		uTexColor = bgfx.CreateUniform("u_texColor", bgfx.Uniform1i, 1)
		uTexLum   = bgfx.CreateUniform("u_texLum", bgfx.Uniform1i, 1)
		uTexBlur  = bgfx.CreateUniform("u_texBlur", bgfx.Uniform1i, 1)
		uMtx      = bgfx.CreateUniform("u_mtx", bgfx.Uniform4x4fv, 1)
		uTonemap  = bgfx.CreateUniform("u_tonemap", bgfx.Uniform4fv, 1)
		uOffset   = bgfx.CreateUniform("u_offset", bgfx.Uniform4fv, 16)
	)
	defer bgfx.DestroyUniform(uTime)
	defer bgfx.DestroyUniform(uTexCube)
	defer bgfx.DestroyUniform(uTexColor)
	defer bgfx.DestroyUniform(uTexLum)
	defer bgfx.DestroyUniform(uTexBlur)
	defer bgfx.DestroyUniform(uMtx)
	defer bgfx.DestroyUniform(uTonemap)
	defer bgfx.DestroyUniform(uOffset)

	mesh := assets.LoadMesh("bunny")
	defer mesh.Unload()

	uffizi := assets.LoadTexture("uffizi.dds", bgfx.TextureUClamp|bgfx.TextureVClamp|bgfx.TextureWClamp)
	defer bgfx.DestroyTexture(uffizi)

	fbtextures := []bgfx.Texture{
		bgfx.CreateTexture2D(app.Width, app.Height, 1, bgfx.TextureFormatBGRA8, bgfx.TextureRT|bgfx.TextureUClamp|bgfx.TextureVClamp, nil),
		bgfx.CreateTexture2D(app.Width, app.Height, 1, bgfx.TextureFormatD16, bgfx.TextureRTBufferOnly, nil),
	}
	fb := bgfx.CreateFrameBufferFromTextures(fbtextures, true)
	lum := [5]bgfx.FrameBuffer{
		bgfx.CreateFrameBuffer(128, 128, bgfx.TextureFormatBGRA8, 0),
		bgfx.CreateFrameBuffer(64, 64, bgfx.TextureFormatBGRA8, 0),
		bgfx.CreateFrameBuffer(16, 16, bgfx.TextureFormatBGRA8, 0),
		bgfx.CreateFrameBuffer(4, 4, bgfx.TextureFormatBGRA8, 0),
		bgfx.CreateFrameBuffer(1, 1, bgfx.TextureFormatBGRA8, 0),
	}
	bright := bgfx.CreateFrameBuffer(app.Width/2, app.Height/2, bgfx.TextureFormatBGRA8, 0)
	blur := bgfx.CreateFrameBuffer(app.Width/8, app.Height/8, bgfx.TextureFormatBGRA8, 0)
	// defer in closure to capture these by reference since we destroy
	// and recreate these when the window resizes.
	defer func() {
		for _, l := range lum {
			bgfx.DestroyFrameBuffer(l)
		}
		bgfx.DestroyFrameBuffer(fb)
		bgfx.DestroyFrameBuffer(bright)
		bgfx.DestroyFrameBuffer(blur)
	}()

	const (
		speed      = 0.37
		middleGray = 0.18
		white      = 1.1
		threshold  = 1.5
	)
	var (
		prevWidth  = app.Width
		prevHeight = app.Height
	)
	for app.Continue() {
		if prevWidth != app.Width || prevHeight != app.Height {
			prevWidth = app.Width
			prevHeight = app.Height
			bgfx.DestroyFrameBuffer(fb)
			bgfx.DestroyFrameBuffer(blur)
			bgfx.DestroyFrameBuffer(bright)
			fbtextures[0] = bgfx.CreateTexture2D(app.Width, app.Height, 1, bgfx.TextureFormatBGRA8, bgfx.TextureRT|bgfx.TextureUClamp|bgfx.TextureVClamp, nil)
			fbtextures[1] = bgfx.CreateTexture2D(app.Width, app.Height, 1, bgfx.TextureFormatD16, bgfx.TextureRTBufferOnly, nil)
			fb = bgfx.CreateFrameBufferFromTextures(fbtextures, true)
			bright = bgfx.CreateFrameBuffer(app.Width/2, app.Height/2, bgfx.TextureFormatBGRA8, 0)
			blur = bgfx.CreateFrameBuffer(app.Width/8, app.Height/8, bgfx.TextureFormatBGRA8, 0)
		}

		bgfx.DebugTextClear()
		bgfx.DebugTextPrintf(0, 1, 0x4f, app.Title)
		bgfx.DebugTextPrintf(0, 2, 0x6f, "Description: Using multiple views and render targets.")
		bgfx.DebugTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", app.DeltaTime*1000.0)

		bgfx.SetUniform(uTime, &app.Time, 1)

		for i := 0; i < 6; i++ {
			bgfx.SetViewRect(bgfx.ViewID(i), 0, 0, app.Width, app.Height)
		}
		bgfx.SetViewFrameBuffer(0, fb)
		bgfx.SetViewFrameBuffer(1, fb)

		bgfx.SetViewRect(2, 0, 0, 128, 128)
		bgfx.SetViewFrameBuffer(2, lum[0])
		bgfx.SetViewRect(3, 0, 0, 64, 64)
		bgfx.SetViewFrameBuffer(3, lum[1])
		bgfx.SetViewRect(4, 0, 0, 16, 16)
		bgfx.SetViewFrameBuffer(4, lum[2])
		bgfx.SetViewRect(5, 0, 0, 4, 4)
		bgfx.SetViewFrameBuffer(5, lum[3])
		bgfx.SetViewRect(6, 0, 0, 1, 1)
		bgfx.SetViewFrameBuffer(6, lum[4])

		bgfx.SetViewRect(7, 0, 0, app.Width/2, app.Height/2)
		bgfx.SetViewFrameBuffer(7, bright)

		bgfx.SetViewRect(8, 0, 0, app.Width/8, app.Height/8)
		bgfx.SetViewFrameBuffer(8, blur)

		bgfx.SetViewRect(9, 0, 0, app.Width, app.Height)

		view := mat4.Identity()
		proj := mat4.OrthoLH(0, 1, 1, 0, 0, 100)
		for i := 0; i < 10; i++ {
			bgfx.SetViewTransform(bgfx.ViewID(i), view, proj)
		}

		var (
			eye = [3]float32{0, 1, -2.5}
			at  = [3]float32{0, 1, 0}
			up  = [3]float32{0, 1, 0}
			mtx = mat4.RotateXYZ(0, cgm.Radians(app.Time)*0.37, 0)
		)
		eye = mat4.Mul3(mtx, eye)
		view = mat4.LookAtLH(eye, at, up)
		proj = mat4.PerspectiveLH(
			cgm.ToRadians(60),
			float32(app.Width)/float32(app.Height),
			0.1, 100,
		)
		bgfx.SetViewTransform(1, view, proj)
		bgfx.SetUniform(uMtx, &mtx, 1)

		// Render skybox into view 0
		bgfx.SetTexture(0, uTexCube, uffizi)
		bgfx.SetProgram(skyProg)
		bgfx.SetState(bgfx.StateRGBWrite | bgfx.StateAlphaWrite)
		screenSpaceQuad(decl, float32(app.Width), float32(app.Height), true)
		bgfx.Submit(0)

		// Render mesh into view 1
		bgfx.SetTexture(0, uTexCube, uffizi)
		mesh.Submit(1, meshProg, mat4.Identity(), 0)

		// Calculate luminance.
		setOffsets2x2Lum(uOffset, 128, 128)
		bgfx.SetTexture(0, uTexColor, fbtextures[0])
		bgfx.SetProgram(lumProg)
		bgfx.SetState(bgfx.StateRGBWrite | bgfx.StateAlphaWrite)
		screenSpaceQuad(decl, 128, 128, originBottomLeft)
		bgfx.Submit(2)

		// Downscale luminance 0.
		setOffsets4x4Lum(uOffset, 128, 128)
		bgfx.SetTextureFromFrameBuffer(0, uTexColor, lum[0])
		bgfx.SetProgram(lumAvgProg)
		bgfx.SetState(bgfx.StateRGBWrite | bgfx.StateAlphaWrite)
		screenSpaceQuad(decl, 64, 64, originBottomLeft)
		bgfx.Submit(3)

		// Downscale luminance 1.
		setOffsets4x4Lum(uOffset, 64, 64)
		bgfx.SetTextureFromFrameBuffer(0, uTexColor, lum[1])
		bgfx.SetProgram(lumAvgProg)
		bgfx.SetState(bgfx.StateRGBWrite | bgfx.StateAlphaWrite)
		screenSpaceQuad(decl, 16, 16, originBottomLeft)
		bgfx.Submit(4)

		// Downscale luminance 2.
		setOffsets4x4Lum(uOffset, 16, 16)
		bgfx.SetTextureFromFrameBuffer(0, uTexColor, lum[2])
		bgfx.SetProgram(lumAvgProg)
		bgfx.SetState(bgfx.StateRGBWrite | bgfx.StateAlphaWrite)
		screenSpaceQuad(decl, 4, 4, originBottomLeft)
		bgfx.Submit(5)

		// Downscale luminance 3.
		setOffsets4x4Lum(uOffset, 4, 4)
		bgfx.SetTextureFromFrameBuffer(0, uTexColor, lum[3])
		bgfx.SetProgram(lumAvgProg)
		bgfx.SetState(bgfx.StateRGBWrite | bgfx.StateAlphaWrite)
		screenSpaceQuad(decl, 1, 1, originBottomLeft)
		bgfx.Submit(6)

		tonemap := [4]float32{middleGray, white * white, threshold, 0}
		bgfx.SetUniform(uTonemap, &tonemap, 1)

		// Bright pass threshold is tonemap[3]
		setOffsets4x4Lum(uOffset, app.Width/2, app.Height/2)
		bgfx.SetTexture(0, uTexColor, fbtextures[0])
		bgfx.SetTextureFromFrameBuffer(1, uTexLum, lum[4])
		bgfx.SetProgram(brightProg)
		bgfx.SetState(bgfx.StateRGBWrite | bgfx.StateAlphaWrite)
		screenSpaceQuad(decl, float32(app.Width/2), float32(app.Height/2), originBottomLeft)
		bgfx.Submit(7)

		// Blur pass vertically
		bgfx.SetTextureFromFrameBuffer(0, uTexColor, bright)
		bgfx.SetProgram(blurProg)
		bgfx.SetState(bgfx.StateRGBWrite | bgfx.StateAlphaWrite)
		screenSpaceQuad(decl, float32(app.Width/8), float32(app.Height/8), originBottomLeft)
		bgfx.Submit(8)

		// Blur pass horizontally, do tonemapping and combine.
		bgfx.SetTexture(0, uTexColor, fbtextures[0])
		bgfx.SetTextureFromFrameBuffer(1, uTexLum, lum[4])
		bgfx.SetTextureFromFrameBuffer(2, uTexBlur, blur)
		bgfx.SetProgram(tonemapProg)
		bgfx.SetState(bgfx.StateRGBWrite | bgfx.StateAlphaWrite)
		screenSpaceQuad(decl, float32(app.Width), float32(app.Height), originBottomLeft)
		bgfx.Submit(9)

		bgfx.Frame()
	}
}
Example #2
0
func main() {
	app := example.Open()
	defer app.Close()
	bgfx.Init()
	defer bgfx.Shutdown()

	bgfx.Reset(app.Width, app.Height, bgfx.ResetVSync)
	bgfx.SetDebug(bgfx.DebugText)
	bgfx.SetViewClear(
		0,
		bgfx.ClearColor|bgfx.ClearDepth,
		0x303030ff,
		1.0,
		0,
	)
	bgfx.SetViewRect(0, 0, 0, app.Width, app.Height)
	bgfx.Submit(0)

	var vd bgfx.VertexDecl
	vd.Begin()
	vd.Add(bgfx.AttribPosition, 3, bgfx.AttribTypeFloat, false, false)
	vd.Add(bgfx.AttribColor0, 4, bgfx.AttribTypeUint8, true, false)
	vd.Add(bgfx.AttribTexcoord0, 2, bgfx.AttribTypeFloat, true, false)
	vd.End()

	uTime := bgfx.CreateUniform("u_time", bgfx.Uniform1f, 1)
	uMtx := bgfx.CreateUniform("u_mtx", bgfx.Uniform4x4fv, 1)
	uLightDir := bgfx.CreateUniform("u_lightDir", bgfx.Uniform3fv, 1)
	defer bgfx.DestroyUniform(uTime)
	defer bgfx.DestroyUniform(uMtx)
	defer bgfx.DestroyUniform(uLightDir)

	prog := assets.LoadProgram("vs_raymarching", "fs_raymarching")
	defer bgfx.DestroyProgram(prog)

	for app.Continue() {
		bgfx.DebugTextClear()
		bgfx.DebugTextPrintf(0, 1, 0x4f, app.Title)
		bgfx.DebugTextPrintf(0, 2, 0x6f, "Description: Updating shader uniforms.")
		bgfx.DebugTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", app.DeltaTime*1000.0)

		var (
			eye = [3]float32{0, 0, -15.0}
			at  = [3]float32{0, 0, 0}
			up  = [3]float32{1, 0, 0}
		)
		view := mat4.LookAtLH(eye, at, up)
		proj := mat4.PerspectiveLH(
			cgm.ToRadians(60),
			float32(app.Width)/float32(app.Height),
			0.1, 100.0,
		)
		bgfx.SetViewRect(0, 0, 0, app.Width, app.Height)
		bgfx.SetViewTransform(0, [16]float32(view), [16]float32(proj))
		bgfx.Submit(0)

		ortho := mat4.OrthoLH(0, float32(app.Width), float32(app.Height), 0, 0, 100)
		bgfx.SetViewRect(1, 0, 0, app.Width, app.Height)
		bgfx.SetViewTransform(1, mat4.Identity(), ortho)

		viewProj := mat4.Mul(proj, view)
		mtx := mat4.RotateXYZ(
			cgm.Radians(app.Time),
			cgm.Radians(app.Time)*0.37,
			0,
		)
		invMtx := mat4.Inv(mtx)
		lightDirModel := [3]float32{-0.4, -0.5, -1.0}
		lightDirModelN := vec3.Normal(lightDirModel)
		lightDir := mat4.Mul4(invMtx,
			[4]float32{
				lightDirModelN[0],
				lightDirModelN[1],
				lightDirModelN[2],
				0,
			})
		invMvp := mat4.Inv(mat4.Mul(viewProj, mtx))

		bgfx.SetUniform(uTime, &app.Time, 1)
		bgfx.SetUniform(uLightDir, &lightDir, 1)
		bgfx.SetUniform(uMtx, &invMvp, 1)

		renderScreenSpaceQuad(1, prog, vd, 0, 0, float32(app.Width), float32(app.Height))

		bgfx.Frame()
	}
}