Skip to content

Commit

Permalink
Add sprite benchmarks
Browse files Browse the repository at this point in the history
  • Loading branch information
bhperry committed Aug 18, 2024
1 parent 6343834 commit 46e463d
Showing 1 changed file with 135 additions and 0 deletions.
135 changes: 135 additions & 0 deletions tools/benchmark/sprite_bench.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package benchmark

import (
"image"
"image/png"
"math"
"os"
"path"
"path/filepath"
"runtime"
"time"

"github.com/gopxl/pixel/v2"
"github.com/gopxl/pixel/v2/backends/opengl"
)

var (
basepath string
logoPath = "logo/LOGOTYPE-HORIZONTAL-BLUE2.png"
logoFrame = pixel.R(100, 44, 232, 180)
)

func init() {
_, b, _, _ := runtime.Caller(0)
basepath = filepath.ToSlash(filepath.Dir(filepath.Dir(filepath.Dir(b))))
logoPath = path.Join(basepath, logoPath)

Benchmarks.Add(
Config{
Name: "sprite",
Description: "Draw a sprite to the window in a grid",
New: newSingleSprite,
Duration: 30 * time.Second,
},
Config{
Name: "sprite-batched",
Description: "Draw a sprite to the window in a grid with batched draw",
New: newBatchedSprite,
Duration: 30 * time.Second,
},
)
}

func newSingleSprite() Benchmark {
return &singleSprite{}
}

type singleSprite struct {
sprite *pixel.Sprite
}

func (ss *singleSprite) Init(win *opengl.Window) error {
sprite, err := loadSprite(logoPath, logoFrame)
if err != nil {
return err
}
ss.sprite = sprite
return nil
}

func (ss *singleSprite) Step(win *opengl.Window) {
win.Clear(backgroundColor)
spriteGrid(ss.sprite, win, win.Bounds())
}

func newBatchedSprite() Benchmark {
return &batchedSprite{}
}

type batchedSprite struct {
sprite *pixel.Sprite
batch *pixel.Batch
}

func (bs *batchedSprite) Init(win *opengl.Window) error {
sprite, err := loadSprite(logoPath, logoFrame)
if err != nil {
return err
}
bs.sprite = sprite
bs.batch = pixel.NewBatch(&pixel.TrianglesData{}, sprite.Picture())
return nil
}

func (bs *batchedSprite) Step(win *opengl.Window) {
win.Clear(backgroundColor)
bs.batch.Clear()
spriteGrid(bs.sprite, bs.batch, win.Bounds())
bs.batch.Draw(win)
}

func spriteGrid(sprite *pixel.Sprite, target pixel.Target, bounds pixel.Rect) {
spriteBounds := sprite.Frame().Bounds()
spriteWidth := spriteBounds.W()
spriteHeight := spriteBounds.H()

heightRatio := bounds.H() / spriteHeight
cols := int(math.Ceil(bounds.W() / spriteWidth))
rows := int(math.Ceil(heightRatio))

alignTop := (heightRatio - float64(rows)) * spriteHeight
offset := pixel.V(spriteWidth/2, spriteHeight/2+alignTop)

for i := 0; i < cols; i++ {
for j := 0; j < rows; j++ {
pos := pixel.V(float64(i)*spriteWidth, float64(j)*spriteHeight).Add(offset)
sprite.Draw(target, pixel.IM.Moved(pos))
}
}
}

func loadSprite(file string, frame pixel.Rect) (sprite *pixel.Sprite, err error) {
image, err := loadPng(file)
if err != nil {
return nil, err
}

pic := pixel.PictureDataFromImage(image)
if frame.Empty() {
frame = pic.Bounds()
}
sprite = pixel.NewSprite(pic, frame)
return sprite, nil
}

func loadPng(file string) (i image.Image, err error) {
f, err := os.Open(file)
if err != nil {
return
}
defer f.Close()

i, err = png.Decode(f)
return
}

0 comments on commit 46e463d

Please sign in to comment.