add background pass

This commit is contained in:
Mitchell Hashimoto
2022-04-19 08:54:39 -07:00
parent e9661fa55e
commit c43c1d38f1
4 changed files with 48 additions and 14 deletions

View File

@ -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);
}
}

View File

@ -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.;
}
}

View File

@ -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,

View File

@ -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]),