mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-26 02:42:02 +01:00
shareable: Add Fill
Before introducing Fill, filling an image with a solid color was implemented by ReplacePixels. When an offscreen image is used, the offscreen image is not fully cleared or filled with a color and out of (0,0)-(width,height) region. This causes a glitch thin line on mobile platforms. This change adds (*shareable.Image).Fill to fill the whole framebuffer region of the image.
This commit is contained in:
parent
d5e6e6893e
commit
1e1f309a1c
@ -112,16 +112,9 @@ func (c *graphicsContext) Update(afterFrameUpdate func()) error {
|
|||||||
afterFrameUpdate()
|
afterFrameUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the screen framebuffer by DrawImage instad of Fill
|
|
||||||
// to clear the whole region including fullscreen's padding.
|
|
||||||
// TODO: This clear is needed only when the screen size is changed.
|
// TODO: This clear is needed only when the screen size is changed.
|
||||||
if c.offsetX > 0 || c.offsetY > 0 {
|
if c.offsetX > 0 || c.offsetY > 0 {
|
||||||
op := &DrawImageOptions{}
|
c.screen.Clear()
|
||||||
w, h := emptyImage.Size()
|
|
||||||
sw, sh := c.screen.Size()
|
|
||||||
op.GeoM.Scale(float64(sw)/float64(w), float64(sh)/float64(h))
|
|
||||||
op.CompositeMode = CompositeModeCopy
|
|
||||||
c.screen.DrawImage(emptyImage, op)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op := &DrawImageOptions{}
|
op := &DrawImageOptions{}
|
||||||
|
41
image.go
41
image.go
@ -25,15 +25,6 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/internal/shareable"
|
"github.com/hajimehoshi/ebiten/internal/shareable"
|
||||||
)
|
)
|
||||||
|
|
||||||
// emptyImage is an empty image used for filling other images with a uniform color.
|
|
||||||
//
|
|
||||||
// Do not call Fill or Clear on emptyImage or the program causes infinite recursion.
|
|
||||||
var emptyImage *Image
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
emptyImage, _ = NewImage(16, 16, FilterDefault)
|
|
||||||
}
|
|
||||||
|
|
||||||
type mipmap struct {
|
type mipmap struct {
|
||||||
orig *shareable.Image
|
orig *shareable.Image
|
||||||
imgs map[image.Rectangle][]*shareable.Image
|
imgs map[image.Rectangle][]*shareable.Image
|
||||||
@ -191,36 +182,8 @@ func (i *Image) Fill(clr color.Color) error {
|
|||||||
|
|
||||||
r16, g16, b16, a16 := clr.RGBA()
|
r16, g16, b16, a16 := clr.RGBA()
|
||||||
r, g, b, a := uint8(r16>>8), uint8(g16>>8), uint8(b16>>8), uint8(a16>>8)
|
r, g, b, a := uint8(r16>>8), uint8(g16>>8), uint8(b16>>8), uint8(a16>>8)
|
||||||
|
i.mipmap.original().Fill(r, g, b, a)
|
||||||
wd, hd := i.Size()
|
i.disposeMipmaps()
|
||||||
if wd*hd <= 256 {
|
|
||||||
// Prefer ReplacePixels since ReplacePixels can keep the images shared.
|
|
||||||
pix := make([]uint8, 4*wd*hd)
|
|
||||||
for i := 0; i < wd*hd; i++ {
|
|
||||||
pix[4*i] = r
|
|
||||||
pix[4*i+1] = g
|
|
||||||
pix[4*i+2] = b
|
|
||||||
pix[4*i+3] = a
|
|
||||||
}
|
|
||||||
i.ReplacePixels(pix)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
ws, hs := emptyImage.Size()
|
|
||||||
sw := float64(wd) / float64(ws)
|
|
||||||
sh := float64(hd) / float64(hs)
|
|
||||||
op := &DrawImageOptions{}
|
|
||||||
op.GeoM.Scale(sw, sh)
|
|
||||||
if a > 0 {
|
|
||||||
rf := float64(r) / float64(a)
|
|
||||||
gf := float64(g) / float64(a)
|
|
||||||
bf := float64(b) / float64(a)
|
|
||||||
af := float64(a) / 0xff
|
|
||||||
op.ColorM.Translate(rf, gf, bf, af)
|
|
||||||
}
|
|
||||||
op.CompositeMode = CompositeModeCopy
|
|
||||||
op.Filter = FilterNearest
|
|
||||||
i.drawImage(emptyImage, op)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,6 +256,39 @@ func (i *Image) DrawImage(img *Image, vertices []float32, indices []uint16, colo
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// emptyImage is an empty image used for filling other images with a uniform color.
|
||||||
|
//
|
||||||
|
// Do not call Fill on emptyImage or the program causes infinite recursion.
|
||||||
|
var emptyImage = NewImage(16, 16)
|
||||||
|
|
||||||
|
// Fill fills the image with a color. This affects not only the (0, 0)-(width, height) region but also the whole
|
||||||
|
// framebuffer region.
|
||||||
|
func (i *Image) Fill(r, g, b, a uint8) {
|
||||||
|
backendsM.Lock()
|
||||||
|
if i.disposed {
|
||||||
|
panic("shareable: the drawing target image must not be disposed")
|
||||||
|
}
|
||||||
|
i.ensureNotShared()
|
||||||
|
backendsM.Unlock()
|
||||||
|
|
||||||
|
dw, dh := i.backend.restorable.SizePowerOf2()
|
||||||
|
sw, sh := emptyImage.Size()
|
||||||
|
vs := emptyImage.QuadVertices(0, 0, sw, sh,
|
||||||
|
float32(dw)/float32(sw), 0, 0, float32(dh)/float32(sh), 0, 0,
|
||||||
|
1, 1, 1, 1)
|
||||||
|
is := graphics.QuadIndices()
|
||||||
|
|
||||||
|
var colorm *affine.ColorM
|
||||||
|
if a > 0 {
|
||||||
|
rf := float32(r) / float32(a)
|
||||||
|
gf := float32(g) / float32(a)
|
||||||
|
bf := float32(b) / float32(a)
|
||||||
|
af := float32(a) / 0xff
|
||||||
|
colorm = colorm.Translate(rf, gf, bf, af)
|
||||||
|
}
|
||||||
|
i.DrawImage(emptyImage, vs, is, colorm, graphics.CompositeModeCopy, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||||
|
}
|
||||||
|
|
||||||
func (i *Image) ReplacePixels(p []byte) {
|
func (i *Image) ReplacePixels(p []byte) {
|
||||||
backendsM.Lock()
|
backendsM.Lock()
|
||||||
defer backendsM.Unlock()
|
defer backendsM.Unlock()
|
||||||
|
Loading…
Reference in New Issue
Block a user