diff --git a/kitty/child-monitor.c b/kitty/child-monitor.c index c389bf47f..4bcf85a6d 100644 --- a/kitty/child-monitor.c +++ b/kitty/child-monitor.c @@ -633,7 +633,7 @@ draw_resizing_text(OSWindow *w) { snprintf(text, sizeof(text), "%u x %u cells", width / w->fonts_data->cell_width, height / w->fonts_data->cell_height); StringCanvas rendered = render_simple_text(w->fonts_data, text); if (rendered.canvas) { - draw_centered_alpha_mask(w->gvao_idx, width, height, rendered.width, rendered.height, rendered.canvas); + draw_centered_alpha_mask(w, width, height, rendered.width, rendered.height, rendered.canvas); free(rendered.canvas); } } diff --git a/kitty/graphics_fragment.glsl b/kitty/graphics_fragment.glsl index 28e05c134..6d2d5c9e3 100644 --- a/kitty/graphics_fragment.glsl +++ b/kitty/graphics_fragment.glsl @@ -4,6 +4,7 @@ uniform sampler2D image; #ifdef ALPHA_MASK uniform uint fg; +uniform float alpha_mask_premult; #else uniform float inactive_text_alpha; #endif @@ -28,6 +29,7 @@ void main() { color = texture(image, texcoord); #ifdef ALPHA_MASK color = vec4(color_to_vec(fg), color.r); + color = mix(color, vec4(color.rgb * color.a, color.a), alpha_mask_premult); #else color.a *= inactive_text_alpha; #ifdef PREMULT diff --git a/kitty/shaders.c b/kitty/shaders.c index bb04716a5..a8c8e7b7e 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -211,7 +211,7 @@ create_graphics_vao() { struct CellUniformData { bool constants_set; bool alpha_mask_fg_set; - GLint gploc, gpploc, cploc, cfploc, fg_loc; + GLint gploc, gpploc, cploc, cfploc, fg_loc, amask_premult_loc; GLfloat prev_inactive_text_alpha; }; @@ -347,7 +347,7 @@ draw_graphics(int program, ssize_t vao_idx, ssize_t gvao_idx, ImageRenderData *d #define BLEND_PREMULT glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // blending of pre-multiplied colors void -draw_centered_alpha_mask(ssize_t gvao_idx, size_t screen_width, size_t screen_height, size_t width, size_t height, uint8_t *canvas) { +draw_centered_alpha_mask(OSWindow *os_window, size_t screen_width, size_t screen_height, size_t width, size_t height, uint8_t *canvas) { static ImageRenderData data = {.group_count=1}; gpu_data_for_centered_image(&data, screen_width, screen_height, width, height); if (!data.texture_id) { glGenTextures(1, &data.texture_id); } @@ -364,11 +364,15 @@ draw_centered_alpha_mask(ssize_t gvao_idx, size_t screen_width, size_t screen_he glUniform1i(glGetUniformLocation(program_id(GRAPHICS_ALPHA_MASK_PROGRAM), "image"), GRAPHICS_UNIT); glUniform1ui(glGetUniformLocation(program_id(GRAPHICS_ALPHA_MASK_PROGRAM), "fg"), OPT(foreground)); } - glScissor(0, 0, screen_width, screen_height); - send_graphics_data_to_gpu(1, gvao_idx, &data); + glUniform1f(cell_uniform_data.amask_premult_loc, os_window->is_semi_transparent ? 1.f : 0.f); + send_graphics_data_to_gpu(1, os_window->gvao_idx, &data); glEnable(GL_BLEND); - BLEND_ONTO_OPAQUE; - draw_graphics(GRAPHICS_ALPHA_MASK_PROGRAM, 0, gvao_idx, &data, 0, 1); + if (os_window->is_semi_transparent) { + BLEND_PREMULT; + } else { + BLEND_ONTO_OPAQUE; + } + draw_graphics(GRAPHICS_ALPHA_MASK_PROGRAM, 0, os_window->gvao_idx, &data, 0, 1); glDisable(GL_BLEND); } @@ -459,6 +463,7 @@ set_cell_uniforms(float current_inactive_text_alpha, bool force) { cell_uniform_data.gpploc = glGetUniformLocation(program_id(GRAPHICS_PREMULT_PROGRAM), "inactive_text_alpha"); cell_uniform_data.cploc = glGetUniformLocation(program_id(CELL_PROGRAM), "inactive_text_alpha"); cell_uniform_data.cfploc = glGetUniformLocation(program_id(CELL_FG_PROGRAM), "inactive_text_alpha"); + cell_uniform_data.amask_premult_loc = glGetUniformLocation(program_id(GRAPHICS_ALPHA_MASK_PROGRAM), "alpha_mask_premult"); #define S(prog, name, val, type) { bind_program(prog); glUniform##type(glGetUniformLocation(program_id(prog), #name), val); } S(GRAPHICS_PROGRAM, image, GRAPHICS_UNIT, 1i); S(GRAPHICS_PREMULT_PROGRAM, image, GRAPHICS_UNIT, 1i); diff --git a/kitty/state.h b/kitty/state.h index cfec69314..96b253b27 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -214,7 +214,7 @@ ssize_t create_graphics_vao(void); ssize_t create_border_vao(void); bool send_cell_data_to_gpu(ssize_t, ssize_t, float, float, float, float, Screen *, OSWindow *); void draw_cells(ssize_t, ssize_t, float, float, float, float, Screen *, OSWindow *, bool, bool); -void draw_centered_alpha_mask(ssize_t gvao_idx, size_t screen_width, size_t screen_height, size_t width, size_t height, uint8_t *canvas); +void draw_centered_alpha_mask(OSWindow *w, size_t screen_width, size_t screen_height, size_t width, size_t height, uint8_t *canvas); void update_surface_size(int, int, uint32_t); void free_texture(uint32_t*); void send_image_to_gpu(uint32_t*, const void*, int32_t, int32_t, bool, bool);