mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
restorable: Add (*Image).Fill
This resets the infomation for restoring if possible. This makes it more efficient to use offscreens.
This commit is contained in:
parent
856e2df1ec
commit
3960a4bbdf
31
image.go
31
image.go
@ -78,14 +78,6 @@ func (i *Image) Clear() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var emptyImage *Image
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
emptyImage, _ = NewImage(1, 1, FilterDefault)
|
|
||||||
// (*Image).Fill uses emptyImage, then Fill cannot be called here.
|
|
||||||
emptyImage.ReplacePixels([]byte{0xff, 0xff, 0xff, 0xff})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fill fills the image with a solid color.
|
// Fill fills the image with a solid color.
|
||||||
//
|
//
|
||||||
// When the image is disposed, Fill does nothing.
|
// When the image is disposed, Fill does nothing.
|
||||||
@ -104,27 +96,8 @@ func (i *Image) Fill(clr color.Color) error {
|
|||||||
|
|
||||||
i.resolvePendingPixels(false)
|
i.resolvePendingPixels(false)
|
||||||
|
|
||||||
r, g, b, a := clr.RGBA()
|
i.mipmap.original().Fill(clr)
|
||||||
rf, gf, bf, af := 0.0, 0.0, 0.0, 0.0
|
i.disposeMipmaps()
|
||||||
if a > 0 {
|
|
||||||
rf = float64(r) / float64(a)
|
|
||||||
gf = float64(g) / float64(a)
|
|
||||||
bf = float64(b) / float64(a)
|
|
||||||
af = float64(a) / 0xffff
|
|
||||||
}
|
|
||||||
|
|
||||||
sw, sh := emptyImage.Size()
|
|
||||||
dw, dh := i.Size()
|
|
||||||
|
|
||||||
op := &DrawImageOptions{}
|
|
||||||
op.GeoM.Scale(float64(dw)/float64(sw), float64(dh)/float64(sh))
|
|
||||||
op.ColorM.Scale(rf, gf, bf, af)
|
|
||||||
// TODO: Use the previous composite mode if possible.
|
|
||||||
if af < 1.0 {
|
|
||||||
op.CompositeMode = CompositeModeCopy
|
|
||||||
}
|
|
||||||
// TODO: As all the pixels will be changed, this image can reset the information for restoring.
|
|
||||||
i.DrawImage(emptyImage, op)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ package restorable
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"image/color"
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/affine"
|
"github.com/hajimehoshi/ebiten/internal/affine"
|
||||||
"github.com/hajimehoshi/ebiten/internal/driver"
|
"github.com/hajimehoshi/ebiten/internal/driver"
|
||||||
@ -100,7 +101,9 @@ type Image struct {
|
|||||||
var emptyImage *Image
|
var emptyImage *Image
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
const w, h = 16, 16
|
// Use a big-enough image as an rendering source. By enlarging with x128, this can reach to 16384.
|
||||||
|
// See #907 for details.
|
||||||
|
const w, h = 128, 128
|
||||||
emptyImage = &Image{
|
emptyImage = &Image{
|
||||||
image: graphicscommand.NewImage(w, h),
|
image: graphicscommand.NewImage(w, h),
|
||||||
width: w,
|
width: w,
|
||||||
@ -229,6 +232,40 @@ func (i *Image) clear() {
|
|||||||
i.stale = false
|
i.stale = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fill fills the specified part of the image with a solid color.
|
||||||
|
func (i *Image) Fill(clr color.Color, x, y, width, height int) {
|
||||||
|
// If all the pixels will be changed, reset the information for restoring.
|
||||||
|
if w, h := i.Size(); x == 0 && y == 0 && width == w && height == h {
|
||||||
|
i.basePixels = Pixels{}
|
||||||
|
i.drawTrianglesHistory = nil
|
||||||
|
i.stale = false
|
||||||
|
}
|
||||||
|
|
||||||
|
var rf, gf, bf, af float32
|
||||||
|
if r, g, b, a := clr.RGBA(); a > 0 {
|
||||||
|
rf = float32(r) / float32(a)
|
||||||
|
gf = float32(g) / float32(a)
|
||||||
|
bf = float32(b) / float32(a)
|
||||||
|
af = float32(a) / 0xffff
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Use the previous composite mode if possible.
|
||||||
|
compositemode := driver.CompositeModeSourceOver
|
||||||
|
if af < 1.0 {
|
||||||
|
compositemode = driver.CompositeModeCopy
|
||||||
|
}
|
||||||
|
|
||||||
|
dw, dh := width, height
|
||||||
|
sw, sh := emptyImage.Size()
|
||||||
|
vs := make([]float32, 4*graphics.VertexFloatNum)
|
||||||
|
graphics.PutQuadVertices(vs, emptyImage, 0, 0, sw, sh,
|
||||||
|
float32(dw)/float32(sw), 0, 0, float32(dh)/float32(sh), float32(x), float32(y),
|
||||||
|
rf, gf, bf, af)
|
||||||
|
is := graphics.QuadIndices()
|
||||||
|
|
||||||
|
i.DrawTriangles(emptyImage, vs, is, nil, compositemode, driver.FilterNearest, driver.AddressClampToZero)
|
||||||
|
}
|
||||||
|
|
||||||
func (i *Image) IsVolatile() bool {
|
func (i *Image) IsVolatile() bool {
|
||||||
return i.volatile
|
return i.volatile
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ package shareable
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"image/color"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@ -329,6 +330,28 @@ func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *Image) Fill(clr color.Color) {
|
||||||
|
backendsM.Lock()
|
||||||
|
defer backendsM.Unlock()
|
||||||
|
|
||||||
|
if i.disposed {
|
||||||
|
panic("shareable: the drawing target image must not be disposed (Fill)")
|
||||||
|
}
|
||||||
|
if i.backend == nil {
|
||||||
|
if _, _, _, a := clr.RGBA(); a == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i.ensureNotShared()
|
||||||
|
|
||||||
|
x, y, width, height := i.region()
|
||||||
|
i.backend.restorable.Fill(clr, x, y, width, height)
|
||||||
|
|
||||||
|
i.nonUpdatedCount = 0
|
||||||
|
delete(imagesToMakeShared, i)
|
||||||
|
}
|
||||||
|
|
||||||
// ClearFramebuffer clears the image with a color. This affects not only the (0, 0)-(width, height) region but also
|
// ClearFramebuffer clears the image with a color. This affects not only the (0, 0)-(width, height) region but also
|
||||||
// the whole framebuffer region.
|
// the whole framebuffer region.
|
||||||
func (i *Image) ClearFramebuffer() {
|
func (i *Image) ClearFramebuffer() {
|
||||||
|
Loading…
Reference in New Issue
Block a user