ebiten: bug fix: resolveSetVerticesCacheIfNeeded could resolve more vertices

Closes #2178
This commit is contained in:
Hajime Hoshi 2022-07-05 00:28:50 +09:00
parent a70e069f0d
commit 66bf40dc84
2 changed files with 18 additions and 16 deletions

View File

@ -66,10 +66,10 @@ func (i *Image) resolveSetVerticesCacheIfNeeded() {
} }
l := len(i.setVerticesCache) l := len(i.setVerticesCache)
vs := make([]float32, l*graphics.VertexFloatNum*4) vs := graphics.Vertices(l * 4)
is := make([]uint16, l*6) is := make([]uint16, l*6)
sx, sy := emptyImage.adjustPositionF32(1, 1) sx, sy := emptyImage.adjustPositionF32(1, 1)
var idx uint16 var idx int
for p, c := range i.setVerticesCache { for p, c := range i.setVerticesCache {
dx := float32(p[0]) dx := float32(p[0])
dy := float32(p[1]) dy := float32(p[1])
@ -115,20 +115,19 @@ func (i *Image) resolveSetVerticesCacheIfNeeded() {
vs[graphics.VertexFloatNum*4*idx+30] = cbf vs[graphics.VertexFloatNum*4*idx+30] = cbf
vs[graphics.VertexFloatNum*4*idx+31] = caf vs[graphics.VertexFloatNum*4*idx+31] = caf
is[6*idx] = 4 * idx is[6*idx] = uint16(4 * idx)
is[6*idx+1] = 4*idx + 1 is[6*idx+1] = uint16(4*idx + 1)
is[6*idx+2] = 4*idx + 2 is[6*idx+2] = uint16(4*idx + 2)
is[6*idx+3] = 4*idx + 1 is[6*idx+3] = uint16(4*idx + 1)
is[6*idx+4] = 4*idx + 2 is[6*idx+4] = uint16(4*idx + 2)
is[6*idx+5] = 4*idx + 3 is[6*idx+5] = uint16(4*idx + 3)
idx++ idx++
} }
i.setVerticesCache = nil
srcs := [graphics.ShaderImageNum]*ui.Image{emptyImage.image} 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.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. // 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) dx, dy := i.adjustPosition(x, y)
cr, cg, cb, ca := clr.RGBA() 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)} 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). // One square requires 6 indices (= 2 triangles).
// Probably this is because the vertices number exceeds 65536 (=2048*32), but why is there such a limitation? if len(i.setVerticesCache) >= graphics.IndicesNum/6 {
if len(i.setVerticesCache) >= 2048 {
i.resolveSetVerticesCacheIfNeeded() i.resolveSetVerticesCacheIfNeeded()
} }
} }

View File

@ -2175,12 +2175,16 @@ func TestImageDrawTrianglesShaderInterpolatesValues(t *testing.T) {
// Issue #1137 // Issue #1137
func TestImageDrawOver(t *testing.T) { 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}) src := image.NewUniform(color.RGBA{0xff, 0, 0, 0xff})
// This must not cause infinite-loop. // This must not cause infinite-loop.
draw.Draw(dst, dst.Bounds(), src, image.ZP, draw.Over) draw.Draw(dst, dst.Bounds(), src, image.ZP, draw.Over)
for j := 0; j < 240; j++ { for j := 0; j < h; j++ {
for i := 0; i < 320; i++ { for i := 0; i < w; i++ {
got := dst.At(i, j) got := dst.At(i, j)
want := color.RGBA{0xff, 0, 0, 0xff} want := color.RGBA{0xff, 0, 0, 0xff}
if got != want { if got != want {