mirror of
https://github.com/lihop/godot-xterm.git
synced 2024-11-10 04:40:25 +01:00
Use shader include for fore/background shaders
The two shaders use a lot of common logic for co-ordinate and attribute look up, so it makes sense to use a common include shader for both. Adds support for the inverse and blink attributes to the foreground shader.
This commit is contained in:
parent
a849423096
commit
8b320622f9
5 changed files with 95 additions and 49 deletions
|
@ -332,14 +332,21 @@ void Terminal::update_sizes(bool force)
|
|||
attr_image = Image::create(std::max(cols, 1u), std::max(rows, 1u), false, Image::FORMAT_L8);
|
||||
attr_texture->set_image(attr_image);
|
||||
|
||||
back_material->set_shader_parameter("cols", cols);
|
||||
back_material->set_shader_parameter("rows", rows);
|
||||
back_material->set_shader_parameter("size", size);
|
||||
back_material->set_shader_parameter("cell_size", cell_size);
|
||||
update_shader_parameters(back_material);
|
||||
update_shader_parameters(fore_material);
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
void Terminal::update_shader_parameters(Ref<ShaderMaterial> material)
|
||||
{
|
||||
material->set_shader_parameter("cols", cols);
|
||||
material->set_shader_parameter("rows", rows);
|
||||
material->set_shader_parameter("size", size);
|
||||
material->set_shader_parameter("cell_size", cell_size);
|
||||
material->set_shader_parameter("grid_size", Vector2(cols * cell_size.x, rows * cell_size.y));
|
||||
}
|
||||
|
||||
void Terminal::initialize_rendering() {
|
||||
ResourceLoader* rl = ResourceLoader::get_singleton();
|
||||
|
||||
|
@ -354,7 +361,7 @@ void Terminal::initialize_rendering() {
|
|||
|
||||
back_material.instantiate();
|
||||
back_material->set_shader(back_shader);
|
||||
back_material->set_shader_parameter("cell_colors", back_texture);
|
||||
back_material->set_shader_parameter("background_colors", back_texture);
|
||||
back_material->set_shader_parameter("attributes", attr_texture);
|
||||
|
||||
back_canvas_item = rs->canvas_item_create();
|
||||
|
@ -404,7 +411,7 @@ void Terminal::update_theme() {
|
|||
tsm_vte_color color = static_cast<tsm_vte_color>(i);
|
||||
palette[color] = get_theme_color(String(COLOR_NAMES[i]));
|
||||
}
|
||||
back_material->set_shader_parameter("background", palette[TSM_COLOR_BACKGROUND]);
|
||||
back_material->set_shader_parameter("background_color", palette[TSM_COLOR_BACKGROUND]);
|
||||
|
||||
// TODO: Default to mono font and handle other styles.
|
||||
font = get_theme_font("normal_font");
|
||||
|
|
|
@ -97,6 +97,7 @@ namespace godot
|
|||
void initialize_rendering();
|
||||
void update_theme();
|
||||
void update_sizes(bool force = false);
|
||||
void update_shader_parameters(Ref<ShaderMaterial> material);
|
||||
void draw_screen();
|
||||
void refresh();
|
||||
void cleanup_rendering();
|
||||
|
|
|
@ -1,38 +1,5 @@
|
|||
// SPDX-FileCopyrightText: 2024 Leroy Hopson <godot-xterm@leroy.nix.nz>
|
||||
// SPDX-License-Identifier: MIT
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform int cols;
|
||||
uniform int rows;
|
||||
uniform vec2 size; // Total size of the Terminal control.
|
||||
uniform vec2 cell_size;
|
||||
uniform vec4 background;
|
||||
uniform sampler2D cell_colors; // Texture containing the cell colors, one pixel per cell.
|
||||
|
||||
const int INVERSE_FLAG = 1 << 0;
|
||||
// Texture containing the cell attributes encoded using bit flags, one flag per cell in the R channel.
|
||||
uniform sampler2D attributes;
|
||||
|
||||
void fragment() {
|
||||
// Grid means the part of the terminal that contains the cells.
|
||||
// Will vary depending on font size and the size of the control.
|
||||
vec2 grid_size = vec2(cell_size.x * float(cols), cell_size.y * float(rows));
|
||||
|
||||
if (UV.x * size.x < grid_size.x && UV.y * size.y < grid_size.y) {
|
||||
vec2 grid_uv = UV * size / cell_size;
|
||||
|
||||
int cell_x = int(grid_uv.x);
|
||||
int cell_y = int(grid_uv.y);
|
||||
|
||||
vec2 sample_uv = (vec2(float(cell_x), float(cell_y)) + 0.5) / vec2(float(cols), float(rows));
|
||||
vec4 color = texture(cell_colors, sample_uv);
|
||||
|
||||
int attr_flags = int(texture(attributes, sample_uv).r * 255.0 + 0.5);
|
||||
if ((attr_flags & INVERSE_FLAG) != 0) {
|
||||
color = vec4(1.0 - color.rgb, color.a);
|
||||
}
|
||||
|
||||
COLOR = color;
|
||||
} else {
|
||||
// If outside the grid area, use the background color.
|
||||
COLOR = background;
|
||||
}
|
||||
}
|
||||
#define BACKGROUND
|
||||
#include "./common.gdshaderinc"
|
73
addons/godot_xterm/shaders/common.gdshaderinc
Normal file
73
addons/godot_xterm/shaders/common.gdshaderinc
Normal file
|
@ -0,0 +1,73 @@
|
|||
// SPDX-FileCopyrightText: 2024 Leroy Hopson <godot-xterm@leroy.nix.nz>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#define FLAG_INVERSE 1 << 0
|
||||
#define FLAG_BLINK 1 << 1
|
||||
|
||||
#define transparent vec4(0)
|
||||
|
||||
uniform int cols;
|
||||
uniform int rows;
|
||||
uniform vec2 size;
|
||||
uniform vec2 cell_size;
|
||||
uniform vec2 grid_size;
|
||||
|
||||
uniform sampler2D attributes;
|
||||
|
||||
#ifdef BACKGROUND
|
||||
uniform vec4 background_color;
|
||||
uniform sampler2D background_colors;
|
||||
#endif
|
||||
|
||||
#ifdef FOREGROUND
|
||||
uniform float blink_off_time = 0.3;
|
||||
uniform float blink_on_time = 0.6;
|
||||
#endif
|
||||
|
||||
bool has_attribute(vec2 uv, int flag) {
|
||||
int flags = int(texture(attributes, uv).r * 255.0 + 0.5);
|
||||
return (flags & flag) != 0;
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
// Check if we are inside the grid.
|
||||
if (UV.x * size.x < grid_size.x && UV.y * size.y < grid_size.y) {
|
||||
vec2 grid_uv = UV * size / cell_size;
|
||||
|
||||
int cell_x = int(grid_uv.x);
|
||||
int cell_y = int(grid_uv.y);
|
||||
|
||||
vec2 sample_uv = (vec2(float(cell_x), float(cell_y)) + 0.5) / vec2(float(cols), float(rows));
|
||||
|
||||
vec4 color;
|
||||
#ifdef BACKGROUND
|
||||
color = texture(background_colors, sample_uv);
|
||||
#elif defined(FOREGROUND)
|
||||
color = texture(TEXTURE, UV);
|
||||
#endif
|
||||
|
||||
if (has_attribute(sample_uv, FLAG_INVERSE)) {
|
||||
color = vec4(1.0 - color.rgb, color.a);
|
||||
}
|
||||
|
||||
#ifdef FOREGROUND
|
||||
if (has_attribute(sample_uv, FLAG_BLINK)) {
|
||||
float blink_cycle = blink_on_time + blink_off_time;
|
||||
float current_time = mod(TIME, blink_cycle);
|
||||
if (current_time > blink_on_time) {
|
||||
color = transparent;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FOREGROUND) || defined(BACKGROUND)
|
||||
COLOR = color;
|
||||
#endif
|
||||
} else { // Outside the grid.
|
||||
#ifdef BACKGROUND
|
||||
COLOR = background_color;
|
||||
#elif defined(FOREGROUND)
|
||||
COLOR = transparent;
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
// SPDX-FileCopyrightText: 2024 Leroy Hopson <godot-xterm@leroy.nix.nz>
|
||||
// SPDX-License-Identifier: MIT
|
||||
shader_type canvas_item;
|
||||
|
||||
void fragment() {
|
||||
COLOR = texture(TEXTURE, UV);
|
||||
// TODO: Check blink attribute and hide/show using the below.
|
||||
//COLOR = vec4(0);
|
||||
}
|
||||
#define FOREGROUND
|
||||
#include "./common.gdshaderinc"
|
Loading…
Reference in a new issue