examples/vector: add switching anti-alias

This change is a proof-of-concept of anti-alias with a pseudo MSAA
effect.

Updates #663
This commit is contained in:
Hajime Hoshi 2022-10-09 21:26:13 +09:00
parent f57fb4763c
commit 5d9acfe7ec

View File

@ -26,6 +26,7 @@ import (
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil" "github.com/hajimehoshi/ebiten/v2/ebitenutil"
"github.com/hajimehoshi/ebiten/v2/inpututil"
"github.com/hajimehoshi/ebiten/v2/vector" "github.com/hajimehoshi/ebiten/v2/vector"
) )
@ -46,7 +47,7 @@ const (
screenHeight = 480 screenHeight = 480
) )
func drawEbitenText(screen *ebiten.Image) { func drawEbitenText(screen *ebiten.Image, scale float32) {
var path vector.Path var path vector.Path
// E // E
@ -117,6 +118,8 @@ func drawEbitenText(screen *ebiten.Image) {
} }
vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil)
for i := range vs { for i := range vs {
vs[i].DstX *= scale
vs[i].DstY *= scale
vs[i].SrcX = 1 vs[i].SrcX = 1
vs[i].SrcY = 1 vs[i].SrcY = 1
vs[i].ColorR = 0xdb / float32(0xff) vs[i].ColorR = 0xdb / float32(0xff)
@ -126,7 +129,7 @@ func drawEbitenText(screen *ebiten.Image) {
screen.DrawTriangles(vs, is, emptySubImage, op) 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 const unit = 16
var path vector.Path var path vector.Path
@ -157,6 +160,8 @@ func drawEbitenLogo(screen *ebiten.Image, x, y int) {
} }
vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil)
for i := range vs { for i := range vs {
vs[i].DstX *= scale
vs[i].DstY *= scale
vs[i].SrcX = 1 vs[i].SrcX = 1
vs[i].SrcY = 1 vs[i].SrcY = 1
vs[i].ColorR = 0xdb / float32(0xff) vs[i].ColorR = 0xdb / float32(0xff)
@ -166,7 +171,7 @@ func drawEbitenLogo(screen *ebiten.Image, x, y int) {
screen.DrawTriangles(vs, is, emptySubImage, op) 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 var path vector.Path
path.MoveTo(350, 100) path.MoveTo(350, 100)
@ -185,6 +190,8 @@ func drawArc(screen *ebiten.Image, count int) {
} }
vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil)
for i := range vs { for i := range vs {
vs[i].DstX *= scale
vs[i].DstY *= scale
vs[i].SrcX = 1 vs[i].SrcX = 1
vs[i].SrcY = 1 vs[i].SrcY = 1
vs[i].ColorR = 0x33 / float32(0xff) vs[i].ColorR = 0x33 / float32(0xff)
@ -198,7 +205,7 @@ func maxCounter(index int) int {
return 128 + (17*index+32)%64 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 var path vector.Path
const npoints = 8 const npoints = 8
@ -228,6 +235,8 @@ func drawWave(screen *ebiten.Image, counter int) {
} }
vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil) vs, is := path.AppendVerticesAndIndicesForFilling(nil, nil)
for i := range vs { for i := range vs {
vs[i].DstX *= scale
vs[i].DstY *= scale
vs[i].SrcX = 1 vs[i].SrcX = 1
vs[i].SrcY = 1 vs[i].SrcY = 1
vs[i].ColorR = 0x33 / float32(0xff) vs[i].ColorR = 0x33 / float32(0xff)
@ -239,21 +248,57 @@ func drawWave(screen *ebiten.Image, counter int) {
type Game struct { type Game struct {
counter int counter int
aa bool
offscreen *ebiten.Image
} }
func (g *Game) Update() error { func (g *Game) Update() error {
g.counter++ g.counter++
// Switch anti-alias.
if inpututil.IsKeyJustPressed(ebiten.KeyA) {
g.aa = !g.aa
}
return nil return nil
} }
func (g *Game) Draw(screen *ebiten.Image) { func (g *Game) Draw(screen *ebiten.Image) {
screen.Fill(color.White) if g.offscreen != nil {
drawEbitenText(screen) w, h := screen.Size()
drawEbitenLogo(screen, 20, 90) if ow, oh := g.offscreen.Size(); ow != w || oh != h {
drawArc(screen, g.counter) g.offscreen.Dispose()
drawWave(screen, g.counter) 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) { func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {