From 41dd733ca7123c9ac4bfc6c781697a660e95b052 Mon Sep 17 00:00:00 2001 From: Can Celik Date: Sat, 4 Apr 2026 19:22:04 +0300 Subject: feat: finish ghostty pane backend integration --- vendor/libghostty-vt/pkg/opengl/Program.zig | 137 ++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 vendor/libghostty-vt/pkg/opengl/Program.zig (limited to 'vendor/libghostty-vt/pkg/opengl/Program.zig') diff --git a/vendor/libghostty-vt/pkg/opengl/Program.zig b/vendor/libghostty-vt/pkg/opengl/Program.zig new file mode 100644 index 00000000..ee77582c --- /dev/null +++ b/vendor/libghostty-vt/pkg/opengl/Program.zig @@ -0,0 +1,137 @@ +const Program = @This(); + +const std = @import("std"); +const assert = std.debug.assert; +const log = std.log.scoped(.opengl); + +const c = @import("c.zig").c; +const Shader = @import("Shader.zig"); +const errors = @import("errors.zig"); +const glad = @import("glad.zig"); + +id: c.GLuint, + +pub const Binding = struct { + pub fn unbind(_: Binding) void { + glad.context.UseProgram.?(0); + } +}; + +pub fn create() !Program { + const id = glad.context.CreateProgram.?(); + if (id == 0) try errors.mustError(); + log.debug("program created id={}", .{id}); + return .{ .id = id }; +} + +/// Create a program from a vertex and fragment shader source. This will +/// compile and link the vertex and fragment shader. +pub fn createVF(vsrc: [:0]const u8, fsrc: [:0]const u8) !Program { + const vs = try Shader.create(c.GL_VERTEX_SHADER); + try vs.setSourceAndCompile(vsrc); + defer vs.destroy(); + + const fs = try Shader.create(c.GL_FRAGMENT_SHADER); + try fs.setSourceAndCompile(fsrc); + defer fs.destroy(); + + const p = try create(); + try p.attachShader(vs); + try p.attachShader(fs); + try p.link(); + + return p; +} + +pub fn destroy(p: Program) void { + assert(p.id != 0); + glad.context.DeleteProgram.?(p.id); + log.debug("program destroyed id={}", .{p.id}); +} + +pub fn attachShader(p: Program, s: Shader) !void { + glad.context.AttachShader.?(p.id, s.id); + try errors.getError(); +} + +pub fn link(p: Program) !void { + glad.context.LinkProgram.?(p.id); + + // Check if linking succeeded + var success: c_int = undefined; + glad.context.GetProgramiv.?(p.id, c.GL_LINK_STATUS, &success); + if (success == c.GL_TRUE) { + log.debug("program linked id={}", .{p.id}); + return; + } + + log.err("program link failure id={} message={s}", .{ + p.id, + std.mem.sliceTo(&p.getInfoLog(), 0), + }); + return error.CompileFailed; +} + +pub fn use(p: Program) !Binding { + glad.context.UseProgram.?(p.id); + try errors.getError(); + return .{}; +} + +pub fn uniformBlockBinding( + self: Program, + index: c.GLuint, + binding: c.GLuint, +) !void { + glad.context.UniformBlockBinding.?(self.id, index, binding); + try errors.getError(); +} + +/// Requires the program is currently in use. +pub fn setUniform( + p: Program, + n: [:0]const u8, + value: anytype, +) !void { + const loc = glad.context.GetUniformLocation.?( + p.id, + @ptrCast(n.ptr), + ); + if (loc < 0) { + return error.UniformNameInvalid; + } + try errors.getError(); + + // Perform the correct call depending on the type of the value. + switch (@TypeOf(value)) { + bool => glad.context.Uniform1i.?(loc, if (value) 1 else 0), + comptime_int => glad.context.Uniform1i.?(loc, value), + f32 => glad.context.Uniform1f.?(loc, value), + @Vector(2, f32) => glad.context.Uniform2f.?(loc, value[0], value[1]), + @Vector(3, f32) => glad.context.Uniform3f.?(loc, value[0], value[1], value[2]), + @Vector(4, f32) => glad.context.Uniform4f.?(loc, value[0], value[1], value[2], value[3]), + [4]@Vector(4, f32) => glad.context.UniformMatrix4fv.?( + loc, + 1, + c.GL_FALSE, + @ptrCast(&value), + ), + else => { + log.warn("unsupported uniform type {}", .{@TypeOf(value)}); + unreachable; + }, + } + try errors.getError(); +} + +/// getInfoLog returns the info log for this program. This attempts to +/// keep the log fully stack allocated and is therefore limited to a max +/// amount of elements. +// +// NOTE(mitchellh): we can add a dynamic version that uses an allocator +// if we ever need it. +pub fn getInfoLog(s: Program) [512]u8 { + var msg: [512]u8 = undefined; + glad.context.GetProgramInfoLog.?(s.id, msg.len, null, &msg); + return msg; +} -- cgit v1.2.3