From b83f0acc4de1653903e34f7b7c94664d55fab8d6 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Thu, 2 Jul 2020 23:06:58 +0900 Subject: [PATCH] Remove source-region information from vertices Fixes #1210 --- image.go | 32 +++------- internal/graphics/vertices.go | 2 +- internal/graphicscommand/command.go | 8 --- internal/graphicscommand/image.go | 20 +++--- internal/graphicscommand/image_test.go | 8 +-- internal/graphicsdriver/metal/graphics.go | 1 - .../graphicsdriver/opengl/defaultshader.go | 7 +- internal/graphicsdriver/opengl/program.go | 4 -- internal/mipmap/mipmap.go | 8 +-- internal/mipmap/vertex.go | 64 +++++++------------ internal/restorable/image.go | 28 ++++---- internal/restorable/images_test.go | 8 +-- internal/shareable/image.go | 32 ++++------ internal/shareable/image_test.go | 8 +-- 14 files changed, 85 insertions(+), 145 deletions(-) diff --git a/image.go b/image.go index 046026e12..0651520b4 100644 --- a/image.go +++ b/image.go @@ -309,30 +309,21 @@ func (i *Image) DrawTriangles(vertices []Vertex, indices []uint16, img *Image, o filter = driver.Filter(img.filter) } - b := img.Bounds() - bx0 := float32(b.Min.X) - by0 := float32(b.Min.Y) - bx1 := float32(b.Max.X) - by1 := float32(b.Max.Y) - vs := make([]float32, len(vertices)*graphics.VertexFloatNum) for i, v := range vertices { vs[i*graphics.VertexFloatNum] = v.DstX vs[i*graphics.VertexFloatNum+1] = v.DstY vs[i*graphics.VertexFloatNum+2] = v.SrcX vs[i*graphics.VertexFloatNum+3] = v.SrcY - vs[i*graphics.VertexFloatNum+4] = bx0 - vs[i*graphics.VertexFloatNum+5] = by0 - vs[i*graphics.VertexFloatNum+6] = bx1 - vs[i*graphics.VertexFloatNum+7] = by1 - vs[i*graphics.VertexFloatNum+8] = v.ColorR - vs[i*graphics.VertexFloatNum+9] = v.ColorG - vs[i*graphics.VertexFloatNum+10] = v.ColorB - vs[i*graphics.VertexFloatNum+11] = v.ColorA + vs[i*graphics.VertexFloatNum+4] = v.ColorR + vs[i*graphics.VertexFloatNum+5] = v.ColorG + vs[i*graphics.VertexFloatNum+6] = v.ColorB + vs[i*graphics.VertexFloatNum+7] = v.ColorA } is := make([]uint16, len(indices)) copy(is, indices) + b := img.Bounds() sr := driver.Region{ X: float32(b.Min.X), Y: float32(b.Min.Y), @@ -396,15 +387,10 @@ func (i *Image) DrawTrianglesWithShader(vertices []Vertex, indices []uint16, sha vs[i*graphics.VertexFloatNum+1] = v.DstY vs[i*graphics.VertexFloatNum+2] = v.SrcX vs[i*graphics.VertexFloatNum+3] = v.SrcY - // TODO: Remove these values for the source region. - vs[i*graphics.VertexFloatNum+4] = 0 - vs[i*graphics.VertexFloatNum+5] = 0 - vs[i*graphics.VertexFloatNum+6] = 0 - vs[i*graphics.VertexFloatNum+7] = 0 - vs[i*graphics.VertexFloatNum+8] = v.ColorR - vs[i*graphics.VertexFloatNum+9] = v.ColorG - vs[i*graphics.VertexFloatNum+10] = v.ColorB - vs[i*graphics.VertexFloatNum+11] = v.ColorA + vs[i*graphics.VertexFloatNum+4] = v.ColorR + vs[i*graphics.VertexFloatNum+5] = v.ColorG + vs[i*graphics.VertexFloatNum+6] = v.ColorB + vs[i*graphics.VertexFloatNum+7] = v.ColorA } is := make([]uint16, len(indices)) copy(is, indices) diff --git a/internal/graphics/vertices.go b/internal/graphics/vertices.go index 0dff03623..7e6a8254b 100644 --- a/internal/graphics/vertices.go +++ b/internal/graphics/vertices.go @@ -16,7 +16,7 @@ package graphics const ( IndicesNum = (1 << 16) / 3 * 3 // Adjust num for triangles. - VertexFloatNum = 12 + VertexFloatNum = 8 ) var ( diff --git a/internal/graphicscommand/command.go b/internal/graphicscommand/command.go index 144b2660c..901e945ce 100644 --- a/internal/graphicscommand/command.go +++ b/internal/graphicscommand/command.go @@ -232,10 +232,6 @@ func (q *commandQueue) Flush() error { // Convert pixels to texels. vs[i*graphics.VertexFloatNum+2] /= s.width vs[i*graphics.VertexFloatNum+3] /= s.height - vs[i*graphics.VertexFloatNum+4] /= s.width - vs[i*graphics.VertexFloatNum+5] /= s.height - vs[i*graphics.VertexFloatNum+6] /= s.width - vs[i*graphics.VertexFloatNum+7] /= s.height // Avoid the center of the pixel, which is problematic (#929, #1171). // Instead, align the vertices with about 1/3 pixels. @@ -263,10 +259,6 @@ func (q *commandQueue) Flush() error { // Convert pixels to texels. vs[i*graphics.VertexFloatNum+2] /= s.width vs[i*graphics.VertexFloatNum+3] /= s.height - vs[i*graphics.VertexFloatNum+4] /= s.width - vs[i*graphics.VertexFloatNum+5] /= s.height - vs[i*graphics.VertexFloatNum+6] /= s.width - vs[i*graphics.VertexFloatNum+7] /= s.height } } diff --git a/internal/graphicscommand/image.go b/internal/graphicscommand/image.go index c9cb3b11d..60455f8b6 100644 --- a/internal/graphicscommand/image.go +++ b/internal/graphicscommand/image.go @@ -137,18 +137,14 @@ func processSrc(src *Image) { // // The vertex floats are: // -// 0: Destination X in pixels -// 1: Destination Y in pixels -// 2: Source X in pixels (not texels!) -// 3: Source Y in pixels -// 4: Bounds of the source min X in pixels -// 5: Bounds of the source min Y in pixels -// 6: Bounds of the source max X in pixels -// 7: Bounds of the source max Y in pixels -// 8: Color R [0.0-1.0] -// 9: Color G -// 10: Color B -// 11: Color Y +// 0: Destination X in pixels +// 1: Destination Y in pixels +// 2: Source X in pixels (not texels!) +// 3: Source Y in pixels +// 4: Color R [0.0-1.0] +// 5: Color G +// 6: Color B +// 7: Color Y // // src and shader are exclusive and only either is non-nil. // diff --git a/internal/graphicscommand/image_test.go b/internal/graphicscommand/image_test.go index c96ac07e6..6181f1bef 100644 --- a/internal/graphicscommand/image_test.go +++ b/internal/graphicscommand/image_test.go @@ -30,10 +30,10 @@ func TestMain(m *testing.M) { func quadVertices(w, h float32) []float32 { return []float32{ - 0, 0, 0, 0, 0, 0, w, h, 1, 1, 1, 1, - w, 0, w, 0, 0, 0, w, h, 1, 1, 1, 1, - 0, w, 0, h, 0, 0, w, h, 1, 1, 1, 1, - w, h, w, h, 0, 0, w, h, 1, 1, 1, 1, + 0, 0, 0, 0, 1, 1, 1, 1, + w, 0, w, 0, 1, 1, 1, 1, + 0, w, 0, h, 1, 1, 1, 1, + w, h, w, h, 1, 1, 1, 1, } } diff --git a/internal/graphicsdriver/metal/graphics.go b/internal/graphicsdriver/metal/graphics.go index 76c2faff6..0d592fcd9 100644 --- a/internal/graphicsdriver/metal/graphics.go +++ b/internal/graphicsdriver/metal/graphics.go @@ -60,7 +60,6 @@ using namespace metal; struct VertexIn { packed_float2 position; packed_float2 tex; - packed_float4 tex_region; packed_float4 color; }; diff --git a/internal/graphicsdriver/opengl/defaultshader.go b/internal/graphicsdriver/opengl/defaultshader.go index 03b76f611..dc7bdce66 100644 --- a/internal/graphicsdriver/opengl/defaultshader.go +++ b/internal/graphicsdriver/opengl/defaultshader.go @@ -111,7 +111,6 @@ const ( uniform vec2 viewport_size; attribute vec2 vertex; attribute vec2 tex; -attribute vec4 tex_region; attribute vec4 color_scale; varying vec2 varying_tex; varying vec4 varying_color_scale; @@ -164,14 +163,14 @@ highp float floorMod(highp float x, highp float y) { return x - y * floor(x/y); } -highp vec2 adjustTexelByAddress(highp vec2 p, highp vec4 tex_region) { +highp vec2 adjustTexelByAddress(highp vec2 p, highp vec4 source_region) { #if defined(ADDRESS_CLAMP_TO_ZERO) return p; #endif #if defined(ADDRESS_REPEAT) - highp vec2 o = vec2(tex_region[0], tex_region[1]); - highp vec2 size = vec2(tex_region[2] - tex_region[0], tex_region[3] - tex_region[1]); + highp vec2 o = vec2(source_region[0], source_region[1]); + highp vec2 size = vec2(source_region[2] - source_region[0], source_region[3] - source_region[1]); return vec2(floorMod((p.x - o.x), size.x) + o.x, floorMod((p.y - o.y), size.y) + o.y); #endif diff --git a/internal/graphicsdriver/opengl/program.go b/internal/graphicsdriver/opengl/program.go index 382b733c9..e8df40244 100644 --- a/internal/graphicsdriver/opengl/program.go +++ b/internal/graphicsdriver/opengl/program.go @@ -97,10 +97,6 @@ var theArrayBufferLayout = arrayBufferLayout{ name: "tex", num: 2, }, - { - name: "tex_region", - num: 4, - }, { name: "color_scale", num: 4, diff --git a/internal/mipmap/mipmap.go b/internal/mipmap/mipmap.go index 2d9ab5fd6..8b66f3fde 100644 --- a/internal/mipmap/mipmap.go +++ b/internal/mipmap/mipmap.go @@ -178,10 +178,10 @@ func (m *Mipmap) DrawTriangles(src *Mipmap, vertices []float32, indices []uint16 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 + vertices[i*n+4] *= cr + vertices[i*n+5] *= cg + vertices[i*n+6] *= cb + vertices[i*n+7] *= ca } } diff --git a/internal/mipmap/vertex.go b/internal/mipmap/vertex.go index 630e8db88..6608e1e02 100644 --- a/internal/mipmap/vertex.go +++ b/internal/mipmap/vertex.go @@ -68,59 +68,43 @@ func quadVertices(sx0, sy0, sx1, sy1 int, a, b, c, d, tx, ty float32, cr, cg, cb // This function is very performance-sensitive and implement in a very dumb way. vs := vertexSlice(4, last) - _ = vs[:48] + _ = vs[:32] vs[0] = tx vs[1] = ty vs[2] = u0 vs[3] = v0 - vs[4] = u0 - vs[5] = v0 - vs[6] = u1 - vs[7] = v1 - vs[8] = cr - vs[9] = cg - vs[10] = cb - vs[11] = ca + vs[4] = cr + vs[5] = cg + vs[6] = cb + vs[7] = ca - vs[12] = ax + tx - vs[13] = cx + ty - vs[14] = u1 - vs[15] = v0 - vs[16] = u0 - vs[17] = v0 - vs[18] = u1 + vs[8] = ax + tx + vs[9] = cx + ty + vs[10] = u1 + vs[11] = v0 + vs[12] = cr + vs[13] = cg + vs[14] = cb + vs[15] = ca + + vs[16] = by + tx + vs[17] = dy + ty + vs[18] = u0 vs[19] = v1 vs[20] = cr vs[21] = cg vs[22] = cb vs[23] = ca - vs[24] = by + tx - vs[25] = dy + ty - vs[26] = u0 + vs[24] = ax + by + tx + vs[25] = cx + dy + ty + vs[26] = u1 vs[27] = v1 - vs[28] = u0 - vs[29] = v0 - vs[30] = u1 - vs[31] = v1 - vs[32] = cr - vs[33] = cg - vs[34] = cb - vs[35] = ca - - vs[36] = ax + by + tx - vs[37] = cx + dy + ty - vs[38] = u1 - vs[39] = v1 - vs[40] = u0 - vs[41] = v0 - vs[42] = u1 - vs[43] = v1 - vs[44] = cr - vs[45] = cg - vs[46] = cb - vs[47] = ca + vs[28] = cr + vs[29] = cg + vs[30] = cb + vs[31] = ca return vs } diff --git a/internal/restorable/image.go b/internal/restorable/image.go index fc1c8362a..0de5718b8 100644 --- a/internal/restorable/image.go +++ b/internal/restorable/image.go @@ -207,10 +207,10 @@ func NewScreenFramebufferImage(width, height int) *Image { // quadVertices returns vertices to render a quad. These values are passed to graphicscommand.Image. func quadVertices(dx0, dy0, dx1, dy1, sx0, sy0, sx1, sy1, cr, cg, cb, ca float32) []float32 { return []float32{ - dx0, dy0, sx0, sy0, sx0, sy0, sx1, sy1, cr, cg, cb, ca, - dx1, dy0, sx1, sy0, sx0, sy0, sx1, sy1, cr, cg, cb, ca, - dx0, dy1, sx0, sy1, sx0, sy0, sx1, sy1, cr, cg, cb, ca, - dx1, dy1, sx1, sy1, sx0, sy0, sx1, sy1, cr, cg, cb, ca, + dx0, dy0, sx0, sy0, cr, cg, cb, ca, + dx1, dy0, sx1, sy0, cr, cg, cb, ca, + dx0, dy1, sx0, sy1, cr, cg, cb, ca, + dx1, dy1, sx1, sy1, cr, cg, cb, ca, } } @@ -357,18 +357,14 @@ func convertUniformVariables(uniforms []interface{}) []interface{} { // // The vertex floats are: // -// 0: Destination X in pixels -// 1: Destination Y in pixels -// 2: Source X in pixels (not texels!) -// 3: Source Y in pixels -// 4: Bounds of the source min X in pixels -// 5: Bounds of the source min Y in pixels -// 6: Bounds of the source max X in pixels -// 7: Bounds of the source max Y in pixels -// 8: Color R [0.0-1.0] -// 9: Color G -// 10: Color B -// 11: Color Y +// 0: Destination X in pixels +// 1: Destination Y in pixels +// 2: Source X in pixels (not texels!) +// 3: Source Y in pixels +// 4: Color R [0.0-1.0] +// 5: Color G +// 6: Color B +// 7: Color Y func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, shader *Shader, uniforms []interface{}) { if i.priority { panic("restorable: DrawTriangles cannot be called on a priority image") diff --git a/internal/restorable/images_test.go b/internal/restorable/images_test.go index 3cee48ed1..eafe4340f 100644 --- a/internal/restorable/images_test.go +++ b/internal/restorable/images_test.go @@ -107,10 +107,10 @@ func quadVertices(sw, sh, x, y int) []float32 { sx1 := float32(sw) sy1 := float32(sh) return []float32{ - dx0, dy0, sx0, sy0, sx0, sy0, sx1, sy1, 1, 1, 1, 1, - dx1, dy0, sx1, sy0, sx0, sy0, sx1, sy1, 1, 1, 1, 1, - dx0, dy1, sx0, sy1, sx0, sy0, sx1, sy1, 1, 1, 1, 1, - dx1, dy1, sx1, sy1, sx0, sy0, sx1, sy1, 1, 1, 1, 1, + dx0, dy0, sx0, sy0, 1, 1, 1, 1, + dx1, dy0, sx1, sy0, 1, 1, 1, 1, + dx0, dy1, sx0, sy1, 1, 1, 1, 1, + dx1, dy1, sx1, sy1, 1, 1, 1, 1, } } diff --git a/internal/shareable/image.go b/internal/shareable/image.go index 386b334da..7b22d8f26 100644 --- a/internal/shareable/image.go +++ b/internal/shareable/image.go @@ -214,10 +214,10 @@ func (i *Image) ensureNotShared() { sy1 := float32(oy + h) newImg := restorable.NewImage(w, h, i.volatile) vs := []float32{ - dx0, dy0, sx0, sy0, sx0, sy0, sx1, sy1, 1, 1, 1, 1, - dx1, dy0, sx1, sy0, sx0, sy0, sx1, sy1, 1, 1, 1, 1, - dx0, dy1, sx0, sy1, sx0, sy0, sx1, sy1, 1, 1, 1, 1, - dx1, dy1, sx1, sy1, sx0, sy0, sx1, sy1, 1, 1, 1, 1, + dx0, dy0, sx0, sy0, 1, 1, 1, 1, + dx1, dy0, sx1, sy0, 1, 1, 1, 1, + dx0, dy1, sx0, sy1, 1, 1, 1, 1, + dx1, dy1, sx1, sy1, 1, 1, 1, 1, } is := graphics.QuadIndices() newImg.DrawTriangles(i.backend.restorable, vs, is, nil, driver.CompositeModeCopy, driver.FilterNearest, driver.AddressUnsafe, driver.Region{}, nil, nil) @@ -297,18 +297,14 @@ func makeSharedIfNeeded(src *Image) { // // The vertex floats are: // -// 0: Destination X in pixels -// 1: Destination Y in pixels -// 2: Source X in pixels (the upper-left is (0, 0)) -// 3: Source Y in pixels -// 4: Bounds of the source min X in pixels -// 5: Bounds of the source min Y in pixels -// 6: Bounds of the source max X in pixels -// 7: Bounds of the source max Y in pixels -// 8: Color R [0.0-1.0] -// 9: Color G -// 10: Color B -// 11: Color Y +// 0: Destination X in pixels +// 1: Destination Y in pixels +// 2: Source X in pixels (the upper-left is (0, 0)) +// 3: Source Y in pixels +// 4: Color R [0.0-1.0] +// 5: Color G +// 6: Color B +// 7: Color Y func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16, colorm *affine.ColorM, mode driver.CompositeMode, filter driver.Filter, address driver.Address, sourceRegion driver.Region, shader *Shader, uniforms []interface{}) { backendsM.Lock() // Do not use defer for performance. @@ -350,10 +346,6 @@ func (i *Image) DrawTriangles(img *Image, vertices []float32, indices []uint16, vertices[i*graphics.VertexFloatNum+1] += dy vertices[i*graphics.VertexFloatNum+2] += oxf vertices[i*graphics.VertexFloatNum+3] += oyf - vertices[i*graphics.VertexFloatNum+4] += oxf - vertices[i*graphics.VertexFloatNum+5] += oyf - vertices[i*graphics.VertexFloatNum+6] += oxf - vertices[i*graphics.VertexFloatNum+7] += oyf } if address != driver.AddressUnsafe { sourceRegion.X += oxf diff --git a/internal/shareable/image_test.go b/internal/shareable/image_test.go index a396e4df0..62582989c 100644 --- a/internal/shareable/image_test.go +++ b/internal/shareable/image_test.go @@ -46,10 +46,10 @@ func quadVertices(sw, sh, x, y int, scalex float32) []float32 { sx1 := float32(sw) sy1 := float32(sh) return []float32{ - dx0, dy0, sx0, sy0, sx0, sy0, sx1, sy1, 1, 1, 1, 1, - dx1, dy0, sx1, sy0, sx0, sy0, sx1, sy1, 1, 1, 1, 1, - dx0, dy1, sx0, sy1, sx0, sy0, sx1, sy1, 1, 1, 1, 1, - dx1, dy1, sx1, sy1, sx0, sy0, sx1, sy1, 1, 1, 1, 1, + dx0, dy0, sx0, sy0, 1, 1, 1, 1, + dx1, dy0, sx1, sy0, 1, 1, 1, 1, + dx0, dy1, sx0, sy1, 1, 1, 1, 1, + dx1, dy1, sx1, sy1, 1, 1, 1, 1, } }