Graphics programs should generate pre-multipled colors in interleaved mode

Also fix a few OpenGL state initialization issues.
This commit is contained in:
Kovid Goyal 2017-11-23 19:12:19 +05:30
parent ffff343e3d
commit 444d9536a7
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 30 additions and 13 deletions

View File

@ -1,4 +1,5 @@
#version GLSL_VERSION #version GLSL_VERSION
#define ALPHA_TYPE
uniform sampler2D image; uniform sampler2D image;
@ -7,4 +8,7 @@ out vec4 color;
void main() { void main() {
color = texture(image, texcoord); color = texture(image, texcoord);
#ifdef PREMULT
color = vec4(color.rgb * color.a, color.a);
#endif
} }

View File

@ -1,6 +1,7 @@
#version GLSL_VERSION #version GLSL_VERSION
in vec4 src; // Have to use fixed locations here as all variants of the program share the same VAO
layout(location=0) in vec4 src;
out vec2 texcoord; out vec2 texcoord;
void main() { void main() {

View File

@ -9,7 +9,7 @@
#include "fonts.h" #include "fonts.h"
#include <sys/sysctl.h> #include <sys/sysctl.h>
enum { CELL_PROGRAM, CELL_BG_PROGRAM, CELL_SPECIAL_PROGRAM, CELL_FG_PROGRAM, CURSOR_PROGRAM, BORDERS_PROGRAM, GRAPHICS_PROGRAM, BLIT_PROGRAM, NUM_PROGRAMS }; enum { CELL_PROGRAM, CELL_BG_PROGRAM, CELL_SPECIAL_PROGRAM, CELL_FG_PROGRAM, CURSOR_PROGRAM, BORDERS_PROGRAM, GRAPHICS_PROGRAM, GRAPHICS_PREMULT_PROGRAM, BLIT_PROGRAM, NUM_PROGRAMS };
enum { SPRITE_MAP_UNIT, GRAPHICS_UNIT, BLIT_UNIT }; enum { SPRITE_MAP_UNIT, GRAPHICS_UNIT, BLIT_UNIT };
// Sprites {{{ // Sprites {{{
@ -278,12 +278,13 @@ cell_prepare_to_render(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, GLfloa
} }
static void static void
draw_graphics(ssize_t vao_idx, ssize_t gvao_idx, ImageRenderData *data, GLuint start, GLuint count) { draw_graphics(int program, ssize_t vao_idx, ssize_t gvao_idx, ImageRenderData *data, GLuint start, GLuint count) {
bind_vertex_array(gvao_idx); bind_vertex_array(gvao_idx);
bind_program(GRAPHICS_PROGRAM); bind_program(program);
static bool graphics_constants_set = false; static bool graphics_constants_set = false;
if (!graphics_constants_set) { if (!graphics_constants_set) {
glUniform1i(glGetUniformLocation(program_id(GRAPHICS_PROGRAM), "image"), GRAPHICS_UNIT); glUniform1i(glGetUniformLocation(program_id(GRAPHICS_PROGRAM), "image"), GRAPHICS_UNIT);
glUniform1i(glGetUniformLocation(program_id(GRAPHICS_PREMULT_PROGRAM), "image"), GRAPHICS_UNIT);
graphics_constants_set = true; graphics_constants_set = true;
} }
glActiveTexture(GL_TEXTURE0 + GRAPHICS_UNIT); glActiveTexture(GL_TEXTURE0 + GRAPHICS_UNIT);
@ -308,7 +309,8 @@ draw_all_cells(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen) {
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns); glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
if (screen->grman->count) { if (screen->grman->count) {
glEnable(GL_BLEND); glEnable(GL_BLEND);
draw_graphics(vao_idx, gvao_idx, screen->grman->render_data, 0, screen->grman->count); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // blending onto opaque colors
draw_graphics(GRAPHICS_PROGRAM, vao_idx, gvao_idx, screen->grman->render_data, 0, screen->grman->count);
glDisable(GL_BLEND); glDisable(GL_BLEND);
} }
} }
@ -329,7 +331,8 @@ draw_cells_interleaved(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, OSWind
bind_program(CELL_BG_PROGRAM); bind_program(CELL_BG_PROGRAM);
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns); glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
glEnable(GL_BLEND); glEnable(GL_BLEND);
if (screen->grman->num_of_negative_refs) draw_graphics(vao_idx, gvao_idx, screen->grman->render_data, 0, screen->grman->num_of_negative_refs); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // blending of pre-multiplied colors
if (screen->grman->num_of_negative_refs) draw_graphics(GRAPHICS_PREMULT_PROGRAM, vao_idx, gvao_idx, screen->grman->render_data, 0, screen->grman->num_of_negative_refs);
bind_program(CELL_SPECIAL_PROGRAM); bind_program(CELL_SPECIAL_PROGRAM);
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns); glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
@ -337,7 +340,7 @@ draw_cells_interleaved(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, OSWind
bind_program(CELL_FG_PROGRAM); bind_program(CELL_FG_PROGRAM);
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns); glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
if (screen->grman->num_of_positive_refs) draw_graphics(vao_idx, gvao_idx, screen->grman->render_data, screen->grman->num_of_negative_refs, screen->grman->num_of_positive_refs); if (screen->grman->num_of_positive_refs) draw_graphics(GRAPHICS_PREMULT_PROGRAM, vao_idx, gvao_idx, screen->grman->render_data, screen->grman->num_of_negative_refs, screen->grman->num_of_positive_refs);
glDisable(GL_BLEND); glDisable(GL_BLEND);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
@ -350,6 +353,7 @@ draw_cells_interleaved(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, OSWind
blit_constants_set = true; blit_constants_set = true;
} }
glActiveTexture(GL_TEXTURE0 + BLIT_UNIT); glActiveTexture(GL_TEXTURE0 + BLIT_UNIT);
glBindTexture(GL_TEXTURE_2D, os_window->offscreen_texture_id);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glDisable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST);
} }
@ -370,6 +374,7 @@ draw_cells(ssize_t vao_idx, ssize_t gvao_idx, GLfloat xstart, GLfloat ystart, GL
if (!cell_constants_set) { if (!cell_constants_set) {
bind_program(CELL_PROGRAM); bind_program(CELL_PROGRAM);
glUniform1i(glGetUniformLocation(program_id(CELL_PROGRAM), "sprites"), SPRITE_MAP_UNIT); glUniform1i(glGetUniformLocation(program_id(CELL_PROGRAM), "sprites"), SPRITE_MAP_UNIT);
glUniform1i(glGetUniformLocation(program_id(CELL_FG_PROGRAM), "sprites"), SPRITE_MAP_UNIT);
cell_constants_set = true; cell_constants_set = true;
} }
bool needs_complex_rendering = screen->grman->num_of_negative_refs || (screen->grman->num_of_positive_refs && os_window->is_semi_transparent); bool needs_complex_rendering = screen->grman->num_of_negative_refs || (screen->grman->num_of_positive_refs && os_window->is_semi_transparent);
@ -550,7 +555,7 @@ static PyMethodDef module_methods[] = {
bool bool
init_shaders(PyObject *module) { init_shaders(PyObject *module) {
#define C(x) if (PyModule_AddIntConstant(module, #x, x) != 0) { PyErr_NoMemory(); return false; } #define C(x) if (PyModule_AddIntConstant(module, #x, x) != 0) { PyErr_NoMemory(); return false; }
C(CELL_PROGRAM); C(CELL_BG_PROGRAM); C(CELL_SPECIAL_PROGRAM); C(CELL_FG_PROGRAM); C(CURSOR_PROGRAM); C(BORDERS_PROGRAM); C(GRAPHICS_PROGRAM); C(BLIT_PROGRAM); C(CELL_PROGRAM); C(CELL_BG_PROGRAM); C(CELL_SPECIAL_PROGRAM); C(CELL_FG_PROGRAM); C(CURSOR_PROGRAM); C(BORDERS_PROGRAM); C(GRAPHICS_PROGRAM); C(GRAPHICS_PREMULT_PROGRAM); C(BLIT_PROGRAM);
C(GLSL_VERSION); C(GLSL_VERSION);
C(GL_VERSION); C(GL_VERSION);
C(GL_VENDOR); C(GL_VENDOR);

View File

@ -14,10 +14,11 @@ from .constants import (
from .fast_data_types import ( from .fast_data_types import (
BLIT_PROGRAM, BRACKETED_PASTE_END, BRACKETED_PASTE_START, CELL_BG_PROGRAM, BLIT_PROGRAM, BRACKETED_PASTE_END, BRACKETED_PASTE_START, CELL_BG_PROGRAM,
CELL_FG_PROGRAM, CELL_PROGRAM, CELL_SPECIAL_PROGRAM, CURSOR_PROGRAM, CELL_FG_PROGRAM, CELL_PROGRAM, CELL_SPECIAL_PROGRAM, CURSOR_PROGRAM,
GRAPHICS_PROGRAM, SCROLL_FULL, SCROLL_LINE, SCROLL_PAGE, Screen, GRAPHICS_PREMULT_PROGRAM, GRAPHICS_PROGRAM, SCROLL_FULL, SCROLL_LINE,
add_window, compile_program, glfw_post_empty_event, init_cell_program, SCROLL_PAGE, Screen, add_window, compile_program, glfw_post_empty_event,
init_cursor_program, set_clipboard_string, set_window_render_data, init_cell_program, init_cursor_program, set_clipboard_string,
update_window_title, update_window_visibility, viewport_for_window set_window_render_data, update_window_title, update_window_visibility,
viewport_for_window
) )
from .keys import keyboard_mode_name from .keys import keyboard_mode_name
from .rgb import to_color from .rgb import to_color
@ -53,7 +54,6 @@ def calculate_gl_geometry(window_geometry, viewport_width, viewport_height, cell
def load_shader_programs(semi_transparent=0): def load_shader_programs(semi_transparent=0):
v, f = load_shaders('cell') v, f = load_shaders('cell')
compile_program(GRAPHICS_PROGRAM, *load_shaders('graphics'))
compile_program(BLIT_PROGRAM, *load_shaders('blit')) compile_program(BLIT_PROGRAM, *load_shaders('blit'))
for which, p in { for which, p in {
'SIMPLE': CELL_PROGRAM, 'SIMPLE': CELL_PROGRAM,
@ -66,6 +66,13 @@ def load_shader_programs(semi_transparent=0):
vv = vv.replace('#define NOT_TRANSPARENT', '#define TRANSPARENT') vv = vv.replace('#define NOT_TRANSPARENT', '#define TRANSPARENT')
ff = ff.replace('#define NOT_TRANSPARENT', '#define TRANSPARENT') ff = ff.replace('#define NOT_TRANSPARENT', '#define TRANSPARENT')
compile_program(p, vv, ff) compile_program(p, vv, ff)
v, f = load_shaders('graphics')
for which, p in {
'SIMPLE': GRAPHICS_PROGRAM,
'PREMULT': GRAPHICS_PREMULT_PROGRAM,
}.items():
ff = f.replace('ALPHA_TYPE', which)
compile_program(p, v, ff)
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()