Prepare for two stage rendering of cells

This commit is contained in:
Kovid Goyal 2017-10-04 14:15:51 +05:30
parent b032130a20
commit ead73c8209
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 45 additions and 19 deletions

View File

@ -1,11 +1,15 @@
#version GLSL_VERSION #version GLSL_VERSION
#define WHICH_PROGRAM
#if defined(FOREGROUND) || defined(ALL)
uniform sampler2DArray sprites; uniform sampler2DArray sprites;
in vec3 sprite_pos; in vec3 sprite_pos;
in vec3 underline_pos; in vec3 underline_pos;
in vec3 strike_pos; in vec3 strike_pos;
in vec3 foreground; in vec3 foreground;
in vec3 background;
in vec3 decoration_fg; in vec3 decoration_fg;
#endif
in vec3 background;
out vec4 final_color; out vec4 final_color;
vec3 blend(float alpha, vec3 over, vec3 under) { vec3 blend(float alpha, vec3 over, vec3 under) {
@ -13,6 +17,7 @@ vec3 blend(float alpha, vec3 over, vec3 under) {
} }
void main() { void main() {
#if defined(FOREGROUND) || defined(ALL)
float text_alpha = texture(sprites, sprite_pos).r; float text_alpha = texture(sprites, sprite_pos).r;
float underline_alpha = texture(sprites, underline_pos).r; float underline_alpha = texture(sprites, underline_pos).r;
float strike_alpha = texture(sprites, strike_pos).r; float strike_alpha = texture(sprites, strike_pos).r;
@ -22,6 +27,13 @@ void main() {
vec3 decoration = blend(underline_alpha, underline, strike); vec3 decoration = blend(underline_alpha, underline, strike);
vec3 combined_fg = blend(text_alpha, fg, decoration); vec3 combined_fg = blend(text_alpha, fg, decoration);
float combined_alpha = max(max(underline_alpha, strike_alpha), text_alpha); float combined_alpha = max(max(underline_alpha, strike_alpha), text_alpha);
#ifdef ALL
final_color = vec4(blend(combined_alpha, combined_fg, background), 1); final_color = vec4(blend(combined_alpha, combined_fg, background), 1);
} #else
final_color = vec4(combined_fg, combined_alpha);
#endif
#else
final_color = vec4(background, 1);
#endif
}

View File

@ -1,4 +1,5 @@
#version GLSL_VERSION #version GLSL_VERSION
#define WHICH_PROGRAM
layout(std140) uniform CellRenderData { layout(std140) uniform CellRenderData {
float xstart, ystart, dx, dy, sprite_dx, sprite_dy; float xstart, ystart, dx, dy, sprite_dx, sprite_dy;
@ -11,16 +12,18 @@ layout(std140) uniform CellRenderData {
uint color_table[256]; uint color_table[256];
}; };
in uvec4 sprite_coords;
in uvec3 colors; in uvec3 colors;
in uvec4 sprite_coords;
#if defined(FOREGROUND) || defined(ALL)
in float is_selected; in float is_selected;
out vec3 sprite_pos; out vec3 sprite_pos;
out vec3 underline_pos; out vec3 underline_pos;
out vec3 strike_pos; out vec3 strike_pos;
out vec3 foreground; out vec3 foreground;
out vec3 background;
out vec3 decoration_fg; out vec3 decoration_fg;
#endif
out vec3 background;
const uvec2 pos_map[] = uvec2[4]( const uvec2 pos_map[] = uvec2[4](
uvec2(1, 0), // right, top uvec2(1, 0), // right, top
@ -89,6 +92,7 @@ float is_cursor(uint x, uint y) {
} }
void main() { void main() {
float cursor;
uint instance_id = uint(gl_InstanceID); uint instance_id = uint(gl_InstanceID);
// The current cell being rendered // The current cell being rendered
uint r = instance_id / xnum; uint r = instance_id / xnum;
@ -100,34 +104,40 @@ void main() {
vec2 xpos = vec2(left, left + dx); vec2 xpos = vec2(left, left + dx);
vec2 ypos = vec2(top, top - dy); vec2 ypos = vec2(top, top - dy);
uvec2 pos = pos_map[gl_VertexID]; uvec2 pos = pos_map[gl_VertexID];
uvec2 default_colors = uvec2(default_fg, default_bg);
ivec2 color_indices = ivec2(color1, color2);
gl_Position = vec4(xpos[pos.x], ypos[pos.y], 0, 1); gl_Position = vec4(xpos[pos.x], ypos[pos.y], 0, 1);
uvec2 default_colors = uvec2(default_fg, default_bg);
ivec2 color_indices = ivec2(color1, color2);
uint text_attrs = sprite_coords[3];
int fg_index = color_indices[(text_attrs >> 6) & REVERSE_MASK];
int bg_index = color_indices[1 - fg_index];
background = to_color(colors[bg_index], default_colors[bg_index]);
#if defined(FOREGROUND) || defined(ALL)
// The character sprite being rendered // The character sprite being rendered
sprite_pos = to_sprite_pos(pos, sprite_coords.x, sprite_coords.y, sprite_coords.z & SHORT_MASK); sprite_pos = to_sprite_pos(pos, sprite_coords.x, sprite_coords.y, sprite_coords.z & SHORT_MASK);
// Foreground and background colors // Foreground and background colors
uint text_attrs = sprite_coords[3];
int fg_index = color_indices[(text_attrs >> 6) & REVERSE_MASK];
int bg_index = color_indices[1 - fg_index];
uint resolved_fg = resolve_color(colors[fg_index], default_colors[fg_index]); uint resolved_fg = resolve_color(colors[fg_index], default_colors[fg_index]);
foreground = color_to_vec(resolved_fg); foreground = color_to_vec(resolved_fg);
background = to_color(colors[bg_index], default_colors[bg_index]);
// Selection // Selection
foreground = choose_color(is_selected, color_to_vec(highlight_fg), foreground); foreground = choose_color(is_selected, color_to_vec(highlight_fg), foreground);
background = choose_color(is_selected, color_to_vec(highlight_bg), background);
// Underline and strike through (rendered via sprites) // Underline and strike through (rendered via sprites)
float in_url = in_range(c, r); float in_url = in_range(c, r);
decoration_fg = choose_color(in_url, color_to_vec(url_color), to_color(colors[2], resolved_fg)); decoration_fg = choose_color(in_url, color_to_vec(url_color), to_color(colors[2], resolved_fg));
underline_pos = choose_color(in_url, to_sprite_pos(pos, TWO, ZERO, ZERO), to_sprite_pos(pos, (text_attrs >> 2) & DECORATION_MASK, ZERO, ZERO)); underline_pos = choose_color(in_url, to_sprite_pos(pos, TWO, ZERO, ZERO), to_sprite_pos(pos, (text_attrs >> 2) & DECORATION_MASK, ZERO, ZERO));
strike_pos = to_sprite_pos(pos, ((text_attrs >> 7) & STRIKE_MASK) * THREE, ZERO, ZERO); strike_pos = to_sprite_pos(pos, ((text_attrs >> 7) & STRIKE_MASK) * THREE, ZERO, ZERO);
// Block cursor rendering // Block cursor rendering
float cursor = is_cursor(c, r); cursor = is_cursor(c, r);
foreground = choose_color(cursor, background, foreground); foreground = choose_color(cursor, background, foreground);
decoration_fg = choose_color(cursor, background, decoration_fg); decoration_fg = choose_color(cursor, background, decoration_fg);
#if defined(SPECIAL) || defined(ALL)
#ifdef SPECIAL
cursor = is_cursor(c, r);
#endif
// Selection and cursor
background = choose_color(is_selected, color_to_vec(highlight_bg), background);
background = choose_color(cursor, color_to_vec(cursor_color), background); background = choose_color(cursor, color_to_vec(cursor_color), background);
#endif
#endif
} }

View File

@ -83,6 +83,7 @@ glew_init(PyObject UNUSED *self) {
#undef ARB_TEST #undef ARB_TEST
#endif #endif
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
@ -113,7 +114,6 @@ send_image_to_gpu_impl(GLuint *tex_id, const void* data, GLsizei width, GLsizei
// }}} // }}}
// Programs {{{ // Programs {{{
enum ProgramNames { CELL_PROGRAM, CURSOR_PROGRAM, BORDERS_PROGRAM, NUM_PROGRAMS };
typedef struct { typedef struct {
GLint size, index; GLint size, index;
@ -135,7 +135,7 @@ typedef struct {
GLint num_of_uniforms; GLint num_of_uniforms;
} Program; } Program;
static Program programs[NUM_PROGRAMS] = {{0}}; static Program programs[64] = {{0}};
static inline GLuint static inline GLuint
compile_shader(GLenum shader_type, const char *source) { compile_shader(GLenum shader_type, const char *source) {

View File

@ -7,6 +7,8 @@
#include "gl.h" #include "gl.h"
enum { CELL_PROGRAM, CURSOR_PROGRAM, BORDERS_PROGRAM, NUM_PROGRAMS };
// Sprites {{{ // Sprites {{{
typedef struct { typedef struct {
int xnum, ynum, x, y, z, last_num_of_layers, last_ynum; int xnum, ynum, x, y, z, last_num_of_layers, last_ynum;
@ -393,7 +395,7 @@ compile_program(PyObject UNUSED *self, PyObject *args) {
int which; int which;
GLuint vertex_shader_id = 0, fragment_shader_id = 0; GLuint vertex_shader_id = 0, fragment_shader_id = 0;
if (!PyArg_ParseTuple(args, "iss", &which, &vertex_shader, &fragment_shader)) return NULL; if (!PyArg_ParseTuple(args, "iss", &which, &vertex_shader, &fragment_shader)) return NULL;
if (which < CELL_PROGRAM || which >= NUM_PROGRAMS) { PyErr_Format(PyExc_ValueError, "Unknown program: %d", which); return NULL; } if (which < 0 || which >= NUM_PROGRAMS) { PyErr_Format(PyExc_ValueError, "Unknown program: %d", which); return NULL; }
if (programs[which].id != 0) { PyErr_SetString(PyExc_ValueError, "program already compiled"); return NULL; } if (programs[which].id != 0) { PyErr_SetString(PyExc_ValueError, "program already compiled"); return NULL; }
programs[which].id = glCreateProgram(); programs[which].id = glCreateProgram();
check_gl(); check_gl();

View File

@ -51,7 +51,9 @@ def calculate_gl_geometry(window_geometry, viewport_width, viewport_height, cell
def load_shader_programs(): def load_shader_programs():
compile_program(CELL_PROGRAM, *load_shaders('cell')) v, f = load_shaders('cell')
v, f = v.replace('WHICH_PROGRAM', 'ALL'), f.replace('WHICH_PROGRAM', 'ALL')
compile_program(CELL_PROGRAM, v, f)
init_cell_program() init_cell_program()
compile_program(CURSOR_PROGRAM, *load_shaders('cursor')) compile_program(CURSOR_PROGRAM, *load_shaders('cursor'))
init_cursor_program() init_cursor_program()