mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-12 12:08:58 +01:00
restorable: Add Fill
This is useful to reduce opportunity to make the image stale.
This commit is contained in:
parent
40f728a326
commit
93d0b0dd09
@ -60,14 +60,20 @@ type Image struct {
|
||||
priority bool
|
||||
}
|
||||
|
||||
var dummyImage *Image
|
||||
var emptyImage *Image
|
||||
|
||||
func init() {
|
||||
dummyImage = &Image{
|
||||
image: graphicscommand.NewImage(16, 16),
|
||||
const w, h = 16, 16
|
||||
emptyImage = &Image{
|
||||
image: graphicscommand.NewImage(w, h),
|
||||
priority: true,
|
||||
}
|
||||
theImages.add(dummyImage)
|
||||
pix := make([]byte, 4*w*h)
|
||||
for i := range pix {
|
||||
pix[i] = 0xff
|
||||
}
|
||||
emptyImage.ReplacePixels(pix, 0, 0, w, h)
|
||||
theImages.add(emptyImage)
|
||||
}
|
||||
|
||||
// NewImage creates an empty image with the given size.
|
||||
@ -103,30 +109,61 @@ func NewScreenFramebufferImage(width, height int) *Image {
|
||||
return i
|
||||
}
|
||||
|
||||
func (i *Image) Clear() {
|
||||
func (i *Image) Fill(r, g, b, a uint8) {
|
||||
theImages.makeStaleIfDependingOn(i)
|
||||
i.clear()
|
||||
i.fill(r, g, b, a)
|
||||
}
|
||||
|
||||
func (i *Image) clear() {
|
||||
i.fill(0, 0, 0, 0)
|
||||
}
|
||||
|
||||
func (i *Image) fill(r, g, b, a uint8) {
|
||||
if i.priority {
|
||||
panic("restorable: clear cannot be called on a priority image")
|
||||
}
|
||||
|
||||
// There are not 'drawImageHistoryItem's for this image and dummyImage.
|
||||
// As dummyImage is a priority image, this is restored before other regular images are restored.
|
||||
rf := float32(0)
|
||||
gf := float32(0)
|
||||
bf := float32(0)
|
||||
af := float32(0)
|
||||
if a > 0 {
|
||||
rf = float32(r) / float32(a)
|
||||
gf = float32(g) / float32(a)
|
||||
bf = float32(b) / float32(a)
|
||||
af = float32(a) / 0xff
|
||||
}
|
||||
|
||||
// There are not 'drawImageHistoryItem's for this image and emptyImage.
|
||||
// As emptyImage is a priority image, this is restored before other regular images are restored.
|
||||
w, h := i.Size()
|
||||
sw, sh := dummyImage.Size()
|
||||
sw, sh := emptyImage.Size()
|
||||
dw := graphics.NextPowerOf2Int(w)
|
||||
dh := graphics.NextPowerOf2Int(h)
|
||||
vs := graphics.QuadVertices(dw, dh, 0, 0, sw, sh,
|
||||
float32(dw)/float32(sw), 0, 0, float32(dh)/float32(sh),
|
||||
0, 0,
|
||||
1, 1, 1, 1)
|
||||
float32(dw)/float32(sw), 0, 0, float32(dh)/float32(sh), 0, 0,
|
||||
rf, gf, bf, af)
|
||||
is := graphics.QuadIndices()
|
||||
i.image.DrawImage(dummyImage.image, vs, is, nil, graphics.CompositeModeClear, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||
c := graphics.CompositeModeCopy
|
||||
if a == 0 {
|
||||
c = graphics.CompositeModeClear
|
||||
}
|
||||
i.image.DrawImage(emptyImage.image, vs, is, nil, c, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||
|
||||
i.basePixels = nil
|
||||
if a == 0 {
|
||||
i.basePixels = nil
|
||||
} else {
|
||||
// TODO: Add baseColor?
|
||||
if i.basePixels == nil {
|
||||
i.basePixels = make([]byte, 4*w*h)
|
||||
}
|
||||
for idx := 0; idx < w*h; idx++ {
|
||||
i.basePixels[4*idx] = r
|
||||
i.basePixels[4*idx+1] = g
|
||||
i.basePixels[4*idx+2] = b
|
||||
i.basePixels[4*idx+3] = a
|
||||
}
|
||||
}
|
||||
i.drawImageHistory = nil
|
||||
i.stale = false
|
||||
}
|
||||
@ -406,7 +443,6 @@ func (i *Image) restore() error {
|
||||
gimg.ReplacePixels(i.basePixels, 0, 0, w, h)
|
||||
} else {
|
||||
// Clear the image explicitly.
|
||||
// TODO: Is dummyImage available for clearing?
|
||||
pix := make([]uint8, w*h*4)
|
||||
gimg.ReplacePixels(pix, 0, 0, w, h)
|
||||
}
|
||||
|
@ -252,22 +252,6 @@ 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)
|
||||
|
||||
func init() {
|
||||
// Initialize emptyImage. As emptyImage is used for Fill, emptyImage itself cannot be initialized with Fill.
|
||||
// Call ReplacePixels instead.
|
||||
w, h := emptyImage.Size()
|
||||
pix := make([]byte, 4*w*h)
|
||||
for i := range pix {
|
||||
pix[i] = 0xff
|
||||
}
|
||||
emptyImage.ReplacePixels(pix)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
@ -278,35 +262,7 @@ func (i *Image) Fill(r, g, b, a uint8) {
|
||||
i.ensureNotShared()
|
||||
backendsM.Unlock()
|
||||
|
||||
if r == 0 && g == 0 && b == 0 && a == 0 {
|
||||
i.backend.restorable.Clear()
|
||||
return
|
||||
}
|
||||
|
||||
rf := float32(0)
|
||||
gf := float32(0)
|
||||
bf := float32(0)
|
||||
af := float32(0)
|
||||
if a > 0 {
|
||||
rf = float32(r) / float32(a)
|
||||
gf = float32(g) / float32(a)
|
||||
bf = float32(b) / float32(a)
|
||||
af = float32(a) / 0xff
|
||||
}
|
||||
|
||||
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,
|
||||
rf, gf, bf, af)
|
||||
is := graphics.QuadIndices()
|
||||
|
||||
c := graphics.CompositeModeCopy
|
||||
if a == 0xff {
|
||||
// If the color is opaque, SourceOver is available and this is preferable for optimization.
|
||||
c = graphics.CompositeModeSourceOver
|
||||
}
|
||||
i.DrawImage(emptyImage, vs, is, nil, c, graphics.FilterNearest, graphics.AddressClampToZero)
|
||||
i.backend.restorable.Fill(r, g, b, a)
|
||||
}
|
||||
|
||||
func (i *Image) ReplacePixels(p []byte) {
|
||||
|
Loading…
Reference in New Issue
Block a user