From c36d4678a3e379ce0bb6769a17bcfa7ac8f54674 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Tue, 17 Mar 2020 01:59:00 +0900 Subject: [PATCH] mipmap: Bug fix: DrawTriangles with a scale-only color matrix should be optimized Fixes #1101 --- image_test.go | 109 ++++++++++++++++++++++++++++++++++++++ internal/mipmap/mipmap.go | 19 ++++++- 2 files changed, 127 insertions(+), 1 deletion(-) diff --git a/image_test.go b/image_test.go index 102766ede..98a3cc183 100644 --- a/image_test.go +++ b/image_test.go @@ -1902,3 +1902,112 @@ func TestImageReplacePixelsOnSubImage(t *testing.T) { } } } + +func TestImageDrawTrianglesWithColorM(t *testing.T) { + const w, h = 16, 16 + dst0, _ := NewImage(w, h, FilterDefault) + dst1, _ := NewImage(w, h, FilterDefault) + src, _ := NewImage(w, h, FilterDefault) + src.Fill(color.White) + + vs0 := []Vertex{ + { + DstX: 0, + DstY: 0, + SrcX: 0, + SrcY: 0, + ColorR: 1, + ColorG: 1, + ColorB: 1, + ColorA: 1, + }, + { + DstX: w, + DstY: 0, + SrcX: w, + SrcY: 0, + ColorR: 1, + ColorG: 1, + ColorB: 1, + ColorA: 1, + }, + { + DstX: 0, + DstY: h, + SrcX: 0, + SrcY: h, + ColorR: 1, + ColorG: 1, + ColorB: 1, + ColorA: 1, + }, + { + DstX: w, + DstY: h, + SrcX: w, + SrcY: h, + ColorR: 1, + ColorG: 1, + ColorB: 1, + ColorA: 1, + }, + } + op := &DrawTrianglesOptions{} + op.ColorM.Scale(0.2, 0.4, 0.6, 0.8) + is := []uint16{0, 1, 2, 1, 2, 3} + dst0.DrawTriangles(vs0, is, src, op) + + vs1 := []Vertex{ + { + DstX: 0, + DstY: 0, + SrcX: 0, + SrcY: 0, + ColorR: 0.2, + ColorG: 0.4, + ColorB: 0.6, + ColorA: 0.8, + }, + { + DstX: w, + DstY: 0, + SrcX: w, + SrcY: 0, + ColorR: 0.2, + ColorG: 0.4, + ColorB: 0.6, + ColorA: 0.8, + }, + { + DstX: 0, + DstY: h, + SrcX: 0, + SrcY: h, + ColorR: 0.2, + ColorG: 0.4, + ColorB: 0.6, + ColorA: 0.8, + }, + { + DstX: w, + DstY: h, + SrcX: w, + SrcY: h, + ColorR: 0.2, + ColorG: 0.4, + ColorB: 0.6, + ColorA: 0.8, + }, + } + dst1.DrawTriangles(vs1, is, src, nil) + + for j := 0; j < h; j++ { + for i := 0; i < w; i++ { + got := dst0.At(i, j) + want := dst1.At(i, j) + if got != want { + t.Errorf("At(%d, %d): got: %v, want: %v", i, j, got, want) + } + } + } +} diff --git a/internal/mipmap/mipmap.go b/internal/mipmap/mipmap.go index 1f53e45f9..41e1737ad 100644 --- a/internal/mipmap/mipmap.go +++ b/internal/mipmap/mipmap.go @@ -132,7 +132,7 @@ func (m *Mipmap) DrawImage(src *Mipmap, bounds image.Rectangle, geom GeoM, color } cr, cg, cb, ca := float32(1), float32(1), float32(1), float32(1) - if colorm.ScaleOnly() { + if colorm != nil && colorm.ScaleOnly() { body, _ := colorm.UnsafeElements() cr = body[0] cg = body[5] @@ -166,6 +166,23 @@ func (m *Mipmap) DrawImage(src *Mipmap, bounds image.Rectangle, geom GeoM, color } func (m *Mipmap) DrawTriangles(src *Mipmap, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address) { + // TODO: Use a mipmap? (#909) + + if colorm != nil && colorm.ScaleOnly() { + body, _ := colorm.UnsafeElements() + cr := body[0] + cg := body[5] + cb := body[10] + ca := body[15] + colorm = nil + const n = graphics.VertexFloatNum + for i := 0; i < len(vertices)/n; i++ { + vertices[i*n+8] *= cr + vertices[i*n+9] *= cg + vertices[i*n+10] *= cb + vertices[i*n+11] *= ca + } + } m.orig.DrawTriangles(src.orig, vertices, indices, colorm, mode, filter, address) m.disposeMipmaps() }