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
#define ALPHA_TYPE
uniform sampler2D image;
@ -7,4 +8,7 @@ out vec4 color;
void main() {
color = texture(image, texcoord);
#ifdef PREMULT
color = vec4(color.rgb * color.a, color.a);
#endif
}

View File

@ -1,6 +1,7 @@
#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;
void main() {

View File

@ -9,7 +9,7 @@
#include "fonts.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 };
// Sprites {{{
@ -278,12 +278,13 @@ cell_prepare_to_render(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, GLfloa
}
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_program(GRAPHICS_PROGRAM);
bind_program(program);
static bool graphics_constants_set = false;
if (!graphics_constants_set) {
glUniform1i(glGetUniformLocation(program_id(GRAPHICS_PROGRAM), "image"), GRAPHICS_UNIT);
glUniform1i(glGetUniformLocation(program_id(GRAPHICS_PREMULT_PROGRAM), "image"), GRAPHICS_UNIT);
graphics_constants_set = true;
}
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);
if (screen->grman->count) {
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);
}
}
@ -329,7 +331,8 @@ draw_cells_interleaved(ssize_t vao_idx, ssize_t gvao_idx, Screen *screen, OSWind
bind_program(CELL_BG_PROGRAM);
glDrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, screen->lines * screen->columns);
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);
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);
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);
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;
}
glActiveTexture(GL_TEXTURE0 + BLIT_UNIT);
glBindTexture(GL_TEXTURE_2D, os_window->offscreen_texture_id);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
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) {
bind_program(CELL_PROGRAM);
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;
}
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
init_shaders(PyObject *module) {
#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(GL_VERSION);
C(GL_VENDOR);

View File

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