diff --git a/kitty/graphics_vertex.glsl b/kitty/graphics_vertex.glsl index d6ed0a6ab..d1abf1396 100644 --- a/kitty/graphics_vertex.glsl +++ b/kitty/graphics_vertex.glsl @@ -4,16 +4,18 @@ layout(location=0) in vec4 src; layout(location=1) in vec4 position; out vec2 texcoord; +const uint LEFT = uint(0), TOP = uint(1), RIGHT = uint(2), BOTTOM = uint(3); + const uvec2 pos_map[] = uvec2[4]( - uvec2(1, 0), // right, top - uvec2(1, 1), // right, bottom - uvec2(0, 1), // left, bottom - uvec2(0, 0) // left, top + uvec2(RIGHT, TOP), + uvec2(RIGHT, BOTTOM), + uvec2(LEFT, BOTTOM), + uvec2(LEFT, TOP) ); void main() { uvec2 pos = pos_map[gl_VertexID]; - gl_Position = vec4(position[pos.x], position[pos.y + uint(2)], 0, 1); - texcoord = vec2(src[pos.x], src[pos.y + uint(2)]); + gl_Position = vec4(position[pos.x], position[pos.y], 0, 1); + texcoord = vec2(src[pos.x], src[pos.y]); } diff --git a/kitty/shaders.c b/kitty/shaders.c index f50a2075e..980ce040a 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -8,6 +8,8 @@ #include "gl.h" enum { CELL_PROGRAM, CELL_BACKGROUND_PROGRAM, CELL_SPECIAL_PROGRAM, CELL_FOREGROUND_PROGRAM, CURSOR_PROGRAM, BORDERS_PROGRAM, GRAPHICS_PROGRAM, NUM_PROGRAMS }; +enum {SPRITE_MAP_UNIT, GRAPHICS_UNIT}; + // Sprites {{{ typedef struct { @@ -89,8 +91,6 @@ render_cell(PyObject *text, bool bold, bool italic, unsigned int underline, bool #undef B } -enum {SPRITE_MAP_UNIT}; - static inline void ensure_sprite_map() { static GLuint bound_texture_id = 0; @@ -303,6 +303,27 @@ cell_prepare_to_render(ssize_t vao_idx, Screen *screen, GLfloat xstart, GLfloat bind_vertex_array(vao_idx); } +static void +draw_graphics(ImageRenderData *data, GLuint start, GLuint count) { + bind_program(GRAPHICS_PROGRAM); + static bool graphics_constants_set = false; + if (!graphics_constants_set) { + glUniform1i(glGetUniformLocation(program_id(GRAPHICS_PROGRAM), "image"), GRAPHICS_UNIT); check_gl(); + graphics_constants_set = true; + } + glActiveTexture(GL_TEXTURE0 + GRAPHICS_UNIT); check_gl(); + + GLuint base = start; + for (GLuint i=0; i < count;) { + ImageRenderData *rd = data + start + i; + glBindTexture(GL_TEXTURE_2D, rd->texture_id); check_gl(); + glDrawArraysInstancedBaseInstance(GL_TRIANGLE_FAN, 0, 4, rd->group_count, base); + base += rd->group_count; + i += rd->group_count; + } + +} + static void draw_all_cells(Screen *screen) { bind_program(CELL_PROGRAM); @@ -312,22 +333,29 @@ draw_all_cells(Screen *screen) { cell_constants_set = true; } glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns); check_gl(); + if (screen->grman->count) draw_graphics(screen->grman->render_data, 0, screen->grman->count); } static void draw_cells_interleaved(Screen *screen) { bind_program(CELL_BACKGROUND_PROGRAM); glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns); check_gl(); + + draw_graphics(screen->grman->render_data, 0, screen->grman->num_of_negative_refs); + bind_program(CELL_SPECIAL_PROGRAM); glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns); check_gl(); + bind_program(CELL_FOREGROUND_PROGRAM); glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns); check_gl(); + + if (screen->grman->num_of_positive_refs) draw_graphics(screen->grman->render_data, screen->grman->num_of_negative_refs, screen->grman->num_of_positive_refs); } static void draw_cells_impl(ssize_t vao_idx, GLfloat xstart, GLfloat ystart, GLfloat dx, GLfloat dy, Screen *screen, CursorRenderInfo *cursor) { cell_prepare_to_render(vao_idx, screen, xstart, ystart, dx, dy, cursor); - if (false) draw_cells_interleaved(screen); + if (screen->grman->num_of_negative_refs) draw_cells_interleaved(screen); else draw_all_cells(screen); }