summaryrefslogtreecommitdiff
path: root/sway/desktop/fx_renderer.c
diff options
context:
space:
mode:
authorWilliam McKinnon <[email protected]>2022-11-11 01:19:02 -0500
committerGitHub <[email protected]>2022-11-11 01:19:02 -0500
commit1930bd0d7136d84900fe1541e4317cbcd7a85ef6 (patch)
tree0953eb462206e0c52c5206370abfd3b33898e1ac /sway/desktop/fx_renderer.c
parent9ee7fa61af58de3dab3d60e325ef1d0c6f40f9fd (diff)
feat: add round titlebars (#26)
Diffstat (limited to 'sway/desktop/fx_renderer.c')
-rw-r--r--sway/desktop/fx_renderer.c94
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) {