mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
shareable: NewImage* now returns a cleared image
This commit is contained in:
parent
1a335032a2
commit
7b5ad46e49
@ -102,12 +102,11 @@ func (c *graphicsContext) Update(afterFrameUpdate func()) error {
|
||||
// TODO: This clear is needed only when the screen size is changed.
|
||||
if c.offsetX > 0 || c.offsetY > 0 {
|
||||
op := &DrawImageOptions{}
|
||||
w, h := dummyImage.Size()
|
||||
w, h := emptyImage.Size()
|
||||
s := float64(graphics.MaxImageSize())
|
||||
op.GeoM.Scale(s/float64(w), s/float64(h))
|
||||
op.ColorM.Scale(0, 0, 0, 0)
|
||||
op.CompositeMode = CompositeModeCopy
|
||||
c.screen.DrawImage(dummyImage, op)
|
||||
c.screen.DrawImage(emptyImage, op)
|
||||
}
|
||||
|
||||
dw, dh := c.screen.Size()
|
||||
|
29
image.go
29
image.go
@ -26,10 +26,14 @@ import (
|
||||
"github.com/hajimehoshi/ebiten/internal/shareable"
|
||||
)
|
||||
|
||||
// dummyImage is an empty image used for filling other images with a uniform color.
|
||||
// emptyImage is an empty image used for filling other images with a uniform color.
|
||||
//
|
||||
// Do not call Fill or Clear on dummyImage or the program causes infinite recursion.
|
||||
var dummyImage = newImageWithoutInit(16, 16)
|
||||
// Do not call Fill or Clear on emptyImage or the program causes infinite recursion.
|
||||
var emptyImage *Image
|
||||
|
||||
func init() {
|
||||
emptyImage, _ = NewImage(16, 16, FilterDefault)
|
||||
}
|
||||
|
||||
// Image represents a rectangle set of pixels.
|
||||
// The pixel format is alpha-premultiplied RGBA.
|
||||
@ -82,12 +86,11 @@ func (i *Image) Fill(clr color.Color) error {
|
||||
|
||||
func (i *Image) fill(r, g, b, a uint8) {
|
||||
wd, hd := i.Size()
|
||||
ws, hs := dummyImage.Size()
|
||||
ws, hs := emptyImage.Size()
|
||||
sw := float64(wd) / float64(ws)
|
||||
sh := float64(hd) / float64(hs)
|
||||
op := &DrawImageOptions{}
|
||||
op.GeoM.Scale(sw, sh)
|
||||
op.ColorM.Scale(0, 0, 0, 0)
|
||||
if a > 0 {
|
||||
rf := float64(r) / float64(a)
|
||||
gf := float64(g) / float64(a)
|
||||
@ -97,7 +100,7 @@ func (i *Image) fill(r, g, b, a uint8) {
|
||||
}
|
||||
op.CompositeMode = CompositeModeCopy
|
||||
op.Filter = FilterNearest
|
||||
_ = i.DrawImage(dummyImage, op)
|
||||
_ = i.DrawImage(emptyImage, op)
|
||||
}
|
||||
|
||||
func (i *Image) isDisposed() bool {
|
||||
@ -351,23 +354,10 @@ func NewImage(width, height int, filter Filter) (*Image, error) {
|
||||
filter: filter,
|
||||
}
|
||||
i.addr = i
|
||||
i.fill(0, 0, 0, 0)
|
||||
runtime.SetFinalizer(i, (*Image).Dispose)
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// newImageWithoutInit creates an empty image without initialization.
|
||||
func newImageWithoutInit(width, height int) *Image {
|
||||
s := shareable.NewImage(width, height)
|
||||
i := &Image{
|
||||
shareableImage: s,
|
||||
filter: FilterDefault,
|
||||
}
|
||||
i.addr = i
|
||||
runtime.SetFinalizer(i, (*Image).Dispose)
|
||||
return i
|
||||
}
|
||||
|
||||
// newVolatileImage returns an empty 'volatile' image.
|
||||
// A volatile image is always cleared at the start of a frame.
|
||||
//
|
||||
@ -389,7 +379,6 @@ func newVolatileImage(width, height int, filter Filter) *Image {
|
||||
filter: filter,
|
||||
}
|
||||
i.addr = i
|
||||
i.fill(0, 0, 0, 0)
|
||||
runtime.SetFinalizer(i, (*Image).Dispose)
|
||||
return i
|
||||
}
|
||||
|
@ -72,43 +72,43 @@ type Image struct {
|
||||
screen bool
|
||||
}
|
||||
|
||||
type rand struct {
|
||||
x, y, z, w uint32
|
||||
var emptyImage = newImageWithoutInit(16, 16, false)
|
||||
|
||||
func init() {
|
||||
w, h := emptyImage.Size()
|
||||
pix := make([]byte, 4*w*h)
|
||||
emptyImage.ReplacePixels(pix, 0, 0, w, h)
|
||||
}
|
||||
|
||||
func (r *rand) next() uint32 {
|
||||
// Xorshift: http://en.wikipedia.org/wiki/Xorshift
|
||||
t := r.x ^ (r.x << 11)
|
||||
r.x, r.y, r.z = r.y, r.z, r.w
|
||||
r.w = (r.w ^ (r.w >> 19)) ^ (t ^ (t >> 8))
|
||||
return r.w
|
||||
}
|
||||
|
||||
var theRand = &rand{12345678, 4185243, 776511, 45411}
|
||||
|
||||
// NewImage creates an empty image with the given size.
|
||||
func NewImage(width, height int, volatile bool) *Image {
|
||||
func newImageWithoutInit(width, height int, volatile bool) *Image {
|
||||
i := &Image{
|
||||
image: graphics.NewImage(width, height),
|
||||
volatile: volatile,
|
||||
}
|
||||
theImages.add(i)
|
||||
runtime.SetFinalizer(i, (*Image).Dispose)
|
||||
|
||||
// Put a random color pixel on newImg to make tests reliable
|
||||
// (e.g. shareable_test.TestEnsureNotShared. This test might pass
|
||||
// without this ReplacePixels even when the next DrawImage has a bug).
|
||||
// This avoids to use remaining GPU memory state unexpectedly.
|
||||
//
|
||||
// TODO: Is it better clearing the image? How about the cost?
|
||||
v := theRand.next()
|
||||
r, g, b := uint8(v>>24), uint8(v>>16), uint8(v>>8)
|
||||
i.ReplacePixels([]byte{r, g, b, 0xff}, 0, 0, 1, 1)
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
// NewImage creates an empty image with the given size.
|
||||
//
|
||||
// The returned image is cleared.
|
||||
func NewImage(width, height int, volatile bool) *Image {
|
||||
i := newImageWithoutInit(width, height, volatile)
|
||||
i.Clear(0, 0, width, height)
|
||||
return i
|
||||
}
|
||||
|
||||
func (i *Image) Clear(x, y, width, height int) {
|
||||
w, h := emptyImage.Size()
|
||||
geom := (*affine.GeoM)(nil).Scale(float64(width)/float64(w), float64(height)/float64(h))
|
||||
geom = geom.Translate(float64(x), float64(y))
|
||||
i.DrawImage(emptyImage, 0, 0, w, h, geom, nil, opengl.CompositeModeCopy, graphics.FilterNearest)
|
||||
}
|
||||
|
||||
// NewScreenFramebufferImage creates a special image that framebuffer is one for the screen.
|
||||
//
|
||||
// The returned image is cleared.
|
||||
func NewScreenFramebufferImage(width, height int) *Image {
|
||||
i := &Image{
|
||||
image: graphics.NewScreenFramebufferImage(width, height),
|
||||
@ -117,6 +117,7 @@ func NewScreenFramebufferImage(width, height int) *Image {
|
||||
}
|
||||
theImages.add(i)
|
||||
runtime.SetFinalizer(i, (*Image).Dispose)
|
||||
i.Clear(0, 0, width, height)
|
||||
return i
|
||||
}
|
||||
|
||||
|
@ -188,6 +188,8 @@ func (s *Image) dispose() {
|
||||
|
||||
s.backend.page.Free(s.node)
|
||||
if !s.backend.page.IsEmpty() {
|
||||
// As this part can be reused, this should be cleared explicitly.
|
||||
s.backend.restorable.Clear(s.region())
|
||||
return
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user