mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
Enable depth buffer, add depth to shader
This commit is contained in:
@ -35,6 +35,17 @@ layout (location = 5) in vec4 bg_color_in;
|
|||||||
// the entire terminal grid in a single GPU pass.
|
// the entire terminal grid in a single GPU pass.
|
||||||
layout (location = 6) in uint mode_in;
|
layout (location = 6) in uint mode_in;
|
||||||
|
|
||||||
|
// The Z-depth. This is between 0.0 and 1.0. This is used to paint newer
|
||||||
|
// values on top of older ones to limit the amount of data that needs to
|
||||||
|
// be sent to the GPU.
|
||||||
|
//
|
||||||
|
// 0 is further back/away, 1 is front/near
|
||||||
|
//
|
||||||
|
// TODO: It would be better to just send the Z value as part of grid_coord
|
||||||
|
// and normalize it to NDC and then linearly transform it but this was easy
|
||||||
|
// to get going more quickly.
|
||||||
|
layout (location = 7) in float grid_z;
|
||||||
|
|
||||||
// The background or foreground color for the fragment, depending on
|
// The background or foreground color for the fragment, depending on
|
||||||
// whether this is a background or foreground pass.
|
// whether this is a background or foreground pass.
|
||||||
flat out vec4 color;
|
flat out vec4 color;
|
||||||
@ -82,6 +93,11 @@ void main() {
|
|||||||
// Example: (1,0) with a 30 wide cell is converted to (30,0)
|
// Example: (1,0) with a 30 wide cell is converted to (30,0)
|
||||||
vec2 cell_pos = cell_size * grid_coord;
|
vec2 cell_pos = cell_size * grid_coord;
|
||||||
|
|
||||||
|
// Our Z value. For now we just use grid_z directly but we pull it
|
||||||
|
// out here so the variable name is more uniform to our cell_pos and
|
||||||
|
// in case we want to do any other math later.
|
||||||
|
float cell_z = grid_z;
|
||||||
|
|
||||||
// Turn the cell position into a vertex point depending on the
|
// Turn the cell position into a vertex point depending on the
|
||||||
// gl_VertexID. Since we use instanced drawing, we have 4 vertices
|
// gl_VertexID. Since we use instanced drawing, we have 4 vertices
|
||||||
// for each corner of the cell. We can use gl_VertexID to determine
|
// for each corner of the cell. We can use gl_VertexID to determine
|
||||||
@ -103,7 +119,7 @@ void main() {
|
|||||||
// one cell up and to the left. (Do the math to verify yourself)
|
// one cell up and to the left. (Do the math to verify yourself)
|
||||||
cell_pos = cell_pos + cell_size * position;
|
cell_pos = cell_pos + cell_size * position;
|
||||||
|
|
||||||
gl_Position = projection * vec4(cell_pos, 0.0, 1.0);
|
gl_Position = projection * vec4(cell_pos, cell_z, 1.0);
|
||||||
color = bg_color_in / 255.0;
|
color = bg_color_in / 255.0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -117,7 +133,7 @@ void main() {
|
|||||||
|
|
||||||
// Calculate the final position of the cell.
|
// Calculate the final position of the cell.
|
||||||
cell_pos = cell_pos + glyph_size * position + glyph_offset_calc;
|
cell_pos = cell_pos + glyph_size * position + glyph_offset_calc;
|
||||||
gl_Position = projection * vec4(cell_pos, 0.0, 1.0);
|
gl_Position = projection * vec4(cell_pos, cell_z, 1.0);
|
||||||
|
|
||||||
// We need to convert our texture position and size to normalized
|
// We need to convert our texture position and size to normalized
|
||||||
// device coordinates (0 to 1.0) by dividing by the size of the texture.
|
// device coordinates (0 to 1.0) by dividing by the size of the texture.
|
||||||
@ -134,7 +150,7 @@ void main() {
|
|||||||
// Same as background since we're taking up the whole cell.
|
// Same as background since we're taking up the whole cell.
|
||||||
cell_pos = cell_pos + cell_size * position;
|
cell_pos = cell_pos + cell_size * position;
|
||||||
|
|
||||||
gl_Position = projection * vec4(cell_pos, 0.0, 1.0);
|
gl_Position = projection * vec4(cell_pos, cell_z, 1.0);
|
||||||
color = bg_color_in / 255.0;
|
color = bg_color_in / 255.0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -145,7 +161,7 @@ void main() {
|
|||||||
// Same as background since we're taking up the whole cell.
|
// Same as background since we're taking up the whole cell.
|
||||||
cell_pos = cell_pos + cell_size * position;
|
cell_pos = cell_pos + cell_size * position;
|
||||||
|
|
||||||
gl_Position = projection * vec4(cell_pos, 0.0, 1.0);
|
gl_Position = projection * vec4(cell_pos, cell_z, 1.0);
|
||||||
color = bg_color_in / 255.0;
|
color = bg_color_in / 255.0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -156,7 +172,7 @@ void main() {
|
|||||||
// Same as background since we're taking up the whole cell.
|
// Same as background since we're taking up the whole cell.
|
||||||
cell_pos = cell_pos + bar_size * position;
|
cell_pos = cell_pos + bar_size * position;
|
||||||
|
|
||||||
gl_Position = projection * vec4(cell_pos, 0.0, 1.0);
|
gl_Position = projection * vec4(cell_pos, cell_z, 1.0);
|
||||||
color = bg_color_in / 255.0;
|
color = bg_color_in / 255.0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -174,7 +190,7 @@ void main() {
|
|||||||
// above the bottom.
|
// above the bottom.
|
||||||
cell_pos = cell_pos + underline_offset - underline_size * position;
|
cell_pos = cell_pos + underline_offset - underline_size * position;
|
||||||
|
|
||||||
gl_Position = projection * vec4(cell_pos, 0.0, 1.0);
|
gl_Position = projection * vec4(cell_pos, cell_z, 1.0);
|
||||||
color = fg_color_in / 255.0;
|
color = fg_color_in / 255.0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
14
src/Grid.zig
14
src/Grid.zig
@ -100,6 +100,10 @@ const GPUCell = struct {
|
|||||||
|
|
||||||
/// uint mode
|
/// uint mode
|
||||||
mode: u8,
|
mode: u8,
|
||||||
|
|
||||||
|
/// float grid_z. This is normalized to a float by dividing by the
|
||||||
|
/// max int value.
|
||||||
|
grid_z: u16,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init(alloc: Allocator, config: *const Config) !Grid {
|
pub fn init(alloc: Allocator, config: *const Config) !Grid {
|
||||||
@ -198,6 +202,8 @@ pub fn init(alloc: Allocator, config: *const Config) !Grid {
|
|||||||
try vbobind.attributeAdvanced(5, 4, gl.c.GL_UNSIGNED_BYTE, false, @sizeOf(GPUCell), offset);
|
try vbobind.attributeAdvanced(5, 4, gl.c.GL_UNSIGNED_BYTE, false, @sizeOf(GPUCell), offset);
|
||||||
offset += 4 * @sizeOf(u8);
|
offset += 4 * @sizeOf(u8);
|
||||||
try vbobind.attributeIAdvanced(6, 1, gl.c.GL_UNSIGNED_BYTE, @sizeOf(GPUCell), offset);
|
try vbobind.attributeIAdvanced(6, 1, gl.c.GL_UNSIGNED_BYTE, @sizeOf(GPUCell), offset);
|
||||||
|
offset += 1 * @sizeOf(u8);
|
||||||
|
try vbobind.attributeAdvanced(7, 1, gl.c.GL_UNSIGNED_SHORT, true, @sizeOf(GPUCell), offset);
|
||||||
try vbobind.enableAttribArray(0);
|
try vbobind.enableAttribArray(0);
|
||||||
try vbobind.enableAttribArray(1);
|
try vbobind.enableAttribArray(1);
|
||||||
try vbobind.enableAttribArray(2);
|
try vbobind.enableAttribArray(2);
|
||||||
@ -205,6 +211,7 @@ pub fn init(alloc: Allocator, config: *const Config) !Grid {
|
|||||||
try vbobind.enableAttribArray(4);
|
try vbobind.enableAttribArray(4);
|
||||||
try vbobind.enableAttribArray(5);
|
try vbobind.enableAttribArray(5);
|
||||||
try vbobind.enableAttribArray(6);
|
try vbobind.enableAttribArray(6);
|
||||||
|
try vbobind.enableAttribArray(7);
|
||||||
try vbobind.attributeDivisor(0, 1);
|
try vbobind.attributeDivisor(0, 1);
|
||||||
try vbobind.attributeDivisor(1, 1);
|
try vbobind.attributeDivisor(1, 1);
|
||||||
try vbobind.attributeDivisor(2, 1);
|
try vbobind.attributeDivisor(2, 1);
|
||||||
@ -212,6 +219,7 @@ pub fn init(alloc: Allocator, config: *const Config) !Grid {
|
|||||||
try vbobind.attributeDivisor(4, 1);
|
try vbobind.attributeDivisor(4, 1);
|
||||||
try vbobind.attributeDivisor(5, 1);
|
try vbobind.attributeDivisor(5, 1);
|
||||||
try vbobind.attributeDivisor(6, 1);
|
try vbobind.attributeDivisor(6, 1);
|
||||||
|
try vbobind.attributeDivisor(7, 1);
|
||||||
|
|
||||||
// Build our texture
|
// Build our texture
|
||||||
const tex = try gl.Texture.create();
|
const tex = try gl.Texture.create();
|
||||||
@ -342,6 +350,7 @@ pub fn updateCells(self: *Grid, term: Terminal) !void {
|
|||||||
.mode = 1,
|
.mode = 1,
|
||||||
.grid_col = @intCast(u16, x),
|
.grid_col = @intCast(u16, x),
|
||||||
.grid_row = @intCast(u16, y),
|
.grid_row = @intCast(u16, y),
|
||||||
|
.grid_z = 0,
|
||||||
.glyph_x = 0,
|
.glyph_x = 0,
|
||||||
.glyph_y = 0,
|
.glyph_y = 0,
|
||||||
.glyph_width = 0,
|
.glyph_width = 0,
|
||||||
@ -380,6 +389,7 @@ pub fn updateCells(self: *Grid, term: Terminal) !void {
|
|||||||
.mode = 2,
|
.mode = 2,
|
||||||
.grid_col = @intCast(u16, x),
|
.grid_col = @intCast(u16, x),
|
||||||
.grid_row = @intCast(u16, y),
|
.grid_row = @intCast(u16, y),
|
||||||
|
.grid_z = 1,
|
||||||
.glyph_x = glyph.atlas_x,
|
.glyph_x = glyph.atlas_x,
|
||||||
.glyph_y = glyph.atlas_y,
|
.glyph_y = glyph.atlas_y,
|
||||||
.glyph_width = glyph.width,
|
.glyph_width = glyph.width,
|
||||||
@ -402,6 +412,7 @@ pub fn updateCells(self: *Grid, term: Terminal) !void {
|
|||||||
.mode = 6, // underline
|
.mode = 6, // underline
|
||||||
.grid_col = @intCast(u16, x),
|
.grid_col = @intCast(u16, x),
|
||||||
.grid_row = @intCast(u16, y),
|
.grid_row = @intCast(u16, y),
|
||||||
|
.grid_z = 1,
|
||||||
.glyph_x = 0,
|
.glyph_x = 0,
|
||||||
.glyph_y = 0,
|
.glyph_y = 0,
|
||||||
.glyph_width = 0,
|
.glyph_width = 0,
|
||||||
@ -435,6 +446,9 @@ pub fn updateCells(self: *Grid, term: Terminal) !void {
|
|||||||
.bg_g = 0xFF,
|
.bg_g = 0xFF,
|
||||||
.bg_b = 0xFF,
|
.bg_b = 0xFF,
|
||||||
.bg_a = 255,
|
.bg_a = 255,
|
||||||
|
|
||||||
|
// The cursor is always at the very front
|
||||||
|
.grid_z = 255,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,6 +200,14 @@ pub fn create(alloc: Allocator, loop: libuv.Loop, config: *const Config) !*Windo
|
|||||||
gl.c.glEnable(gl.c.GL_BLEND);
|
gl.c.glEnable(gl.c.GL_BLEND);
|
||||||
gl.c.glBlendFunc(gl.c.GL_SRC_ALPHA, gl.c.GL_ONE_MINUS_SRC_ALPHA);
|
gl.c.glBlendFunc(gl.c.GL_SRC_ALPHA, gl.c.GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
// Depth test since we use the Z-buffer as an optimization to send
|
||||||
|
// only changed cells to the GPU. As cells are updated, we bump their
|
||||||
|
// Z value to be closer, so that over time new values are rendered "over"
|
||||||
|
// values (in reality old values are culled by the depth test, so they
|
||||||
|
// aren't ever "rendered").
|
||||||
|
gl.c.glEnable(gl.c.GL_DEPTH_TEST);
|
||||||
|
gl.c.glDepthFunc(gl.c.GL_LESS);
|
||||||
|
|
||||||
// Create our terminal grid with the initial window size
|
// Create our terminal grid with the initial window size
|
||||||
const window_size = try window.getSize();
|
const window_size = try window.getSize();
|
||||||
var grid = try Grid.init(alloc, config);
|
var grid = try Grid.init(alloc, config);
|
||||||
@ -960,7 +968,7 @@ fn renderTimerCallback(t: *libuv.Timer) void {
|
|||||||
.a = win.bg_a,
|
.a = win.bg_a,
|
||||||
};
|
};
|
||||||
gl.clearColor(gl_bg.r, gl_bg.g, gl_bg.b, gl_bg.a);
|
gl.clearColor(gl_bg.r, gl_bg.g, gl_bg.b, gl_bg.a);
|
||||||
gl.clear(gl.c.GL_COLOR_BUFFER_BIT);
|
gl.clear(gl.c.GL_COLOR_BUFFER_BIT | gl.c.GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
// Update the cells for drawing
|
// Update the cells for drawing
|
||||||
win.grid.updateCells(win.terminal) catch |err|
|
win.grid.updateCells(win.terminal) catch |err|
|
||||||
|
Reference in New Issue
Block a user