From 66bf40dc84a9b84a20002753f1f97e60e26e2590 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Tue, 5 Jul 2022 00:28:50 +0900 Subject: [PATCH] ebiten: bug fix: resolveSetVerticesCacheIfNeeded could resolve more vertices Closes #2178 --- image.go | 24 +++++++++++------------- image_test.go | 10 +++++++--- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/image.go b/image.go index 6721ff0bf..6c34cc35e 100644 --- a/image.go +++ b/image.go @@ -66,10 +66,10 @@ func (i *Image) resolveSetVerticesCacheIfNeeded() { } l := len(i.setVerticesCache) - vs := make([]float32, l*graphics.VertexFloatNum*4) + vs := graphics.Vertices(l * 4) is := make([]uint16, l*6) sx, sy := emptyImage.adjustPositionF32(1, 1) - var idx uint16 + var idx int for p, c := range i.setVerticesCache { dx := float32(p[0]) dy := float32(p[1]) @@ -115,20 +115,19 @@ func (i *Image) resolveSetVerticesCacheIfNeeded() { vs[graphics.VertexFloatNum*4*idx+30] = cbf vs[graphics.VertexFloatNum*4*idx+31] = caf - is[6*idx] = 4 * idx - is[6*idx+1] = 4*idx + 1 - is[6*idx+2] = 4*idx + 2 - is[6*idx+3] = 4*idx + 1 - is[6*idx+4] = 4*idx + 2 - is[6*idx+5] = 4*idx + 3 + is[6*idx] = uint16(4 * idx) + is[6*idx+1] = uint16(4*idx + 1) + is[6*idx+2] = uint16(4*idx + 2) + is[6*idx+3] = uint16(4*idx + 1) + is[6*idx+4] = uint16(4*idx + 2) + is[6*idx+5] = uint16(4*idx + 3) idx++ } + i.setVerticesCache = nil srcs := [graphics.ShaderImageNum]*ui.Image{emptyImage.image} i.image.DrawTriangles(srcs, vs, is, affine.ColorMIdentity{}, graphicsdriver.CompositeModeSourceOver, graphicsdriver.FilterNearest, graphicsdriver.AddressUnsafe, i.adjustedRegion(), graphicsdriver.Region{}, [graphics.ShaderImageNum - 1][2]float32{}, nil, nil, false, true) - - i.setVerticesCache = nil } // Size returns the size of the image. @@ -843,9 +842,8 @@ func (i *Image) Set(x, y int, clr color.Color) { dx, dy := i.adjustPosition(x, y) cr, cg, cb, ca := clr.RGBA() i.setVerticesCache[[2]int{dx, dy}] = [4]byte{byte(cr / 0x101), byte(cg / 0x101), byte(cb / 0x101), byte(ca / 0x101)} - // TODO: This fails with 2049 or more. In theory this should work with 10000. Investigate why (#2178). - // Probably this is because the vertices number exceeds 65536 (=2048*32), but why is there such a limitation? - if len(i.setVerticesCache) >= 2048 { + // One square requires 6 indices (= 2 triangles). + if len(i.setVerticesCache) >= graphics.IndicesNum/6 { i.resolveSetVerticesCacheIfNeeded() } } diff --git a/image_test.go b/image_test.go index d4da2172c..7483a8fbf 100644 --- a/image_test.go +++ b/image_test.go @@ -2175,12 +2175,16 @@ func TestImageDrawTrianglesShaderInterpolatesValues(t *testing.T) { // Issue #1137 func TestImageDrawOver(t *testing.T) { - dst := ebiten.NewImage(320, 240) + const ( + w = 320 + h = 240 + ) + dst := ebiten.NewImage(w, h) src := image.NewUniform(color.RGBA{0xff, 0, 0, 0xff}) // This must not cause infinite-loop. draw.Draw(dst, dst.Bounds(), src, image.ZP, draw.Over) - for j := 0; j < 240; j++ { - for i := 0; i < 320; i++ { + for j := 0; j < h; j++ { + for i := 0; i < w; i++ { got := dst.At(i, j) want := color.RGBA{0xff, 0, 0, 0xff} if got != want {