From 5d9acfe7ecbd3eee9b779b1f7cd7d050683c9b87 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 9 Oct 2022 21:26:13 +0900 Subject: [PATCH] examples/vector: add switching anti-alias This change is a proof-of-concept of anti-alias with a pseudo MSAA effect. Updates #663 --- examples/vector/main.go | 65 ++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/examples/vector/main.go b/examples/vector/main.go index 622dc7cb7..944f70e6a 100644 --- a/examples/vector/main.go +++ b/examples/vector/main.go @@ -26,6 +26,7 @@ import ( "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/ebitenutil" + "github.com/hajimehoshi/ebiten/v2/inpututil" "github.com/hajimehoshi/ebiten/v2/vector" ) @@ -46,7 +47,7 @@ const ( screenHeight = 480 ) -func drawEbitenText(screen *ebiten.Image) { +func drawEbitenText(screen *ebiten.Image, scale float32) { var path vector.Path // E @@ -117,6 +118,8 @@ func drawEbitenText(screen *ebiten.Image) { } vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) for i := range vs { + vs[i].DstX *= scale + vs[i].DstY *= scale vs[i].SrcX = 1 vs[i].SrcY = 1 vs[i].ColorR = 0xdb / float32(0xff) @@ -126,7 +129,7 @@ func drawEbitenText(screen *ebiten.Image) { screen.DrawTriangles(vs, is, emptySubImage, op) } -func drawEbitenLogo(screen *ebiten.Image, x, y int) { +func drawEbitenLogo(screen *ebiten.Image, x, y int, scale float32) { const unit = 16 var path vector.Path @@ -157,6 +160,8 @@ func drawEbitenLogo(screen *ebiten.Image, x, y int) { } vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) for i := range vs { + vs[i].DstX *= scale + vs[i].DstY *= scale vs[i].SrcX = 1 vs[i].SrcY = 1 vs[i].ColorR = 0xdb / float32(0xff) @@ -166,7 +171,7 @@ func drawEbitenLogo(screen *ebiten.Image, x, y int) { screen.DrawTriangles(vs, is, emptySubImage, op) } -func drawArc(screen *ebiten.Image, count int) { +func drawArc(screen *ebiten.Image, count int, scale float32) { var path vector.Path path.MoveTo(350, 100) @@ -185,6 +190,8 @@ func drawArc(screen *ebiten.Image, count int) { } vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) for i := range vs { + vs[i].DstX *= scale + vs[i].DstY *= scale vs[i].SrcX = 1 vs[i].SrcY = 1 vs[i].ColorR = 0x33 / float32(0xff) @@ -198,7 +205,7 @@ func maxCounter(index int) int { return 128 + (17*index+32)%64 } -func drawWave(screen *ebiten.Image, counter int) { +func drawWave(screen *ebiten.Image, counter int, scale float32) { var path vector.Path const npoints = 8 @@ -228,6 +235,8 @@ func drawWave(screen *ebiten.Image, counter int) { } vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) for i := range vs { + vs[i].DstX *= scale + vs[i].DstY *= scale vs[i].SrcX = 1 vs[i].SrcY = 1 vs[i].ColorR = 0x33 / float32(0xff) @@ -239,21 +248,57 @@ func drawWave(screen *ebiten.Image, counter int) { type Game struct { counter int + + aa bool + offscreen *ebiten.Image } func (g *Game) Update() error { g.counter++ + + // Switch anti-alias. + if inpututil.IsKeyJustPressed(ebiten.KeyA) { + g.aa = !g.aa + } + return nil } func (g *Game) Draw(screen *ebiten.Image) { - screen.Fill(color.White) - drawEbitenText(screen) - drawEbitenLogo(screen, 20, 90) - drawArc(screen, g.counter) - drawWave(screen, g.counter) + if g.offscreen != nil { + w, h := screen.Size() + if ow, oh := g.offscreen.Size(); ow != w || oh != h { + g.offscreen.Dispose() + g.offscreen = nil + } + } + if g.aa && g.offscreen == nil { + w, h := screen.Size() + g.offscreen = ebiten.NewImage(w*2, h*2) + } - ebitenutil.DebugPrint(screen, fmt.Sprintf("TPS: %0.2f\nFPS: %0.2f", ebiten.ActualTPS(), ebiten.ActualFPS())) + scale := float32(1) + dst := screen + if g.aa { + scale = 2 + dst = g.offscreen + } + + dst.Fill(color.White) + drawEbitenText(dst, scale) + drawEbitenLogo(dst, 20, 90, scale) + drawArc(dst, g.counter, scale) + drawWave(dst, g.counter, scale) + + if g.aa { + op := &ebiten.DrawImageOptions{} + op.GeoM.Scale(0.5, 0.5) + op.Filter = ebiten.FilterLinear + screen.DrawImage(g.offscreen, op) + } + + msg := fmt.Sprintf("TPS: %0.2f\nFPS: %0.2f\nPress A to switch anti-alias", ebiten.ActualTPS(), ebiten.ActualFPS()) + ebitenutil.DebugPrint(screen, msg) } func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {