diff --git a/shaders/cell.f.glsl b/shaders/cell.f.glsl index beed2d4e2..c62e89ddb 100644 --- a/shaders/cell.f.glsl +++ b/shaders/cell.f.glsl @@ -2,18 +2,21 @@ in vec2 glyph_tex_coords; -/// The background color for this cell. -flat in vec4 bg_color; +// The color for this cell. If this is a background pass this is the +// background color. Otherwise, this is the foreground color. +flat in vec4 color; -/// Font texture +// Font texture uniform sampler2D text; +// Background or foreground pass. +uniform int background; + void main() { - int background = 0; if (background == 1) { - gl_FragColor = bg_color; + gl_FragColor = color; } else { float a = texture(text, glyph_tex_coords).r; - gl_FragColor = vec4(bg_color.rgb, bg_color.a*a); + gl_FragColor = vec4(color.rgb, color.a*a); } } diff --git a/shaders/cell.v.glsl b/shaders/cell.v.glsl index dc86e92cb..97c8ea715 100644 --- a/shaders/cell.v.glsl +++ b/shaders/cell.v.glsl @@ -13,10 +13,14 @@ layout (location = 2) in vec2 glyph_size; layout (location = 3) in vec2 glyph_offset; // The background color for this cell in RGBA (0 to 1.0) -layout (location = 4) in vec4 bg_color_in; +layout (location = 4) in vec4 fg_color_in; // The background color for this cell in RGBA (0 to 1.0) -flat out vec4 bg_color; +layout (location = 5) in vec4 bg_color_in; + +// The background or foreground color for the fragment, depending on +// whether this is a background or foreground pass. +flat out vec4 color; // The x/y coordinate for the glyph representing the font. out vec2 glyph_tex_coords; @@ -25,6 +29,10 @@ uniform sampler2D text; uniform vec2 cell_size; uniform mat4 projection; +// non-zero if this is a background pass where we draw the background +// of the cell. We do a background pass followed by a foreground pass. +uniform int background; + void main() { // Top-left cell coordinates converted to world space // Example: (1,0) with a 30 wide cell is converted to (30,0) @@ -44,7 +52,6 @@ void main() { position.x = (gl_VertexID == 0 || gl_VertexID == 1) ? 1. : 0.; position.y = (gl_VertexID == 0 || gl_VertexID == 3) ? 0. : 1.; - int background = 0; if (background == 1) { // Calculate the final position of our cell in world space. // We have to add our cell size since our vertices are offset @@ -52,7 +59,7 @@ void main() { cell_pos = cell_pos + cell_size * position; gl_Position = projection * vec4(cell_pos, 0.0, 1.0); - bg_color = vec4(bg_color_in.rgb / 255.0, 1.0); + color = bg_color_in / 255.0; } else { // TODO: why? vec2 glyph_offset_calc = glyph_offset; @@ -67,7 +74,7 @@ void main() { vec2 glyph_tex_size = glyph_size / text_size.xy; glyph_tex_coords = glyph_pos + glyph_tex_size * position; - // This is used to color the font for now. - bg_color = vec4(bg_color_in.rgb / 255.0, 1.0); + // Set our foreground color output + color = fg_color_in / 255.; } } diff --git a/src/Grid.zig b/src/Grid.zig index 6dbc53302..b6b18d35c 100644 --- a/src/Grid.zig +++ b/src/Grid.zig @@ -52,6 +52,12 @@ const GPUCell = struct { glyph_offset_x: i32, glyph_offset_y: i32, + /// vec4 fg_color_in + fg_r: u8, + fg_g: u8, + fg_b: u8, + fg_a: u8, + /// vec4 bg_color_in bg_r: u8, bg_g: u8, @@ -140,16 +146,20 @@ pub fn init(alloc: Allocator) !Grid { try vbobind.attributeAdvanced(3, 2, gl.c.GL_INT, false, @sizeOf(GPUCell), offset); offset += 2 * @sizeOf(i32); try vbobind.attributeAdvanced(4, 4, gl.c.GL_UNSIGNED_BYTE, false, @sizeOf(GPUCell), offset); + offset += 4 * @sizeOf(u8); + try vbobind.attributeAdvanced(5, 4, gl.c.GL_UNSIGNED_BYTE, false, @sizeOf(GPUCell), offset); try vbobind.enableAttribArray(0); try vbobind.enableAttribArray(1); try vbobind.enableAttribArray(2); try vbobind.enableAttribArray(3); try vbobind.enableAttribArray(4); + try vbobind.enableAttribArray(5); try vbobind.attributeDivisor(0, 1); try vbobind.attributeDivisor(1, 1); try vbobind.attributeDivisor(2, 1); try vbobind.attributeDivisor(3, 1); try vbobind.attributeDivisor(4, 1); + try vbobind.attributeDivisor(5, 1); // Build our texture const tex = try gl.Texture.create(); @@ -246,10 +256,14 @@ pub fn updateCells(self: *Grid, term: Terminal) !void { .glyph_height = glyph.height, .glyph_offset_x = glyph.offset_x, .glyph_offset_y = glyph.offset_y, - .bg_r = 0xFF, + .fg_r = 0xFF, + .fg_g = 0xA5, + .fg_b = 0, + .fg_a = 255, + .bg_r = 0x0, .bg_g = 0xA5, .bg_b = 0, - .bg_a = 255, + .bg_a = 0, }); } } @@ -304,6 +318,15 @@ pub fn render(self: Grid) !void { var texbind = try self.texture.bind(.@"2D"); defer texbind.unbind(); + try self.program.setUniform("background", 1); + try gl.drawElementsInstanced( + gl.c.GL_TRIANGLES, + 6, + gl.c.GL_UNSIGNED_BYTE, + self.cells.items.len, + ); + + try self.program.setUniform("background", 0); try gl.drawElementsInstanced( gl.c.GL_TRIANGLES, 6, diff --git a/src/opengl/Program.zig b/src/opengl/Program.zig index 0e961b4c7..a68f0cd9b 100644 --- a/src/opengl/Program.zig +++ b/src/opengl/Program.zig @@ -82,6 +82,7 @@ pub inline fn setUniform(p: Program, n: [:0]const u8, value: anytype) !void { // Perform the correct call depending on the type of the value. switch (@TypeOf(value)) { + comptime_int => c.glUniform1i(loc, value), @Vector(2, f32) => c.glUniform2f(loc, value[0], value[1]), @Vector(3, f32) => c.glUniform3f(loc, value[0], value[1], value[2]), @Vector(4, f32) => c.glUniform4f(loc, value[0], value[1], value[2], value[3]),