diff options
Diffstat (limited to 'sway/desktop/fx_renderer.c')
-rw-r--r-- | sway/desktop/fx_renderer.c | 94 |
1 files changed, 90 insertions, 4 deletions
diff --git a/sway/desktop/fx_renderer.c b/sway/desktop/fx_renderer.c index 7af4a313..2b5ba060 100644 --- a/sway/desktop/fx_renderer.c +++ b/sway/desktop/fx_renderer.c @@ -20,6 +20,8 @@ // shaders #include "quad_vert_src.h" #include "quad_frag_src.h" +#include "quad_round_tl_frag_src.h" +#include "quad_round_tr_frag_src.h" #include "corner_frag_src.h" #include "tex_vert_src.h" #include "tex_rgba_frag_src.h" @@ -97,6 +99,22 @@ bool init_frag_shader(struct gles2_tex_shader *shader, GLuint prog) { shader->size = glGetUniformLocation(prog, "size"); shader->position = glGetUniformLocation(prog, "position"); shader->radius = glGetUniformLocation(prog, "radius"); + shader->has_titlebar = glGetUniformLocation(prog, "has_titlebar"); + return true; +} + +// initializes a provided rounded quad shader and returns false if unsuccessful +bool init_rounded_quad_shader(struct rounded_quad_shader *shader, GLuint prog) { + shader->program = prog; + if (!shader->program) { + return false; + } + shader->proj = glGetUniformLocation(prog, "proj"); + shader->color = glGetUniformLocation(prog, "color"); + shader->pos_attrib = glGetAttribLocation(prog, "pos"); + shader->size = glGetUniformLocation(prog, "size"); + shader->position = glGetUniformLocation(prog, "position"); + shader->radius = glGetUniformLocation(prog, "radius"); return true; } @@ -133,6 +151,7 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) { // init shaders GLuint prog; + // quad fragment shader prog = link_program(quad_vert_src, quad_frag_src); renderer->shaders.quad.program = prog; if (!renderer->shaders.quad.program) { @@ -142,7 +161,17 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) { renderer->shaders.quad.color = glGetUniformLocation(prog, "color"); renderer->shaders.quad.pos_attrib = glGetAttribLocation(prog, "pos"); - // Border corners + // rounded quad fragment shaders + prog = link_program(quad_vert_src, quad_round_tl_frag_src); + if (!init_rounded_quad_shader(&renderer->shaders.rounded_tl_quad, prog)) { + goto error; + } + prog = link_program(quad_vert_src, quad_round_tr_frag_src); + if (!init_rounded_quad_shader(&renderer->shaders.rounded_tr_quad, prog)) { + goto error; + } + + // Border corner shader prog = link_program(quad_vert_src, corner_frag_src); renderer->shaders.corner.program = prog; if (!renderer->shaders.corner.program) { @@ -225,7 +254,7 @@ void fx_renderer_scissor(struct wlr_box *box) { bool fx_render_subtexture_with_matrix(struct fx_renderer *renderer, struct wlr_texture *wlr_texture, const struct wlr_fbox *src_box, const struct wlr_box *dst_box, const float matrix[static 9], - float alpha, int radius) { + float alpha, int radius, const bool has_titlebar) { assert(wlr_texture_is_gles2(wlr_texture)); struct wlr_gles2_texture_attribs texture_attrs; @@ -282,6 +311,7 @@ bool fx_render_subtexture_with_matrix(struct fx_renderer *renderer, struct wlr_t glUniformMatrix3fv(shader->proj, 1, GL_FALSE, gl_matrix); glUniform1i(shader->tex, 0); glUniform1f(shader->alpha, alpha); + glUniform1f(shader->has_titlebar, has_titlebar); // rounded corners glUniform2f(shader->size, dst_box->width, dst_box->height); @@ -316,14 +346,15 @@ bool fx_render_subtexture_with_matrix(struct fx_renderer *renderer, struct wlr_t } bool fx_render_texture_with_matrix(struct fx_renderer *renderer, struct wlr_texture *wlr_texture, - const struct wlr_box *dst_box, const float matrix[static 9], float alpha, int radius) { + const struct wlr_box *dst_box, const float matrix[static 9], float alpha, int radius, + const bool has_titlebar) { struct wlr_fbox src_box = { .x = 0, .y = 0, .width = wlr_texture->width, .height = wlr_texture->height, }; - return fx_render_subtexture_with_matrix(renderer, wlr_texture, &src_box, dst_box, matrix, alpha, radius); + return fx_render_subtexture_with_matrix(renderer, wlr_texture, &src_box, dst_box, matrix, alpha, radius, has_titlebar); } void fx_render_rect(struct fx_renderer *renderer, const struct wlr_box *box, @@ -364,6 +395,61 @@ void fx_render_rect(struct fx_renderer *renderer, const struct wlr_box *box, glDisableVertexAttribArray(renderer->shaders.quad.pos_attrib); } +void fx_render_rounded_rect(struct fx_renderer *renderer, const struct wlr_box *box, + const float color[static 4], const float projection[static 9], + int radius, enum corner_location corner_location) { + if (box->width == 0 || box->height == 0) { + return; + } + assert(box->width > 0 && box->height > 0); + + struct rounded_quad_shader *shader = NULL; + + switch (corner_location) { + case TOP_LEFT: + shader = &renderer->shaders.rounded_tl_quad; + break; + case TOP_RIGHT: + shader = &renderer->shaders.rounded_tr_quad; + break; + default: + sway_log(SWAY_ERROR, "Invalid Corner Location. Aborting render"); + abort(); + } + + float matrix[9]; + wlr_matrix_project_box(matrix, box, WL_OUTPUT_TRANSFORM_NORMAL, 0, projection); + + float gl_matrix[9]; + wlr_matrix_multiply(gl_matrix, renderer->projection, matrix); + + // TODO: investigate why matrix is flipped prior to this cmd + // wlr_matrix_multiply(gl_matrix, flip_180, gl_matrix); + + wlr_matrix_transpose(gl_matrix, gl_matrix); + + glEnable(GL_BLEND); + + glUseProgram(shader->program); + + glUniformMatrix3fv(shader->proj, 1, GL_FALSE, gl_matrix); + glUniform4f(shader->color, color[0], color[1], color[2], color[3]); + + // rounded corners + glUniform2f(shader->size, box->width, box->height); + glUniform2f(shader->position, box->x, box->y); + glUniform1f(shader->radius, radius); + + glVertexAttribPointer(shader->pos_attrib, 2, GL_FLOAT, GL_FALSE, + 0, verts); + + glEnableVertexAttribArray(shader->pos_attrib); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glDisableVertexAttribArray(shader->pos_attrib); +} + void fx_render_border_corner(struct fx_renderer *renderer, const struct wlr_box *box, const float color[static 4], const float projection[static 9], enum corner_location corner_location, int radius, int border_thickness) { |