Fix rendering of semi-transparent bg images in semi-transparent windows

Output colors must be premultiplied
This commit is contained in:
Kovid Goyal 2020-02-02 11:45:48 +05:30
parent 330ed8e4ae
commit 3774cc54c7
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 8 additions and 2 deletions

View File

@ -2,10 +2,14 @@
uniform sampler2D image; uniform sampler2D image;
uniform float opacity; uniform float opacity;
uniform float premult;
in vec2 texcoord; in vec2 texcoord;
out vec4 color; out vec4 color;
void main() { void main() {
color = texture(image, texcoord); color = texture(image, texcoord);
color = vec4(color.rgb, color.a * opacity); float alpha = color.a * opacity;
vec4 premult_color = vec4(color.rgb * alpha, alpha);
color = vec4(color.rgb, alpha);
color = premult * premult_color + (1 - premult) * color;
} }

View File

@ -165,7 +165,7 @@ typedef struct {
static CellProgramLayout cell_program_layouts[NUM_PROGRAMS]; static CellProgramLayout cell_program_layouts[NUM_PROGRAMS];
static ssize_t blit_vertex_array; static ssize_t blit_vertex_array;
typedef struct { typedef struct {
GLint image_location, tiled_location, sizes_location, opacity_location; GLint image_location, tiled_location, sizes_location, opacity_location, premult_location;
} BGImageProgramLayout; } BGImageProgramLayout;
static BGImageProgramLayout bgimage_program_layout = {0}; static BGImageProgramLayout bgimage_program_layout = {0};
typedef struct { typedef struct {
@ -194,6 +194,7 @@ init_cell_program(void) {
bgimage_program_layout.opacity_location = get_uniform_location(BGIMAGE_PROGRAM, "opacity"); bgimage_program_layout.opacity_location = get_uniform_location(BGIMAGE_PROGRAM, "opacity");
bgimage_program_layout.sizes_location = get_uniform_location(BGIMAGE_PROGRAM, "sizes"); bgimage_program_layout.sizes_location = get_uniform_location(BGIMAGE_PROGRAM, "sizes");
bgimage_program_layout.tiled_location = get_uniform_location(BGIMAGE_PROGRAM, "tiled"); bgimage_program_layout.tiled_location = get_uniform_location(BGIMAGE_PROGRAM, "tiled");
bgimage_program_layout.premult_location = get_uniform_location(BGIMAGE_PROGRAM, "premult");
tint_program_layout.tint_color_location = get_uniform_location(TINT_PROGRAM, "tint_color"); tint_program_layout.tint_color_location = get_uniform_location(TINT_PROGRAM, "tint_color");
tint_program_layout.edges_location = get_uniform_location(TINT_PROGRAM, "edges"); tint_program_layout.edges_location = get_uniform_location(TINT_PROGRAM, "edges");
} }
@ -362,6 +363,7 @@ draw_bg(OSWindow *w) {
} }
glUniform4f(bgimage_program_layout.sizes_location, glUniform4f(bgimage_program_layout.sizes_location,
(GLfloat)w->window_width, (GLfloat)w->window_height, (GLfloat)w->bgimage->width, (GLfloat)w->bgimage->height); (GLfloat)w->window_width, (GLfloat)w->window_height, (GLfloat)w->bgimage->width, (GLfloat)w->bgimage->height);
glUniform1f(bgimage_program_layout.premult_location, w->is_semi_transparent ? 1.f : 0.f);
glActiveTexture(GL_TEXTURE0 + BGIMAGE_UNIT); glActiveTexture(GL_TEXTURE0 + BGIMAGE_UNIT);
glBindTexture(GL_TEXTURE_2D, w->bgimage->texture_id); glBindTexture(GL_TEXTURE_2D, w->bgimage->texture_id);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawArrays(GL_TRIANGLE_FAN, 0, 4);