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, ) var ( uTexColor = bgfx.CreateUniform("u_texColor", bgfx.Uniform1iv, 1) uStipple = bgfx.CreateUniform("u_stipple", bgfx.Uniform3fv, 1) uTexStipple = bgfx.CreateUniform("u_texStipple", bgfx.Uniform1iv, 1) ) defer bgfx.DestroyUniform(uTexColor) defer bgfx.DestroyUniform(uStipple) defer bgfx.DestroyUniform(uTexStipple) prog := assets.LoadProgram("vs_tree", "fs_tree") defer bgfx.DestroyProgram(prog) textureLeafs := assets.LoadTexture("leafs1.dds", 0) textureBark := assets.LoadTexture("bark1.dds", 0) defer bgfx.DestroyTexture(textureLeafs) defer bgfx.DestroyTexture(textureBark) stippleData := make([]byte, 8*4) for i, v := range knightTour { stippleData[(v.Y*8 + v.X)] = byte(i * 4) } textureStipple := bgfx.CreateTexture2D(8, 4, 1, bgfx.TextureFormatR8, bgfx.TextureMinPoint|bgfx.TextureMagPoint, stippleData) defer bgfx.DestroyTexture(textureStipple) meshTop := [3]assets.Mesh{ assets.LoadMesh("tree1b_lod0_1"), assets.LoadMesh("tree1b_lod1_1"), assets.LoadMesh("tree1b_lod2_1"), } meshTrunk := [3]assets.Mesh{ assets.LoadMesh("tree1b_lod0_2"), assets.LoadMesh("tree1b_lod1_2"), assets.LoadMesh("tree1b_lod2_2"), } for _, m := range meshTop { defer m.Unload() } for _, m := range meshTrunk { defer m.Unload() } var ( stateCommon = bgfx.StateRGBWrite | bgfx.StateAlphaWrite | bgfx.StateDepthTestLess | bgfx.StateCullCCW | bgfx.StateMSAA stateTransparent = stateCommon | bgfx.StateBlendAlpha() stateOpaque = stateCommon | bgfx.StateDepthWrite transitions = true transitionFrame = 0 currLOD = 0 targetLOD = 0 ) for app.Continue() { bgfx.SetViewRect(0, 0, 0, app.Width, app.Height) bgfx.Submit(0) bgfx.DebugTextClear() bgfx.DebugTextPrintf(0, 1, 0x4f, app.Title) bgfx.DebugTextPrintf(0, 2, 0x6f, "Description: Mesh LOD transitions.") bgfx.DebugTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", app.DeltaTime*1000.0) var ( currentLODframe = 32 mainLOD = targetLOD distance = float32(math.Cos(float64(app.Time))*2 + 4.0) ) if transitions { currentLODframe = 32 - transitionFrame mainLOD = currLOD } stipple := [3]float32{ 0, -1, (float32(currentLODframe) * 4 / 255) - (1.0 / 255), } stippleInv := [3]float32{ 31.0 * 4 / 255, 1, (float32(transitionFrame) * 4 / 255) - (1.0 / 255), } var ( eye = [3]float32{0, 1, -distance} at = [3]float32{0, 1, 0} up = [3]float32{0, 1, 0} ) view := mat4.LookAtLH(eye, at, up) proj := mat4.PerspectiveLH( cgm.ToRadians(60), float32(app.Width)/float32(app.Height), 0.1, 100, ) mtx := mat4.Scale(0.1, 0.1, 0.1) bgfx.SetViewTransform(0, view, proj) bgfx.SetTexture(0, uTexColor, textureBark) bgfx.SetTexture(1, uTexStipple, textureStipple) bgfx.SetUniform(uStipple, &stipple, 1) meshTrunk[mainLOD].Submit(0, prog, mtx, stateOpaque) bgfx.SetTexture(0, uTexColor, textureLeafs) bgfx.SetTexture(1, uTexStipple, textureStipple) bgfx.SetUniform(uStipple, &stipple, 1) meshTop[mainLOD].Submit(0, prog, mtx, stateTransparent) if transitions && transitionFrame != 0 { bgfx.SetTexture(0, uTexColor, textureBark) bgfx.SetTexture(1, uTexStipple, textureStipple) bgfx.SetUniform(uStipple, &stippleInv, 1) meshTrunk[targetLOD].Submit(0, prog, mtx, stateOpaque) bgfx.SetTexture(0, uTexColor, textureLeafs) bgfx.SetTexture(1, uTexStipple, textureStipple) bgfx.SetUniform(uStipple, &stippleInv, 1) meshTop[targetLOD].Submit(0, prog, mtx, stateTransparent) } lod := 0 if distance > 2.5 { lod = 1 } if distance > 5.0 { lod = 2 } if targetLOD != lod && targetLOD == currLOD { targetLOD = lod } if currLOD != targetLOD { transitionFrame++ } if transitionFrame > 32 { currLOD = targetLOD transitionFrame = 0 } bgfx.Frame() } }
func main() { app := example.Open() defer app.Close() bgfx.Init() defer bgfx.Shutdown() bgfx.Reset(app.Width, app.Height, 0) bgfx.SetDebug(bgfx.DebugText) bgfx.SetViewClear( 0, bgfx.ClearColor|bgfx.ClearDepth, 0x303030ff, 1.0, 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.End() vb := bgfx.CreateVertexBuffer(vertices, vd) defer bgfx.DestroyVertexBuffer(vb) ib := bgfx.CreateIndexBuffer(indices) defer bgfx.DestroyIndexBuffer(ib) prog := assets.LoadProgram("vs_cubes", "fs_cubes") defer bgfx.DestroyProgram(prog) var ( avgdt, totaldt float32 nframes int dim = 12 ) for app.Continue() { dt := app.DeltaTime if totaldt >= 1.0 { avgdt = totaldt / float32(nframes) if avgdt < 1.0/65 { dim += 2 } else if avgdt > 1.0/57 && dim > 2 { dim -= 1 } totaldt = 0 nframes = 0 } totaldt += dt nframes++ var ( eye = [3]float32{0, 0, -35.0} at = [3]float32{0, 0, 0} up = [3]float32{0, 1, 0} ) view := mat4.LookAtLH(eye, at, up) proj := mat4.PerspectiveLH( cgm.ToRadians(60), float32(app.Width)/float32(app.Height), 0.1, 100.0, ) bgfx.SetViewTransform(0, view, proj) bgfx.SetViewRect(0, 0, 0, app.Width, app.Height) bgfx.DebugTextClear() bgfx.DebugTextPrintf(0, 1, 0x4f, app.Title) bgfx.DebugTextPrintf(0, 2, 0x6f, "Description: Draw stress, maximizing number of draw calls.") bgfx.DebugTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", dt*1000.0) bgfx.DebugTextPrintf(0, 5, 0x0f, "Draw calls: %d", dim*dim*dim) bgfx.DebugTextPrintf(0, 6, 0x0f, "Dim: %d", dim) bgfx.DebugTextPrintf(0, 7, 0x0f, "AvgFrame: % 7.3f[ms]", avgdt*1000.0) bgfx.Submit(0) const step = 0.6 pos := [3]float32{ -step * float32(dim) / 2.0, -step * float32(dim) / 2.0, -15, } for z := 0; z < dim; z++ { for y := 0; y < dim; y++ { for x := 0; x < dim; x++ { mtx := mat4.RotateXYZ( cgm.Radians(app.Time)+cgm.Radians(x)*0.21, cgm.Radians(app.Time)+cgm.Radians(y)*0.37, cgm.Radians(app.Time)+cgm.Radians(z)*0.13, ) mtx = mat4.Mul(mtx, mat4.Scale(0.25, 0.25, 0.25)) mtx[12] = pos[0] + float32(x)*step mtx[13] = pos[1] + float32(y)*step mtx[14] = pos[2] + float32(z)*step bgfx.SetTransform(mtx) bgfx.SetProgram(prog) bgfx.SetVertexBuffer(vb) bgfx.SetIndexBuffer(ib) bgfx.SetState(bgfx.StateDefault) bgfx.Submit(0) } } } bgfx.Frame() } }