mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-28 11:11:47 +02:00
Calculate background image position on the GPU
This commit is contained in:
@@ -8,8 +8,8 @@
|
|||||||
#define tex_right 1
|
#define tex_right 1
|
||||||
#define tex_bottom 1
|
#define tex_bottom 1
|
||||||
|
|
||||||
uniform float unscaled;
|
uniform float rescaled;
|
||||||
uniform vec2 translate; // [ left, top ]
|
uniform vec2 transform; // [ pos_left_relative, pos_top_relative ]
|
||||||
uniform vec4 sizes; // [ window_width, window_height, image_width, image_height ]
|
uniform vec4 sizes; // [ window_width, window_height, image_width, image_height ]
|
||||||
|
|
||||||
out vec2 texcoord;
|
out vec2 texcoord;
|
||||||
@@ -28,12 +28,16 @@ const vec2 tex_map[] = vec2[4](
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
float unscaling_factor(int i) {
|
float scaling_factor(int i) {
|
||||||
return unscaled * (sizes[i] / sizes[i + 2]) + (1 - unscaled);
|
return rescaled * (sizes[i] / sizes[i + 2]) + (1 - rescaled);
|
||||||
|
}
|
||||||
|
|
||||||
|
float position_divisor(int i) {
|
||||||
|
return (sizes[i] - sizes[i + 2]) * transform[i] / sizes[i + 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 tex_coords = tex_map[gl_VertexID];
|
vec2 tex_coords = tex_map[gl_VertexID];
|
||||||
texcoord = vec2(tex_coords[0] * unscaling_factor(0) - translate[0], tex_coords[1] * unscaling_factor(1) - translate[1]);
|
texcoord = vec2(tex_coords[0] * scaling_factor(0) - position_divisor(0), tex_coords[1] * scaling_factor(1) - position_divisor(1));
|
||||||
gl_Position = vec4(pos_map[gl_VertexID], 0, 1);
|
gl_Position = vec4(pos_map[gl_VertexID], 0, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,7 +166,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, unscaled_location, translate_location, sizes_location, opacity_location, premult_location;
|
GLint image_location, rescaled_location, transform_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 {
|
||||||
@@ -198,8 +198,8 @@ init_cell_program(void) {
|
|||||||
bgimage_program_layout.image_location = get_uniform_location(BGIMAGE_PROGRAM, "image");
|
bgimage_program_layout.image_location = get_uniform_location(BGIMAGE_PROGRAM, "image");
|
||||||
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.unscaled_location = get_uniform_location(BGIMAGE_PROGRAM, "unscaled");
|
bgimage_program_layout.rescaled_location = get_uniform_location(BGIMAGE_PROGRAM, "rescaled");
|
||||||
bgimage_program_layout.translate_location = get_uniform_location(BGIMAGE_PROGRAM, "translate");
|
bgimage_program_layout.transform_location = get_uniform_location(BGIMAGE_PROGRAM, "transform");
|
||||||
bgimage_program_layout.premult_location = get_uniform_location(BGIMAGE_PROGRAM, "premult");
|
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");
|
||||||
@@ -408,28 +408,28 @@ draw_bg(OSWindow *w) {
|
|||||||
bind_program(BGIMAGE_PROGRAM);
|
bind_program(BGIMAGE_PROGRAM);
|
||||||
bind_vertex_array(blit_vertex_array);
|
bind_vertex_array(blit_vertex_array);
|
||||||
|
|
||||||
const bool unscaled = OPT(background_image_layout) == TILING || OPT(background_image_layout) == MIRRORED || OPT(background_image_layout) == CLAMPED;
|
const bool rescaled = OPT(background_image_layout) == TILING || OPT(background_image_layout) == MIRRORED || OPT(background_image_layout) == CLAMPED;
|
||||||
static bool bgimage_constants_set = false;
|
static bool bgimage_constants_set = false;
|
||||||
if (!bgimage_constants_set) {
|
if (!bgimage_constants_set) {
|
||||||
glUniform1i(bgimage_program_layout.image_location, BGIMAGE_UNIT);
|
glUniform1i(bgimage_program_layout.image_location, BGIMAGE_UNIT);
|
||||||
glUniform1f(bgimage_program_layout.opacity_location, OPT(background_opacity));
|
glUniform1f(bgimage_program_layout.opacity_location, OPT(background_opacity));
|
||||||
glUniform1f(bgimage_program_layout.unscaled_location, (GLfloat)unscaled);
|
glUniform1f(bgimage_program_layout.rescaled_location, (GLfloat)rescaled);
|
||||||
bgimage_constants_set = true;
|
bgimage_constants_set = true;
|
||||||
}
|
}
|
||||||
float translate_left = 0.0f, translate_top = 0.0f;
|
float pos_left_relative = 0.0f, pos_top_relative = 0.0f;
|
||||||
if (unscaled) {
|
if (rescaled) {
|
||||||
if (OPT(background_image_anchor) == TOP || OPT(background_image_anchor) == CENTER || OPT(background_image_anchor) == BOTTOM) {
|
if (OPT(background_image_anchor) == TOP || OPT(background_image_anchor) == CENTER || OPT(background_image_anchor) == BOTTOM) {
|
||||||
translate_left = ((float)w->window_width / 2.0f - (float)w->bgimage->width / 2.0f) / (float)w->bgimage->width;
|
pos_left_relative = 0.5f;
|
||||||
} else if (OPT(background_image_anchor) == TOP_RIGHT || OPT(background_image_anchor) == RIGHT || OPT(background_image_anchor) == BOTTOM_RIGHT) {
|
} else if (OPT(background_image_anchor) == TOP_RIGHT || OPT(background_image_anchor) == RIGHT || OPT(background_image_anchor) == BOTTOM_RIGHT) {
|
||||||
translate_left = ((float)w->window_width - (float)w->bgimage->width) / (float)w->bgimage->width;
|
pos_left_relative = 1.0f;
|
||||||
}
|
}
|
||||||
if (OPT(background_image_anchor) == LEFT || OPT(background_image_anchor) == CENTER || OPT(background_image_anchor) == RIGHT) {
|
if (OPT(background_image_anchor) == LEFT || OPT(background_image_anchor) == CENTER || OPT(background_image_anchor) == RIGHT) {
|
||||||
translate_top = ((float)w->window_height / 2.0f - (float)w->bgimage->height / 2.0f) / (float)w->bgimage->height;
|
pos_top_relative = 0.5f;
|
||||||
} else if (OPT(background_image_anchor) == BOTTOM_LEFT || OPT(background_image_anchor) == BOTTOM || OPT(background_image_anchor) == BOTTOM_RIGHT) {
|
} else if (OPT(background_image_anchor) == BOTTOM_LEFT || OPT(background_image_anchor) == BOTTOM || OPT(background_image_anchor) == BOTTOM_RIGHT) {
|
||||||
translate_top = ((float)w->window_height - (float)w->bgimage->height) / (float)w->bgimage->height;
|
pos_top_relative = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glUniform2f(bgimage_program_layout.translate_location, (GLfloat)translate_left, (GLfloat)translate_top);
|
glUniform2f(bgimage_program_layout.transform_location, (GLfloat)pos_left_relative, (GLfloat)pos_top_relative);
|
||||||
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);
|
glUniform1f(bgimage_program_layout.premult_location, w->is_semi_transparent ? 1.f : 0.f);
|
||||||
|
|||||||
Reference in New Issue
Block a user