diff --git a/image.go b/image.go index 6d15a6abe..90c19f0da 100644 --- a/image.go +++ b/image.go @@ -203,10 +203,6 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) error { sy1 = r.Max.Y } } - vs := vertices(sx0, sy0, sx1, sy1, w, h, options.GeoM.impl) - if vs == nil { - return nil - } mode := opengl.CompositeMode(options.CompositeMode) filter := graphics.FilterNearest @@ -216,7 +212,7 @@ func (i *Image) DrawImage(img *Image, options *DrawImageOptions) error { filter = graphics.Filter(img.filter) } - i.restorable.DrawImage(img.restorable, vs, &options.ColorM.impl, mode, filter) + i.restorable.DrawImage(img.restorable, sx0, sy0, sx1, sy1, options.GeoM.impl, &options.ColorM.impl, mode, filter) return nil } diff --git a/internal/restorable/image.go b/internal/restorable/image.go index e034462c1..e6b59f5f8 100644 --- a/internal/restorable/image.go +++ b/internal/restorable/image.go @@ -29,11 +29,6 @@ import ( // MaxImageSize represents the maximum width/height of an image. const MaxImageSize = graphics.MaxImageSize -// QuadVertexSizeInBytes returns the byte size of vertices for a quadrilateral. -func QuadVertexSizeInBytes() int { - return graphics.QuadVertexSizeInBytes() -} - // drawImageHistoryItem is an item for history of draw-image commands. type drawImageHistoryItem struct { image *Image @@ -176,14 +171,18 @@ func (i *Image) ReplacePixels(pixels []byte) { } // DrawImage draws a given image img to the image. -func (i *Image) DrawImage(img *Image, vertices []float32, colorm *affine.ColorM, mode opengl.CompositeMode, filter graphics.Filter) { +func (i *Image) DrawImage(img *Image, sx0, sy0, sx1, sy1 int, geom *affine.GeoM, colorm *affine.ColorM, mode opengl.CompositeMode, filter graphics.Filter) { theImages.makeStaleIfDependingOn(i) + vs := img.vertices(sx0, sy0, sx1, sy1, geom) + if vs == nil { + return + } if img.stale || img.volatile || !IsRestoringEnabled() { i.makeStale() } else { - i.appendDrawImageHistory(img, vertices, colorm, mode, filter) + i.appendDrawImageHistory(img, vs, colorm, mode, filter) } - i.image.DrawImage(img.image, vertices, colorm, mode, filter) + i.image.DrawImage(img.image, vs, colorm, mode, filter) } // appendDrawImageHistory appends a draw-image history item to the image. diff --git a/internal/restorable/images_test.go b/internal/restorable/images_test.go index 62c6b1a20..4a037d97c 100644 --- a/internal/restorable/images_test.go +++ b/internal/restorable/images_test.go @@ -132,7 +132,7 @@ func TestRestoreChain(t *testing.T) { clr := color.RGBA{0x00, 0x00, 0x00, 0xff} fill(imgs[0], clr.R, clr.G, clr.B, clr.A) for i := 0; i < num-1; i++ { - imgs[i+1].DrawImage(imgs[i], vertices(1, 1, 0, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) + imgs[i+1].DrawImage(imgs[i], 0, 0, 1, 1, nil, &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) } if err := ResolveStaleImages(); err != nil { t.Fatal(err) @@ -167,10 +167,10 @@ func TestRestoreOverrideSource(t *testing.T) { clr0 := color.RGBA{0x00, 0x00, 0x00, 0xff} clr1 := color.RGBA{0x00, 0x00, 0x01, 0xff} fill(img1, clr0.R, clr0.G, clr0.B, clr0.A) - img2.DrawImage(img1, vertices(1, 1, 0, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) - img3.DrawImage(img2, vertices(1, 1, 0, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) + img2.DrawImage(img1, 0, 0, 1, 1, nil, &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) + img3.DrawImage(img2, 0, 0, 1, 1, nil, &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) fill(img0, clr1.R, clr1.G, clr1.B, clr1.A) - img1.DrawImage(img0, vertices(1, 1, 0, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) + img1.DrawImage(img0, 0, 0, 1, 1, nil, &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) if err := ResolveStaleImages(); err != nil { t.Fatal(err) } @@ -248,15 +248,15 @@ func TestRestoreComplexGraph(t *testing.T) { img1.Dispose() img0.Dispose() }() - img3.DrawImage(img0, vertices(4, 1, 0, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) - img3.DrawImage(img1, vertices(4, 1, 1, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) - img4.DrawImage(img1, vertices(4, 1, 1, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) - img4.DrawImage(img2, vertices(4, 1, 2, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) - img5.DrawImage(img3, vertices(4, 1, 0, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) - img6.DrawImage(img3, vertices(4, 1, 0, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) - img6.DrawImage(img4, vertices(4, 1, 1, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) - img7.DrawImage(img2, vertices(4, 1, 0, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) - img7.DrawImage(img3, vertices(4, 1, 2, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) + img3.DrawImage(img0, 0, 0, 4, 1, (*affine.GeoM)(nil).Translate(0, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) + img3.DrawImage(img1, 0, 0, 4, 1, (*affine.GeoM)(nil).Translate(1, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) + img4.DrawImage(img1, 0, 0, 4, 1, (*affine.GeoM)(nil).Translate(1, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) + img4.DrawImage(img2, 0, 0, 4, 1, (*affine.GeoM)(nil).Translate(2, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) + img5.DrawImage(img3, 0, 0, 4, 1, (*affine.GeoM)(nil).Translate(0, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) + img6.DrawImage(img3, 0, 0, 4, 1, (*affine.GeoM)(nil).Translate(0, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) + img6.DrawImage(img4, 0, 0, 4, 1, (*affine.GeoM)(nil).Translate(1, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) + img7.DrawImage(img2, 0, 0, 4, 1, (*affine.GeoM)(nil).Translate(0, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) + img7.DrawImage(img3, 0, 0, 4, 1, (*affine.GeoM)(nil).Translate(2, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) if err := ResolveStaleImages(); err != nil { t.Fatal(err) } @@ -343,8 +343,8 @@ func TestRestoreRecursive(t *testing.T) { img1.Dispose() img0.Dispose() }() - img1.DrawImage(img0, vertices(4, 1, 1, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) - img0.DrawImage(img1, vertices(4, 1, 1, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) + img1.DrawImage(img0, 0, 0, 4, 1, (*affine.GeoM)(nil).Translate(1, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) + img0.DrawImage(img1, 0, 0, 4, 1, (*affine.GeoM)(nil).Translate(1, 0), &affine.ColorM{}, opengl.CompositeModeSourceOver, graphics.FilterNearest) if err := ResolveStaleImages(); err != nil { t.Fatal(err) } diff --git a/vertices.go b/internal/restorable/vertices.go similarity index 91% rename from vertices.go rename to internal/restorable/vertices.go index 4ebd522c1..f020c7896 100644 --- a/vertices.go +++ b/internal/restorable/vertices.go @@ -12,15 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -package ebiten +package restorable import ( "github.com/hajimehoshi/ebiten/internal/affine" - "github.com/hajimehoshi/ebiten/internal/restorable" + "github.com/hajimehoshi/ebiten/internal/graphics" ) var ( - quadFloat32Num = restorable.QuadVertexSizeInBytes() / 4 + quadFloat32Num = graphics.QuadVertexSizeInBytes() / 4 theVerticesBackend = &verticesBackend{} ) @@ -43,7 +43,7 @@ func (v *verticesBackend) get() []float32 { return s } -func vertices(sx0, sy0, sx1, sy1 int, width, height int, geo *affine.GeoM) []float32 { +func (i *Image) vertices(sx0, sy0, sx1, sy1 int, geo *affine.GeoM) []float32 { if sx0 >= sx1 || sy0 >= sy1 { return nil } @@ -75,6 +75,7 @@ func vertices(sx0, sy0, sx1, sy1 int, width, height int, geo *affine.GeoM) []flo // it really feels like we should be able to cache this computation // but it may not matter. + width, height := i.Size() w := 1 h := 1 for w < width {