diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index bd4fd9f00..ff096fef0 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -57,6 +57,7 @@ texture_greyscale: objc.Object, // MTLTexture const GPUCell = extern struct { mode: GPUCellMode, grid_pos: [2]f32, + color: [4]u8, glyph_pos: [2]u32 = .{ 0, 0 }, glyph_size: [2]u32 = .{ 0, 0 }, glyph_offset: [2]i32 = .{ 0, 0 }, @@ -520,10 +521,11 @@ pub fn updateCell( // If the cell has a background, we always draw it. if (colors.bg) |rgb| { - _ = rgb; self.cells.appendAssumeCapacity(.{ .mode = .bg, .grid_pos = .{ @intToFloat(f32, x), @intToFloat(f32, y) }, + .color = .{ rgb.r, rgb.g, rgb.b, alpha }, + // .grid_col = @intCast(u16, x), // .grid_row = @intCast(u16, y), // .grid_width = cell.widthLegacy(), @@ -537,7 +539,6 @@ pub fn updateCell( // .bg_a = alpha, }); } - _ = alpha; // If the cell has a character, draw it if (cell.char > 0) { @@ -554,6 +555,7 @@ pub fn updateCell( self.cells.appendAssumeCapacity(.{ .mode = .fg, .grid_pos = .{ @intToFloat(f32, x), @intToFloat(f32, y) }, + .color = .{ colors.fg.r, colors.fg.g, colors.fg.b, alpha }, .glyph_pos = .{ glyph.atlas_x, glyph.atlas_y }, .glyph_size = .{ glyph.width, glyph.height }, .glyph_offset = .{ glyph.offset_x, glyph.offset_y }, @@ -742,6 +744,17 @@ fn initPipelineState(device: objc.Object, library: objc.Object) !objc.Object { attr.setProperty("offset", @as(c_ulong, @offsetOf(GPUCell, "glyph_offset"))); attr.setProperty("bufferIndex", @as(c_ulong, 0)); } + { + const attr = attrs.msgSend( + objc.Object, + objc.sel("objectAtIndexedSubscript:"), + .{@as(c_ulong, 5)}, + ); + + attr.setProperty("format", @enumToInt(MTLVertexFormat.uchar4)); + attr.setProperty("offset", @as(c_ulong, @offsetOf(GPUCell, "color"))); + attr.setProperty("bufferIndex", @as(c_ulong, 0)); + } // The layout describes how and when we fetch the next vertex input. const layouts = objc.Object.fromId(desc.getProperty(?*anyopaque, "layouts")); @@ -887,6 +900,7 @@ const MTLIndexType = enum(c_ulong) { /// https://developer.apple.com/documentation/metal/mtlvertexformat?language=objc const MTLVertexFormat = enum(c_ulong) { + uchar4 = 3, float2 = 29, int2 = 33, uint2 = 37, diff --git a/src/shaders/cell.metal b/src/shaders/cell.metal index 157ab7d9c..560fffa3e 100644 --- a/src/shaders/cell.metal +++ b/src/shaders/cell.metal @@ -18,6 +18,10 @@ struct VertexIn { // The grid coordinates (x, y) where x < columns and y < rows float2 grid_pos [[ attribute(1) ]]; + // The color. For BG modes, this is the bg color, for FG modes this is + // the text color. For styles, this is the color of the style. + uchar4 color [[ attribute(5) ]]; + // The fields below are present only when rendering text. // The position of the glyph in the texture (x,y) @@ -32,6 +36,8 @@ struct VertexIn { struct VertexOut { float4 position [[ position ]]; + uint8_t mode; + float4 color; }; vertex VertexOut uber_vertex( @@ -60,6 +66,8 @@ vertex VertexOut uber_vertex( float2 cell_size = uniforms.cell_size; VertexOut out; + out.mode = input.mode; + out.color = float4(input.color) / 255.0f; switch (input.mode) { case MODE_BG: // Calculate the final position of our cell in world space. @@ -91,8 +99,17 @@ vertex VertexOut uber_vertex( return out; } -fragment half4 uber_fragment( - VertexOut in [[ stage_in ]] +fragment float4 uber_fragment( + VertexOut in [[ stage_in ]], + texture2d textureGreyscale [[ texture(0) ]] ) { - return half4(1.0, 0.0, 0.0, 1.0); + constexpr sampler textureSampler; + + switch (in.mode) { + case MODE_BG: + return in.color; + + case MODE_FG: + return in.color; + } }