ebiten: add DefaultDrawFinalScreen

Closes #3139
This commit is contained in:
Hajime Hoshi 2024-10-21 11:17:00 +09:00
parent 6452cbc895
commit 94fee8be55

View File

@ -18,6 +18,7 @@ import (
"fmt" "fmt"
"image" "image"
"math" "math"
"sync"
"sync/atomic" "sync/atomic"
"github.com/hajimehoshi/ebiten/v2/internal/atlas" "github.com/hajimehoshi/ebiten/v2/internal/atlas"
@ -32,12 +33,11 @@ func init() {
} }
type gameForUI struct { type gameForUI struct {
game Game game Game
offscreen *Image offscreen *Image
screen *Image screen *Image
screenShader *Shader imageDumper imageDumper
imageDumper imageDumper transparent bool
transparent bool
} }
func newGameForUI(game Game, transparent bool) *gameForUI { func newGameForUI(game Game, transparent bool) *gameForUI {
@ -45,13 +45,6 @@ func newGameForUI(game Game, transparent bool) *gameForUI {
game: game, game: game,
transparent: transparent, transparent: transparent,
} }
s, err := newShader(builtinshader.ScreenShaderSource, "screen")
if err != nil {
panic(fmt.Sprintf("ebiten: compiling the screen shader failed: %v", err))
}
g.screenShader = s
return g return g
} }
@ -136,21 +129,44 @@ func (g *gameForUI) DrawFinalScreen(scale, offsetX, offsetY float64) {
return return
} }
DefaultDrawFinalsScreen(g.screen, g.offscreen, geoM)
}
var (
theScreenShader *Shader
theScreenShaderOnce sync.Once
)
// DefaultDrawFinalsScreen is the default implementation of [FinalScreenDrawer.DrawFinalScreen],
// used when a [Game] doesn't implement [FinalScreenDrawer].
//
// DefaultDrawFinalsScreen is used when you need the default implementation of [FinalScreenDrawer.DrawFinalScreen]
// in your implementation of [FinalScreenDrawer], for example.
func DefaultDrawFinalsScreen(screen *Image, offscreen *Image, geoM GeoM) {
theScreenShaderOnce.Do(func() {
s, err := newShader(builtinshader.ScreenShaderSource, "screen")
if err != nil {
panic(fmt.Sprintf("ebiten: compiling the screen shader failed: %v", err))
}
theScreenShader = s
})
scale := geoM.Element(0, 0)
switch { switch {
case !screenFilterEnabled.Load(), math.Floor(scale) == scale: case !screenFilterEnabled.Load(), math.Floor(scale) == scale:
op := &DrawImageOptions{} op := &DrawImageOptions{}
op.GeoM = geoM op.GeoM = geoM
g.screen.DrawImage(g.offscreen, op) screen.DrawImage(offscreen, op)
case scale < 1: case scale < 1:
op := &DrawImageOptions{} op := &DrawImageOptions{}
op.GeoM = geoM op.GeoM = geoM
op.Filter = FilterLinear op.Filter = FilterLinear
g.screen.DrawImage(g.offscreen, op) screen.DrawImage(offscreen, op)
default: default:
op := &DrawRectShaderOptions{} op := &DrawRectShaderOptions{}
op.Images[0] = g.offscreen op.Images[0] = offscreen
op.GeoM = geoM op.GeoM = geoM
w, h := g.offscreen.Bounds().Dx(), g.offscreen.Bounds().Dy() w, h := offscreen.Bounds().Dx(), offscreen.Bounds().Dy()
g.screen.DrawRectShader(w, h, g.screenShader, op) screen.DrawRectShader(w, h, theScreenShader, op)
} }
} }