Closed sedyh closed 1 year ago
v2.5.0-alpha.12
go version
1.20
When rendering images via ebiten.Blend, DestinationOut behaves the same as SourceOut.
Source: Destination:
package main import ( "bytes" _ "embed" "fmt" "image" _ "image/png" "log" "math" "github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2/text" "github.com/hajimehoshi/ebiten/v2/vector" "golang.org/x/image/colornames" "golang.org/x/image/font/inconsolata" ) var ( //go:embed source.png Source []byte //go:embed dest.png Dest []byte ) func main() { ebiten.SetWindowSize(980, 600) ebiten.SetWindowResizingMode(ebiten.WindowResizingModeEnabled) if err := ebiten.RunGame(NewGame()); err != nil { log.Fatal(err) } } type Mode struct { Blend ebiten.Blend Name string } type Game struct { Source *ebiten.Image Dest *ebiten.Image Offscreen *ebiten.Image TileSize float64 GridW, GridH float64 Padding float64 TextSpacing float64 Modes []Mode } func NewGame() *Game { g := &Game{ Source: LoadImage(Source), Dest: LoadImage(Dest), Modes: []Mode{ {Blend: ebiten.BlendCopy, Name: "BlendCopy"}, {Blend: ebiten.BlendSourceAtop, Name: "BlendSourceAtop"}, {Blend: ebiten.BlendSourceOver, Name: "BlendSourceOver"}, {Blend: ebiten.BlendSourceIn, Name: "BlendSourceIn"}, {Blend: ebiten.BlendSourceOut, Name: "BlendSourceOut"}, {Blend: ebiten.BlendDestination, Name: "BlendDestination"}, {Blend: ebiten.BlendDestinationAtop, Name: "BlendDestinationAtop"}, {Blend: ebiten.BlendDestinationOver, Name: "BlendDestinationOver"}, {Blend: ebiten.BlendDestinationIn, Name: "BlendDestinationIn"}, {Blend: ebiten.BlendDestinationOut, Name: "BlendDestinationOut"}, {Blend: ebiten.BlendClear, Name: "BlendClear"}, {Blend: ebiten.BlendXor, Name: "BlendXor"}, {Blend: ebiten.BlendLighter, Name: "BlendLighter"}, }, GridW: 5, GridH: 3, Padding: 64, TextSpacing: 16, } g.TileSize = MaxSide(g.Source, g.Dest) g.Offscreen = ebiten.NewImage(int(g.TileSize), int(g.TileSize)) return g } func (g *Game) Update() error { return nil } func (g *Game) Draw(screen *ebiten.Image) { screen.Fill(colornames.White) sw, sh := float64(screen.Bounds().Dx()), float64(screen.Bounds().Dy()) ebiten.SetWindowTitle(fmt.Sprintf("%.0fx%.0f", sw, sh)) gw, gh := g.GridW*(g.TileSize+g.Padding)-g.Padding, g.GridH*(g.TileSize+g.Padding) cx, cy := (sw-gw)/2, (sh-gh)/2 for y := 0.; y < g.GridH; y++ { for x := 0.; x < g.GridW; x++ { px, py := x*(g.TileSize+g.Padding), y*(g.TileSize+g.Padding) if y > 0 { py += g.TextSpacing * y } mode := Get(g.Modes, int(x), int(y), int(g.GridW), int(g.GridH)) g.DrawBlendMode(screen, px+cx, py+cy, mode.Blend) DrawCenteredText(screen, px+cx+g.TileSize/2, py+cy+g.TileSize+g.TextSpacing, mode.Name) } } } func (g *Game) Layout(w, h int) (int, int) { return w, h } func (g *Game) DrawBlendMode(screen *ebiten.Image, x, y float64, mode ebiten.Blend) { g.Offscreen.Clear() g.Offscreen.DrawImage(g.Dest, nil) op := &ebiten.DrawImageOptions{} op.Blend = mode g.Offscreen.DrawImage(g.Source, op) op = &ebiten.DrawImageOptions{} op.GeoM.Translate(x, y) screen.DrawImage(g.Offscreen, op) vector.StrokeRect( screen, float32(x), float32(y), float32(g.TileSize), float32(g.TileSize), 2, colornames.Blue, ) } func LoadImage(data []byte) *ebiten.Image { m, _, err := image.Decode(bytes.NewReader(data)) if err != nil { log.Fatal(err) } return ebiten.NewImageFromImage(m) } func MaxSide(a, b *ebiten.Image) float64 { xMax := math.Max(float64(a.Bounds().Dx()), float64(a.Bounds().Dx())) yMax := math.Max(float64(b.Bounds().Dx()), float64(b.Bounds().Dx())) return math.Max(xMax, yMax) } func Index(x, y, w int) int { return y*w + x } func InRange(x, y, w, h int) bool { xOut := x < 0 || x >= w yOut := y < 0 || y >= h if xOut || yOut { return false } return true } func Get(modes []Mode, x, y, w, h int) Mode { index := Index(x, y, w) if !InRange(x, y, w, h) || index > len(modes)-1 { return Mode{Blend: ebiten.BlendClear, Name: "Empty"} } return modes[index] } func DrawCenteredText(screen *ebiten.Image, cx, cy float64, s string, args ...any) { interpolated := fmt.Sprintf(s, args...) bounds := text.BoundString(inconsolata.Bold8x16, interpolated) x, y := int(cx)-bounds.Min.X-bounds.Dx()/2, int(cy)-bounds.Min.Y-bounds.Dy()/2 text.Draw(screen, interpolated, inconsolata.Bold8x16, x, y, colornames.Black) }
I've not tested it with ebitengine 2.4 but add the result for it later.
Thanks! I'll take a look later.
Fixed it, adding PR...
Oh I could fixed this now, but you can send a PR
Ebitengine Version
v2.5.0-alpha.12
Operating System
Go Version (
go version
)1.20
What steps will reproduce the problem?
When rendering images via ebiten.Blend, DestinationOut behaves the same as SourceOut.
Images for test
Source: Destination:
Code example
What is the expected result?
What happens instead?
Anything else you feel useful to add?
I've not tested it with ebitengine 2.4 but add the result for it later.