From 55f8222855b7775535685b7c91f2ccb853d0c838 Mon Sep 17 00:00:00 2001 From: Will McKinnon Date: Wed, 26 Oct 2022 00:25:33 -0400 Subject: [PATCH] refactor: improved rounded corner shader --- include/sway/desktop/fx_renderer.h | 5 ++--- include/sway/desktop/shaders.h | 36 +++++++++--------------------- sway/desktop/fx_renderer.c | 10 ++++----- 3 files changed, 17 insertions(+), 34 deletions(-) diff --git a/include/sway/desktop/fx_renderer.h b/include/sway/desktop/fx_renderer.h index cc518284..39c1a25b 100644 --- a/include/sway/desktop/fx_renderer.h +++ b/include/sway/desktop/fx_renderer.h @@ -41,11 +41,10 @@ struct fx_renderer { GLint is_top_right; GLint is_bottom_left; GLint is_bottom_right; - GLint width; - GLint height; GLint position; GLint radius; - GLint thickness; + GLint half_size; + GLint half_thickness; } corner; struct gles2_tex_shader tex_rgba; struct gles2_tex_shader tex_rgbx; diff --git a/include/sway/desktop/shaders.h b/include/sway/desktop/shaders.h index a5ff3d5f..a30d45e0 100644 --- a/include/sway/desktop/shaders.h +++ b/include/sway/desktop/shaders.h @@ -113,11 +113,10 @@ const GLchar corner_fragment_src[] = "uniform bool is_bottom_left;\n" "uniform bool is_bottom_right;\n" "\n" -"uniform float width;\n" -"uniform float height;\n" "uniform vec2 position;\n" "uniform float radius;\n" -"uniform float thickness;\n" +"uniform vec2 half_size;\n" +"uniform float half_thickness;\n" "\n" "float roundedBoxSDF(vec2 center, vec2 size, float radius) {\n" " return length(max(abs(center) - size + radius, 0.0)) - radius;\n" @@ -125,36 +124,23 @@ const GLchar corner_fragment_src[] = "\n" "void main() {\n" " gl_FragColor = v_color;\n" -" vec2 size = vec2(width, height);\n" -" vec2 pos = vec2(position.x - (width + thickness) * 0.5, position.y -\n" -" (width + thickness) * 0.5);\n" -" vec2 rel_pos = gl_FragCoord.xy - pos - size - thickness * 0.5;\n" -"\n" -" float distance = roundedBoxSDF(\n" -" rel_pos,\n" // Center -" (size - thickness) * 0.5,\n" // Size -" radius + thickness * 0.5\n" // Radius -" );\n" -"\n" -" float smoothedAlphaOuter = 1.0 - smoothstep(-1.0, 1.0, distance - thickness * 0.5);\n" - // Creates a inner circle that isn't as anti-aliased as the outer ring -" float smoothedAlphaInner = 1.0 - smoothstep(-1.0, 0.5, distance + thickness * 0.5);\n" +" vec2 center = gl_FragCoord.xy - position - half_size;\n" +" float distance = roundedBoxSDF(center, half_size - half_thickness, radius + half_thickness);\n" +" float smoothedAlphaOuter = 1.0 - smoothstep(-1.0, 1.0, distance - half_thickness);\n" +// Create an inner circle that isn't as anti-aliased as the outer ring +" float smoothedAlphaInner = 1.0 - smoothstep(-1.0, 0.5, distance + half_thickness);\n" " gl_FragColor = mix(vec4(0), gl_FragColor, smoothedAlphaOuter - smoothedAlphaInner);\n" "\n" -// top left -" if (is_top_left && (rel_pos.y > 0.0 || rel_pos.x > 0.0)) {\n" +" if (is_top_left && (center.y > 0.0 || center.x > 0.0)) {\n" " discard;\n" " }\n" -// top right -" else if (is_top_right && (rel_pos.y > 0.0 || rel_pos.x < 0.0)) {\n" +" else if (is_top_right && (center.y > 0.0 || center.x < 0.0)) {\n" " discard;\n" " }\n" -// bottom left -" else if (is_bottom_left && (rel_pos.y < 0.0 || rel_pos.x > 0.0)) {\n" +" else if (is_bottom_left && (center.y < 0.0 || center.x > 0.0)) {\n" " discard;\n" " }\n" -// bottom right -" else if (is_bottom_right && (rel_pos.y < 0.0 || rel_pos.x < 0.0)) {\n" +" else if (is_bottom_right && (center.y < 0.0 || center.x < 0.0)) {\n" " discard;\n" " }\n" "}\n"; diff --git a/sway/desktop/fx_renderer.c b/sway/desktop/fx_renderer.c index eb281bd5..7c8ebc43 100644 --- a/sway/desktop/fx_renderer.c +++ b/sway/desktop/fx_renderer.c @@ -148,11 +148,10 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) { renderer->shaders.corner.is_top_right = glGetUniformLocation(prog, "is_top_right"); renderer->shaders.corner.is_bottom_left = glGetUniformLocation(prog, "is_bottom_left"); renderer->shaders.corner.is_bottom_right = glGetUniformLocation(prog, "is_bottom_right"); - renderer->shaders.corner.width = glGetUniformLocation(prog, "width"); - renderer->shaders.corner.height = glGetUniformLocation(prog, "height"); renderer->shaders.corner.position = glGetUniformLocation(prog, "position"); renderer->shaders.corner.radius = glGetUniformLocation(prog, "radius"); - renderer->shaders.corner.thickness = glGetUniformLocation(prog, "thickness"); + renderer->shaders.corner.half_size = glGetUniformLocation(prog, "half_size"); + renderer->shaders.corner.half_thickness = glGetUniformLocation(prog, "half_thickness"); // fragment shaders prog = link_program(tex_vertex_src, tex_fragment_src_rgba); @@ -393,11 +392,10 @@ void fx_render_border_corner(struct fx_renderer *renderer, const struct wlr_box glUniform1f(renderer->shaders.corner.is_bottom_left, corner_location == BOTTOM_LEFT); glUniform1f(renderer->shaders.corner.is_bottom_right, corner_location == BOTTOM_RIGHT); - glUniform1f(renderer->shaders.corner.width, box->width); - glUniform1f(renderer->shaders.corner.height, box->height); glUniform2f(renderer->shaders.corner.position, box->x, box->y); glUniform1f(renderer->shaders.corner.radius, radius); - glUniform1f(renderer->shaders.corner.thickness, border_thickness); + glUniform2f(renderer->shaders.corner.half_size, box->width / 2.0, box->height / 2.0); + glUniform1f(renderer->shaders.corner.half_thickness, border_thickness / 2.0); glVertexAttribPointer(renderer->shaders.corner.pos_attrib, 2, GL_FLOAT, GL_FALSE, 0, verts);