Move the GLSL shaders into their own files
This commit is contained in:
parent
21874339f1
commit
fe3e51a00d
@ -26,7 +26,7 @@ from .fast_data_types import (
|
|||||||
)
|
)
|
||||||
from .fonts.render import set_font_family
|
from .fonts.render import set_font_family
|
||||||
from .borders import BordersProgram
|
from .borders import BordersProgram
|
||||||
from .char_grid import cursor_shader, cell_shader
|
from .char_grid import load_shader_programs
|
||||||
from .constants import is_key_pressed
|
from .constants import is_key_pressed
|
||||||
from .keys import interpret_text_event, interpret_key_event, get_shortcut, get_sent_data
|
from .keys import interpret_text_event, interpret_key_event, get_shortcut, get_sent_data
|
||||||
from .session import create_session
|
from .session import create_session
|
||||||
@ -100,6 +100,7 @@ class Boss(Thread):
|
|||||||
glfw_window.window_focus_callback = self.on_focus
|
glfw_window.window_focus_callback = self.on_focus
|
||||||
self.tab_manager = TabManager(opts, args, startup_session)
|
self.tab_manager = TabManager(opts, args, startup_session)
|
||||||
self.sprites = Sprites()
|
self.sprites = Sprites()
|
||||||
|
cell_shader, cursor_shader = load_shader_programs()
|
||||||
self.cell_program = ShaderProgram(*cell_shader)
|
self.cell_program = ShaderProgram(*cell_shader)
|
||||||
self.cursor_program = ShaderProgram(*cursor_shader)
|
self.cursor_program = ShaderProgram(*cursor_shader)
|
||||||
self.borders_program = BordersProgram()
|
self.borders_program = BordersProgram()
|
||||||
|
|||||||
26
kitty/cell_fragment.glsl
Normal file
26
kitty/cell_fragment.glsl
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
uniform sampler2DArray sprites;
|
||||||
|
in vec3 sprite_pos;
|
||||||
|
in vec3 underline_pos;
|
||||||
|
in vec3 strike_pos;
|
||||||
|
in vec3 foreground;
|
||||||
|
in vec3 background;
|
||||||
|
in vec3 decoration_fg;
|
||||||
|
out vec4 final_color;
|
||||||
|
|
||||||
|
vec3 blend(float alpha, vec3 over, vec3 under) {
|
||||||
|
return over + (1 - alpha) * under;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float text_alpha = texture(sprites, sprite_pos).r;
|
||||||
|
float underline_alpha = texture(sprites, underline_pos).r;
|
||||||
|
float strike_alpha = texture(sprites, strike_pos).r;
|
||||||
|
vec3 underline = underline_alpha * decoration_fg;
|
||||||
|
vec3 strike = strike_alpha * foreground;
|
||||||
|
vec3 fg = text_alpha * foreground;
|
||||||
|
vec3 decoration = blend(underline_alpha, underline, strike);
|
||||||
|
vec3 combined_fg = blend(text_alpha, fg, decoration);
|
||||||
|
float combined_alpha = max(max(underline_alpha, strike_alpha), text_alpha);
|
||||||
|
final_color = vec4(blend(combined_alpha, combined_fg, background), 1);
|
||||||
|
}
|
||||||
|
|
||||||
63
kitty/cell_vertex.glsl
Normal file
63
kitty/cell_vertex.glsl
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
uniform uvec2 dimensions; // xnum, ynum
|
||||||
|
uniform vec4 steps; // xstart, ystart, dx, dy
|
||||||
|
uniform vec2 sprite_layout; // dx, dy
|
||||||
|
uniform usamplerBuffer sprite_map; // gl_InstanceID -> x, y, z
|
||||||
|
uniform ivec2 color_indices; // which color to use as fg and which as bg
|
||||||
|
out vec3 sprite_pos;
|
||||||
|
out vec3 underline_pos;
|
||||||
|
out vec3 strike_pos;
|
||||||
|
out vec3 foreground;
|
||||||
|
out vec3 background;
|
||||||
|
out vec3 decoration_fg;
|
||||||
|
|
||||||
|
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
|
||||||
|
);
|
||||||
|
|
||||||
|
const uint BYTE_MASK = uint(255);
|
||||||
|
const uint ZERO = uint(0);
|
||||||
|
const uint SMASK = uint(3);
|
||||||
|
|
||||||
|
vec3 to_color(uint c) {
|
||||||
|
uint r, g, b;
|
||||||
|
r = (c >> 16) & BYTE_MASK;
|
||||||
|
g = (c >> 8) & BYTE_MASK;
|
||||||
|
b = c & BYTE_MASK;
|
||||||
|
return vec3(float(r) / 255.0, float(g) / 255.0, float(b) / 255.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 to_sprite_pos(uvec2 pos, uint x, uint y, uint z) {
|
||||||
|
vec2 s_xpos = vec2(x, float(x) + 1.0) * sprite_layout[0];
|
||||||
|
vec2 s_ypos = vec2(y, float(y) + 1.0) * sprite_layout[1];
|
||||||
|
return vec3(s_xpos[pos[0]], s_ypos[pos[1]], z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
uint instance_id = uint(gl_InstanceID);
|
||||||
|
uint r = instance_id / dimensions[0];
|
||||||
|
uint c = instance_id - r * dimensions[0];
|
||||||
|
float left = steps[0] + c * steps[2];
|
||||||
|
float top = steps[1] - r * steps[3];
|
||||||
|
vec2 xpos = vec2(left, left + steps[2]);
|
||||||
|
vec2 ypos = vec2(top, top - steps[3]);
|
||||||
|
uvec2 pos = pos_map[gl_VertexID];
|
||||||
|
gl_Position = vec4(xpos[pos[0]], ypos[pos[1]], 0, 1);
|
||||||
|
|
||||||
|
int sprite_id = gl_InstanceID * STRIDE;
|
||||||
|
uint x = texelFetch(sprite_map, sprite_id).r;
|
||||||
|
uint y = texelFetch(sprite_map, sprite_id + 1).r;
|
||||||
|
uint z = texelFetch(sprite_map, sprite_id + 2).r;
|
||||||
|
sprite_pos = to_sprite_pos(pos, x, y, z);
|
||||||
|
sprite_id += 3;
|
||||||
|
uint fg = texelFetch(sprite_map, sprite_id + color_indices[0]).r;
|
||||||
|
uint bg = texelFetch(sprite_map, sprite_id + color_indices[1]).r;
|
||||||
|
uint decoration = texelFetch(sprite_map, sprite_id + 2).r;
|
||||||
|
foreground = to_color(fg);
|
||||||
|
background = to_color(bg);
|
||||||
|
decoration_fg = to_color(decoration);
|
||||||
|
underline_pos = to_sprite_pos(pos, (decoration >> 24) & SMASK, ZERO, ZERO);
|
||||||
|
strike_pos = to_sprite_pos(pos, (decoration >> 26) & SMASK, ZERO, ZERO);
|
||||||
|
}
|
||||||
@ -20,6 +20,7 @@ from .fast_data_types import (
|
|||||||
glUniform4f, glUniform2i
|
glUniform4f, glUniform2i
|
||||||
)
|
)
|
||||||
from .rgb import to_color
|
from .rgb import to_color
|
||||||
|
from .shaders import load_shaders
|
||||||
from .utils import (
|
from .utils import (
|
||||||
color_as_int, color_from_int, get_logical_dpi, open_url, safe_print,
|
color_as_int, color_from_int, get_logical_dpi, open_url, safe_print,
|
||||||
set_primary_selection
|
set_primary_selection
|
||||||
@ -32,137 +33,12 @@ class DynamicColor(Enum):
|
|||||||
default_fg, default_bg, cursor_color, highlight_fg, highlight_bg = range(1, 6)
|
default_fg, default_bg, cursor_color, highlight_fg, highlight_bg = range(1, 6)
|
||||||
|
|
||||||
|
|
||||||
if DATA_CELL_SIZE % 3:
|
def load_shader_programs():
|
||||||
raise ValueError('Incorrect data cell size, must be a multiple of 3')
|
vert, frag = load_shaders('cell')
|
||||||
|
vert = vert.replace('STRIDE', str(DATA_CELL_SIZE))
|
||||||
|
cell = vert, frag
|
||||||
# cell shader {{{
|
cursor = load_shaders('cursor')
|
||||||
|
return cell, cursor
|
||||||
cell_shader = (
|
|
||||||
'''\
|
|
||||||
uniform uvec2 dimensions; // xnum, ynum
|
|
||||||
uniform vec4 steps; // xstart, ystart, dx, dy
|
|
||||||
uniform vec2 sprite_layout; // dx, dy
|
|
||||||
uniform usamplerBuffer sprite_map; // gl_InstanceID -> x, y, z
|
|
||||||
uniform ivec2 color_indices; // which color to use as fg and which as bg
|
|
||||||
out vec3 sprite_pos;
|
|
||||||
out vec3 underline_pos;
|
|
||||||
out vec3 strike_pos;
|
|
||||||
out vec3 foreground;
|
|
||||||
out vec3 background;
|
|
||||||
out vec3 decoration_fg;
|
|
||||||
|
|
||||||
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
|
|
||||||
);
|
|
||||||
|
|
||||||
const uint BYTE_MASK = uint(255);
|
|
||||||
const uint ZERO = uint(0);
|
|
||||||
const uint SMASK = uint(3);
|
|
||||||
|
|
||||||
vec3 to_color(uint c) {
|
|
||||||
uint r, g, b;
|
|
||||||
r = (c >> 16) & BYTE_MASK;
|
|
||||||
g = (c >> 8) & BYTE_MASK;
|
|
||||||
b = c & BYTE_MASK;
|
|
||||||
return vec3(float(r) / 255.0, float(g) / 255.0, float(b) / 255.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 to_sprite_pos(uvec2 pos, uint x, uint y, uint z) {
|
|
||||||
vec2 s_xpos = vec2(x, float(x) + 1.0) * sprite_layout[0];
|
|
||||||
vec2 s_ypos = vec2(y, float(y) + 1.0) * sprite_layout[1];
|
|
||||||
return vec3(s_xpos[pos[0]], s_ypos[pos[1]], z);
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
uint instance_id = uint(gl_InstanceID);
|
|
||||||
uint r = instance_id / dimensions[0];
|
|
||||||
uint c = instance_id - r * dimensions[0];
|
|
||||||
float left = steps[0] + c * steps[2];
|
|
||||||
float top = steps[1] - r * steps[3];
|
|
||||||
vec2 xpos = vec2(left, left + steps[2]);
|
|
||||||
vec2 ypos = vec2(top, top - steps[3]);
|
|
||||||
uvec2 pos = pos_map[gl_VertexID];
|
|
||||||
gl_Position = vec4(xpos[pos[0]], ypos[pos[1]], 0, 1);
|
|
||||||
|
|
||||||
int sprite_id = gl_InstanceID * STRIDE;
|
|
||||||
uint x = texelFetch(sprite_map, sprite_id).r;
|
|
||||||
uint y = texelFetch(sprite_map, sprite_id + 1).r;
|
|
||||||
uint z = texelFetch(sprite_map, sprite_id + 2).r;
|
|
||||||
sprite_pos = to_sprite_pos(pos, x, y, z);
|
|
||||||
sprite_id += 3;
|
|
||||||
uint fg = texelFetch(sprite_map, sprite_id + color_indices[0]).r;
|
|
||||||
uint bg = texelFetch(sprite_map, sprite_id + color_indices[1]).r;
|
|
||||||
uint decoration = texelFetch(sprite_map, sprite_id + 2).r;
|
|
||||||
foreground = to_color(fg);
|
|
||||||
background = to_color(bg);
|
|
||||||
decoration_fg = to_color(decoration);
|
|
||||||
underline_pos = to_sprite_pos(pos, (decoration >> 24) & SMASK, ZERO, ZERO);
|
|
||||||
strike_pos = to_sprite_pos(pos, (decoration >> 26) & SMASK, ZERO, ZERO);
|
|
||||||
}
|
|
||||||
'''.replace('STRIDE', str(DATA_CELL_SIZE)),
|
|
||||||
|
|
||||||
'''\
|
|
||||||
uniform sampler2DArray sprites;
|
|
||||||
in vec3 sprite_pos;
|
|
||||||
in vec3 underline_pos;
|
|
||||||
in vec3 strike_pos;
|
|
||||||
in vec3 foreground;
|
|
||||||
in vec3 background;
|
|
||||||
in vec3 decoration_fg;
|
|
||||||
out vec4 final_color;
|
|
||||||
|
|
||||||
vec3 blend(float alpha, vec3 over, vec3 under) {
|
|
||||||
return over + (1 - alpha) * under;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
float text_alpha = texture(sprites, sprite_pos).r;
|
|
||||||
float underline_alpha = texture(sprites, underline_pos).r;
|
|
||||||
float strike_alpha = texture(sprites, strike_pos).r;
|
|
||||||
vec3 underline = underline_alpha * decoration_fg;
|
|
||||||
vec3 strike = strike_alpha * foreground;
|
|
||||||
vec3 fg = text_alpha * foreground;
|
|
||||||
vec3 decoration = blend(underline_alpha, underline, strike);
|
|
||||||
vec3 combined_fg = blend(text_alpha, fg, decoration);
|
|
||||||
float combined_alpha = max(max(underline_alpha, strike_alpha), text_alpha);
|
|
||||||
final_color = vec4(blend(combined_alpha, combined_fg, background), 1);
|
|
||||||
}
|
|
||||||
''')
|
|
||||||
# }}}
|
|
||||||
|
|
||||||
# cursor shader {{{
|
|
||||||
|
|
||||||
cursor_shader = (
|
|
||||||
'''\
|
|
||||||
uniform vec2 xpos;
|
|
||||||
uniform vec2 ypos;
|
|
||||||
|
|
||||||
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(xpos[pos[0]], ypos[pos[1]], 0, 1);
|
|
||||||
}
|
|
||||||
''',
|
|
||||||
|
|
||||||
'''\
|
|
||||||
uniform vec4 color;
|
|
||||||
out vec4 final_color;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
final_color = color;
|
|
||||||
}
|
|
||||||
''')
|
|
||||||
# }}}
|
|
||||||
|
|
||||||
|
|
||||||
class Selection: # {{{
|
class Selection: # {{{
|
||||||
|
|||||||
6
kitty/cursor_fragment.glsl
Normal file
6
kitty/cursor_fragment.glsl
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
uniform vec4 color;
|
||||||
|
out vec4 final_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
final_color = color;
|
||||||
|
}
|
||||||
16
kitty/cursor_vertex.glsl
Normal file
16
kitty/cursor_vertex.glsl
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
uniform vec2 xpos;
|
||||||
|
uniform vec2 ypos;
|
||||||
|
|
||||||
|
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(xpos[pos[0]], ypos[pos[1]], 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2,6 +2,7 @@
|
|||||||
# vim:fileencoding=utf-8
|
# vim:fileencoding=utf-8
|
||||||
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
from ctypes import addressof, sizeof
|
from ctypes import addressof, sizeof
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
@ -33,6 +34,14 @@ GL_VERSION = (3, 3)
|
|||||||
VERSION = GL_VERSION[0] * 100 + GL_VERSION[1] * 10
|
VERSION = GL_VERSION[0] * 100 + GL_VERSION[1] * 10
|
||||||
ITALIC_MASK = 1 << ITALIC
|
ITALIC_MASK = 1 << ITALIC
|
||||||
BOLD_MASK = 1 << BOLD
|
BOLD_MASK = 1 << BOLD
|
||||||
|
BASE = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache()
|
||||||
|
def load_shaders(name):
|
||||||
|
vert = open(os.path.join(BASE, '{}_vertex.glsl'.format(name))).read()
|
||||||
|
frag = open(os.path.join(BASE, '{}_fragment.glsl'.format(name))).read()
|
||||||
|
return vert, frag
|
||||||
|
|
||||||
|
|
||||||
class Sprites:
|
class Sprites:
|
||||||
|
|||||||
2
setup.py
2
setup.py
@ -319,7 +319,7 @@ def package(args, for_bundle=False): # {{{
|
|||||||
def src_ignore(parent, entries):
|
def src_ignore(parent, entries):
|
||||||
return [
|
return [
|
||||||
x for x in entries
|
x for x in entries
|
||||||
if '.' in x and x.rpartition('.')[2] not in ('py', 'so', 'conf')
|
if '.' in x and x.rpartition('.')[2] not in ('py', 'so', 'conf', 'glsl')
|
||||||
]
|
]
|
||||||
|
|
||||||
shutil.copytree('kitty', os.path.join(libdir, 'kitty'), ignore=src_ignore)
|
shutil.copytree('kitty', os.path.join(libdir, 'kitty'), ignore=src_ignore)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user