diff --git a/kitty/gl.h b/kitty/gl.h index dedae0d70..2d074ef74 100644 --- a/kitty/gl.h +++ b/kitty/gl.h @@ -338,11 +338,9 @@ add_buffer_to_vao(ssize_t vao_idx, GLenum usage) { } static void -add_attribute_to_vao(int p, ssize_t vao_idx, const char *name, GLint size, GLenum data_type, GLsizei stride, void *offset, GLuint divisor) { +add_located_attribute_to_vao(ssize_t vao_idx, GLint aloc, GLint size, GLenum data_type, GLsizei stride, void *offset, GLuint divisor) { VAO *vao = vaos + vao_idx; - if (!vao->num_buffers) { fatal("You must create a buffer for this attribute first"); return; } - GLint aloc = attrib_location(p, name); - if (aloc == -1) { fatal("No attribute named: %s found in this program", name); return; } + if (!vao->num_buffers) fatal("You must create a buffer for this attribute first"); ssize_t buf = vao->buffers[vao->num_buffers - 1]; bind_buffer(buf); glEnableVertexAttribArray(aloc); @@ -366,7 +364,14 @@ add_attribute_to_vao(int p, ssize_t vao_idx, const char *name, GLint size, GLenu check_gl(); } unbind_buffer(buf); - return; +} + + +static inline void +add_attribute_to_vao(int p, ssize_t vao_idx, const char *name, GLint size, GLenum data_type, GLsizei stride, void *offset, GLuint divisor) { + GLint aloc = attrib_location(p, name); + if (aloc == -1) fatal("No attribute named: %s found in this program", name); + add_located_attribute_to_vao(vao_idx, aloc, size, data_type, stride, offset, divisor); } static void diff --git a/kitty/graphics_fragment.glsl b/kitty/graphics_fragment.glsl new file mode 100644 index 000000000..d556e802e --- /dev/null +++ b/kitty/graphics_fragment.glsl @@ -0,0 +1,10 @@ +#version 330 + +uniform sampler2D image; + +in vec2 texcoord; +out vec4 color; + +void main() { + color = texture2D(image, texcoord); +} diff --git a/kitty/graphics_vertex.glsl b/kitty/graphics_vertex.glsl new file mode 100644 index 000000000..aebe20810 --- /dev/null +++ b/kitty/graphics_vertex.glsl @@ -0,0 +1,19 @@ +#version 330 + +layout(location=8) in vec4 src; +layout(location=9) in vec4 position; +out vec2 texcoord; + +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 +); + + +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)]); +} diff --git a/kitty/shaders.c b/kitty/shaders.c index 1582a3c8f..c04c0f4b3 100644 --- a/kitty/shaders.c +++ b/kitty/shaders.c @@ -7,7 +7,7 @@ #include "gl.h" -enum { CELL_PROGRAM, CELL_BACKGROUND_PROGRAM, CELL_SPECIAL_PROGRAM, CELL_FOREGROUND_PROGRAM, CURSOR_PROGRAM, BORDERS_PROGRAM, NUM_PROGRAMS }; +enum { CELL_PROGRAM, CELL_BACKGROUND_PROGRAM, CELL_SPECIAL_PROGRAM, CELL_FOREGROUND_PROGRAM, CURSOR_PROGRAM, BORDERS_PROGRAM, GRAPHICS_PROGRAM, NUM_PROGRAMS }; // Sprites {{{ typedef struct { @@ -175,8 +175,6 @@ destroy_sprite_map() { // Cell {{{ -#define CELL_BUFFERS enum { cell_data_buffer, selection_buffer, uniform_buffer }; - typedef struct { UniformBlock render_data; ArrayInformation color_table; @@ -195,6 +193,8 @@ init_cell_program() { } } +#define CELL_BUFFERS enum { cell_data_buffer, selection_buffer, uniform_buffer, graphics_buffer }; + static ssize_t create_cell_vao() { ssize_t vao_idx = create_vao(); @@ -202,17 +202,26 @@ create_cell_vao() { add_attribute_to_vao(CELL_PROGRAM, vao_idx, #name, \ /*size=*/size, /*dtype=*/dtype, /*stride=*/stride, /*offset=*/offset, /*divisor=*/1); #define A1(name, size, dtype, offset) A(name, size, dtype, (void*)(offsetof(Cell, offset)), sizeof(Cell)) +#define AL(p, name, size, dtype, offset, stride) { GLint aloc = attrib_location(p, name); if (aloc == -1 ) fatal("No attribute named: %s found in this program", name); add_located_attribute_to_vao(vao_idx, aloc, size, dtype, stride, (void*)offset, 1); } add_buffer_to_vao(vao_idx, GL_ARRAY_BUFFER); A1(sprite_coords, 4, GL_UNSIGNED_SHORT, sprite_x); A1(colors, 3, GL_UNSIGNED_INT, fg); + add_buffer_to_vao(vao_idx, GL_ARRAY_BUFFER); A(is_selected, 1, GL_FLOAT, NULL, 0); + size_t bufnum = add_buffer_to_vao(vao_idx, GL_UNIFORM_BUFFER); alloc_vao_buffer(vao_idx, cell_program_layouts[CELL_PROGRAM].render_data.size, bufnum, GL_STREAM_DRAW); + + add_buffer_to_vao(vao_idx, GL_ARRAY_BUFFER); + AL(GRAPHICS_PROGRAM, "src", 4, GL_FLOAT, 0, sizeof(ImageRenderData)); + AL(GRAPHICS_PROGRAM, "position", 4, GL_FLOAT, offsetof(ImageRenderData, dest_rect), sizeof(ImageRenderData)); + return vao_idx; #undef A #undef A1 +#undef AL } static inline void @@ -560,7 +569,7 @@ init_shaders_debug(PyObject *module) { init_shaders(PyObject *module) { #endif #define C(x) if (PyModule_AddIntConstant(module, #x, x) != 0) { PyErr_NoMemory(); return false; } - C(CELL_PROGRAM); C(CELL_BACKGROUND_PROGRAM); C(CELL_SPECIAL_PROGRAM); C(CELL_FOREGROUND_PROGRAM); C(CURSOR_PROGRAM); C(BORDERS_PROGRAM); + C(CELL_PROGRAM); C(CELL_BACKGROUND_PROGRAM); C(CELL_SPECIAL_PROGRAM); C(CELL_FOREGROUND_PROGRAM); C(CURSOR_PROGRAM); C(BORDERS_PROGRAM); C(GRAPHICS_PROGRAM); C(GLSL_VERSION); C(GL_VERSION); C(GL_VENDOR); diff --git a/kitty/window.py b/kitty/window.py index a6280ae9e..fa1f1222d 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -16,9 +16,9 @@ from .constants import ( from .fast_data_types import ( BRACKETED_PASTE_END, BRACKETED_PASTE_START, CELL_BACKGROUND_PROGRAM, CELL_FOREGROUND_PROGRAM, CELL_PROGRAM, CELL_SPECIAL_PROGRAM, - CURSOR_PROGRAM, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, Screen, - compile_program, create_cell_vao, glfw_post_empty_event, init_cell_program, - init_cursor_program, remove_vao, set_window_render_data, + CURSOR_PROGRAM, GRAPHICS_PROGRAM, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, + Screen, compile_program, create_cell_vao, glfw_post_empty_event, + init_cell_program, init_cursor_program, remove_vao, set_window_render_data, update_window_title, update_window_visibility ) from .rgb import to_color @@ -62,6 +62,7 @@ def load_shader_programs(): init_cell_program() compile_program(CURSOR_PROGRAM, *load_shaders('cursor')) init_cursor_program() + compile_program(GRAPHICS_PROGRAM, *load_shaders('graphics')) class Window: