From 4149a56524c95a7a31a9d856586e1620a7eb6305 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 23 Dec 2018 01:40:43 +0900 Subject: [PATCH] graphics: Refactoring: Use 12 floats for each vertex This is a preparation for #761. --- internal/graphics/vertices.go | 100 ++++++++++++---------- internal/graphicsdriver/metal/driver.go | 33 +++---- internal/graphicsdriver/opengl/program.go | 6 +- internal/graphicsdriver/opengl/shader.go | 41 ++++----- 4 files changed, 90 insertions(+), 90 deletions(-) diff --git a/internal/graphics/vertices.go b/internal/graphics/vertices.go index 5ef8af029..ceb92a738 100644 --- a/internal/graphics/vertices.go +++ b/internal/graphics/vertices.go @@ -25,7 +25,7 @@ type verticesBackend struct { const ( IndicesNum = (1 << 16) / 3 * 3 // Adjust num for triangles. - VertexFloatNum = 10 + VertexFloatNum = 12 ) func (v *verticesBackend) slice(n int) []float32 { @@ -81,8 +81,8 @@ func quadVerticesImpl(x, y, u0, v0, u1, v1, a, b, c, d, tx, ty, cr, cg, cb, ca f // Specifying a range explicitly here is redundant but this helps optimization // to eliminate boundary checks. // - // 4*VertexFloatNum is better than 40, but in GopherJS, optimization might not work. - vs := theVerticesBackend.slice(4)[0:40] + // 4*VertexFloatNum is better than 48, but in GopherJS, optimization might not work. + vs := theVerticesBackend.slice(4)[0:48] ax, by, cx, dy := a*x, b*y, c*x, d*y @@ -95,46 +95,54 @@ func quadVerticesImpl(x, y, u0, v0, u1, v1, a, b, c, d, tx, ty, cr, cg, cb, ca f // The second is needed to calculate source rectangle size in shader programs. vs[2] = u0 vs[3] = v0 - vs[4] = u1 - vs[5] = v1 - vs[6] = cr - vs[7] = cg - vs[8] = cb - vs[9] = ca + vs[4] = u0 + vs[5] = v0 + vs[6] = u1 + vs[7] = v1 + vs[8] = cr + vs[9] = cg + vs[10] = cb + vs[11] = ca // and the same for the other three coordinates - vs[10] = ax + tx - vs[11] = cx + ty - vs[12] = u1 - vs[13] = v0 - vs[14] = u0 - vs[15] = v1 - vs[16] = cr - vs[17] = cg - vs[18] = cb - vs[19] = 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[19] = v1 + vs[20] = cr + vs[21] = cg + vs[22] = cb + vs[23] = ca - vs[20] = by + tx - vs[21] = dy + ty - vs[22] = u0 - vs[23] = v1 - vs[24] = u1 - vs[25] = v0 - vs[26] = cr - vs[27] = cg - vs[28] = cb - vs[29] = ca + vs[24] = by + tx + vs[25] = dy + ty + vs[26] = u0 + 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[30] = ax + by + tx - vs[31] = cx + dy + ty - vs[32] = u1 - vs[33] = v1 - vs[34] = u0 - vs[35] = v0 - vs[36] = cr - vs[37] = cg - vs[38] = cb - vs[39] = 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 return vs } @@ -166,10 +174,12 @@ func PutVertex(vs []float32, width, height int, dx, dy, sx, sy float32, cr, cg, vs[1] = dy vs[2] = sx / wf vs[3] = sy / hf - vs[4] = -1 - vs[5] = -1 - vs[6] = cr - vs[7] = cg - vs[8] = cb - vs[9] = ca + vs[4] = 0 + vs[5] = 0 + vs[6] = 1 + vs[7] = 1 + vs[8] = cr + vs[9] = cg + vs[10] = cb + vs[11] = ca } diff --git a/internal/graphicsdriver/metal/driver.go b/internal/graphicsdriver/metal/driver.go index 9fd8efc33..e6cad38db 100644 --- a/internal/graphicsdriver/metal/driver.go +++ b/internal/graphicsdriver/metal/driver.go @@ -40,15 +40,15 @@ using namespace metal; struct VertexIn { packed_float2 position; - packed_float4 tex; + packed_float2 tex; + packed_float4 tex_region; packed_float4 color; }; struct VertexOut { float4 position [[position]]; float2 tex; - float2 tex_min; - float2 tex_max; + float4 tex_region; float4 color; }; @@ -68,18 +68,11 @@ vertex VertexOut VertexShader( VertexOut out = { .position = projectionMatrix * float4(in.position, 0, 1), - .tex = float2(in.tex[0], in.tex[1]), + .tex = in.tex, + .tex_region = in.tex_region, .color = in.color, }; - if (in.tex[2] >= 0 && in.tex[3] >= 0) { - out.tex_min = float2(min(in.tex[0], in.tex[2]), min(in.tex[1], in.tex[3])); - out.tex_max = float2(max(in.tex[0], in.tex[2]), max(in.tex[1], in.tex[3])); - } else { - out.tex_min = float2(0); - out.tex_max = float2(1); - } - return out; } @@ -117,10 +110,10 @@ fragment float4 FragmentShader(VertexOut v [[stage_in]], switch (filter) { case FILTER_NEAREST: { c = texture.sample(texture_sampler, v.tex); - if (v.tex.x < v.tex_min.x || - v.tex.y < v.tex_min.y || - (v.tex_max.x - texel_size.x / 512.0) <= v.tex.x || - (v.tex_max.y - texel_size.y / 512.0) <= v.tex.y) { + if (v.tex.x < v.tex_region[0] || + v.tex.y < v.tex_region[1] || + (v.tex_region[2] - texel_size.x / 512.0) <= v.tex.x || + (v.tex_region[3] - texel_size.y / 512.0) <= v.tex.y) { c = 0; } break; @@ -136,19 +129,19 @@ fragment float4 FragmentShader(VertexOut v [[stage_in]], float4 c2 = texture.sample(texture_sampler, float2(p0.x, p1.y)); float4 c3 = texture.sample(texture_sampler, p1); - if (p0.x < v.tex_min.x) { + if (p0.x < v.tex_region[0]) { c0 = 0; c2 = 0; } - if (p0.y < v.tex_min.y) { + if (p0.y < v.tex_region[1]) { c0 = 0; c1 = 0; } - if ((v.tex_max.x - texel_size.x / 512.0) <= p1.x) { + if ((v.tex_region[2] - texel_size.x / 512.0) <= p1.x) { c1 = 0; c3 = 0; } - if ((v.tex_max.y - texel_size.y / 512.0) <= p1.y) { + if ((v.tex_region[3] - texel_size.y / 512.0) <= p1.y) { c2 = 0; c3 = 0; } diff --git a/internal/graphicsdriver/opengl/program.go b/internal/graphicsdriver/opengl/program.go index c64c69bc5..3f160abbc 100644 --- a/internal/graphicsdriver/opengl/program.go +++ b/internal/graphicsdriver/opengl/program.go @@ -89,7 +89,11 @@ func initializeArrayBuferLayout() { num: 2, }, { - name: "tex_coord", + name: "tex", + num: 2, + }, + { + name: "tex_region", num: 4, }, { diff --git a/internal/graphicsdriver/opengl/shader.go b/internal/graphicsdriver/opengl/shader.go index b3437849c..90719e227 100644 --- a/internal/graphicsdriver/opengl/shader.go +++ b/internal/graphicsdriver/opengl/shader.go @@ -49,22 +49,16 @@ const ( shaderStrVertex = ` uniform vec2 viewport_size; attribute vec2 vertex; -attribute vec4 tex_coord; +attribute vec2 tex; +attribute vec4 tex_region; attribute vec4 color_scale; -varying vec2 varying_tex_coord; -varying vec2 varying_tex_coord_min; -varying vec2 varying_tex_coord_max; +varying vec2 varying_tex; +varying vec4 varying_tex_region; varying vec4 varying_color_scale; void main(void) { - varying_tex_coord = vec2(tex_coord[0], tex_coord[1]); - if (tex_coord[2] >= 0.0 && tex_coord[3] >= 0.0) { - varying_tex_coord_min = vec2(min(tex_coord[0], tex_coord[2]), min(tex_coord[1], tex_coord[3])); - varying_tex_coord_max = vec2(max(tex_coord[0], tex_coord[2]), max(tex_coord[1], tex_coord[3])); - } else { - varying_tex_coord_min = vec2(0, 0); - varying_tex_coord_max = vec2(1, 1); - } + varying_tex = tex; + varying_tex_region = tex_region; varying_color_scale = color_scale; mat4 projection_matrix = mat4( @@ -97,9 +91,8 @@ uniform highp vec2 source_size; uniform highp float scale; #endif -varying highp vec2 varying_tex_coord; -varying highp vec2 varying_tex_coord_min; -varying highp vec2 varying_tex_coord_max; +varying highp vec2 varying_tex; +varying highp vec4 varying_tex_region; varying highp vec4 varying_color_scale; // adjustTexel adjusts the two texels and returns the adjusted second texel. @@ -117,15 +110,15 @@ highp vec2 adjustTexel(highp vec2 p0, highp vec2 p1) { } void main(void) { - highp vec2 pos = varying_tex_coord; + highp vec2 pos = varying_tex; highp vec2 texel_size = 1.0 / source_size; #if defined(FILTER_NEAREST) vec4 color = texture2D(texture, pos); - if (pos.x < varying_tex_coord_min.x || - pos.y < varying_tex_coord_min.y || - (varying_tex_coord_max.x - texel_size.x / 512.0) <= pos.x || - (varying_tex_coord_max.y - texel_size.y / 512.0) <= pos.y) { + if (pos.x < varying_tex_region[0] || + pos.y < varying_tex_region[1] || + (varying_tex_region[2] - texel_size.x / 512.0) <= pos.x || + (varying_tex_region[3] - texel_size.y / 512.0) <= pos.y) { color = vec4(0, 0, 0, 0); } #endif @@ -140,19 +133,19 @@ void main(void) { vec4 c1 = texture2D(texture, vec2(p1.x, p0.y)); vec4 c2 = texture2D(texture, vec2(p0.x, p1.y)); vec4 c3 = texture2D(texture, p1); - if (p0.x < varying_tex_coord_min.x) { + if (p0.x < varying_tex_region[0]) { c0 = vec4(0, 0, 0, 0); c2 = vec4(0, 0, 0, 0); } - if (p0.y < varying_tex_coord_min.y) { + if (p0.y < varying_tex_region[1]) { c0 = vec4(0, 0, 0, 0); c1 = vec4(0, 0, 0, 0); } - if ((varying_tex_coord_max.x - texel_size.x / 512.0) <= p1.x) { + if ((varying_tex_region[2] - texel_size.x / 512.0) <= p1.x) { c1 = vec4(0, 0, 0, 0); c3 = vec4(0, 0, 0, 0); } - if ((varying_tex_coord_max.y - texel_size.y / 512.0) <= p1.y) { + if ((varying_tex_region[3] - texel_size.y / 512.0) <= p1.y) { c2 = vec4(0, 0, 0, 0); c3 = vec4(0, 0, 0, 0); }