mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-10-16 06:46:09 +00:00
renderer/opengl: create the screen texture
This commit is contained in:
@@ -1346,11 +1346,11 @@ fn flushAtlas(self: *OpenGL) !void {
|
||||
atlas.resized = false;
|
||||
try texbind.image2D(
|
||||
0,
|
||||
.Red,
|
||||
.red,
|
||||
@intCast(atlas.size),
|
||||
@intCast(atlas.size),
|
||||
0,
|
||||
.Red,
|
||||
.red,
|
||||
.UnsignedByte,
|
||||
atlas.data.ptr,
|
||||
);
|
||||
@@ -1361,7 +1361,7 @@ fn flushAtlas(self: *OpenGL) !void {
|
||||
0,
|
||||
@intCast(atlas.size),
|
||||
@intCast(atlas.size),
|
||||
.Red,
|
||||
.red,
|
||||
.UnsignedByte,
|
||||
atlas.data.ptr,
|
||||
);
|
||||
@@ -1380,11 +1380,11 @@ fn flushAtlas(self: *OpenGL) !void {
|
||||
atlas.resized = false;
|
||||
try texbind.image2D(
|
||||
0,
|
||||
.RGBA,
|
||||
.rgba,
|
||||
@intCast(atlas.size),
|
||||
@intCast(atlas.size),
|
||||
0,
|
||||
.BGRA,
|
||||
.bgra,
|
||||
.UnsignedByte,
|
||||
atlas.data.ptr,
|
||||
);
|
||||
@@ -1395,7 +1395,7 @@ fn flushAtlas(self: *OpenGL) !void {
|
||||
0,
|
||||
@intCast(atlas.size),
|
||||
@intCast(atlas.size),
|
||||
.BGRA,
|
||||
.bgra,
|
||||
.UnsignedByte,
|
||||
atlas.data.ptr,
|
||||
);
|
||||
@@ -1441,8 +1441,7 @@ fn drawCustomPrograms(
|
||||
const custom_bind = try custom_state.bind();
|
||||
defer custom_bind.unbind();
|
||||
|
||||
// Sync the uniform data.
|
||||
// TODO: only do this when the data has changed
|
||||
// Setup the new frame
|
||||
try custom_state.newFrame();
|
||||
|
||||
// Go through each custom shader and draw it.
|
||||
@@ -1469,6 +1468,14 @@ fn drawCellProgram(
|
||||
// are changes to the atlas.
|
||||
try self.flushAtlas();
|
||||
|
||||
// If we have custom shaders, then we draw to the custom
|
||||
// shader framebuffer.
|
||||
const fbobind: ?gl.Framebuffer.Binding = fbobind: {
|
||||
const state = gl_state.custom orelse break :fbobind null;
|
||||
break :fbobind try state.fbo.bind(.framebuffer);
|
||||
};
|
||||
defer if (fbobind) |v| v.unbind();
|
||||
|
||||
// Clear the surface
|
||||
gl.clearColor(
|
||||
@as(f32, @floatFromInt(self.draw_background.r)) / 255,
|
||||
@@ -1615,11 +1622,11 @@ const GLState = struct {
|
||||
try texbind.parameter(.MagFilter, gl.c.GL_LINEAR);
|
||||
try texbind.image2D(
|
||||
0,
|
||||
.Red,
|
||||
.red,
|
||||
@intCast(font_group.atlas_greyscale.size),
|
||||
@intCast(font_group.atlas_greyscale.size),
|
||||
0,
|
||||
.Red,
|
||||
.red,
|
||||
.UnsignedByte,
|
||||
font_group.atlas_greyscale.data.ptr,
|
||||
);
|
||||
@@ -1636,11 +1643,11 @@ const GLState = struct {
|
||||
try texbind.parameter(.MagFilter, gl.c.GL_LINEAR);
|
||||
try texbind.image2D(
|
||||
0,
|
||||
.RGBA,
|
||||
.rgba,
|
||||
@intCast(font_group.atlas_color.size),
|
||||
@intCast(font_group.atlas_color.size),
|
||||
0,
|
||||
.BGRA,
|
||||
.bgra,
|
||||
.UnsignedByte,
|
||||
font_group.atlas_color.data.ptr,
|
||||
);
|
||||
|
@@ -3,6 +3,8 @@ const Allocator = std.mem.Allocator;
|
||||
const gl = @import("opengl");
|
||||
const ScreenSize = @import("../size.zig").ScreenSize;
|
||||
|
||||
const log = std.log.scoped(.opengl_custom);
|
||||
|
||||
/// The "INDEX" is the index into the global GL state and the
|
||||
/// "BINDING" is the binding location in the shader.
|
||||
const UNIFORM_INDEX: gl.c.GLuint = 0;
|
||||
@@ -27,9 +29,11 @@ pub const State = struct {
|
||||
uniforms: Uniforms,
|
||||
|
||||
/// The OpenGL buffers
|
||||
fbo: gl.Framebuffer,
|
||||
ubo: gl.Buffer,
|
||||
vao: gl.VertexArray,
|
||||
ebo: gl.Buffer,
|
||||
fb_texture: gl.Texture,
|
||||
|
||||
/// The set of programs for the custom shaders.
|
||||
programs: []const Program,
|
||||
@@ -50,6 +54,44 @@ pub const State = struct {
|
||||
try programs.append(try Program.init(src));
|
||||
}
|
||||
|
||||
// Create the texture for the framebuffer
|
||||
const fb_tex = try gl.Texture.create();
|
||||
errdefer fb_tex.destroy();
|
||||
{
|
||||
const texbind = try fb_tex.bind(.@"2D");
|
||||
try texbind.parameter(.WrapS, gl.c.GL_CLAMP_TO_EDGE);
|
||||
try texbind.parameter(.WrapT, gl.c.GL_CLAMP_TO_EDGE);
|
||||
try texbind.parameter(.MinFilter, gl.c.GL_LINEAR);
|
||||
try texbind.parameter(.MagFilter, gl.c.GL_LINEAR);
|
||||
try texbind.image2D(
|
||||
0,
|
||||
.rgb,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
.rgb,
|
||||
.UnsignedByte,
|
||||
null,
|
||||
);
|
||||
}
|
||||
|
||||
// Create our framebuffer for rendering off screen.
|
||||
// The shader prior to custom shaders should use this
|
||||
// framebuffer.
|
||||
const fbo = try gl.Framebuffer.create();
|
||||
errdefer fbo.destroy();
|
||||
const fbbind = try fbo.bind(.framebuffer);
|
||||
defer fbbind.unbind();
|
||||
try fbbind.texture2D(.color0, .@"2D", fb_tex, 0);
|
||||
const fbstatus = fbbind.checkStatus();
|
||||
if (fbstatus != .complete) {
|
||||
log.warn(
|
||||
"framebuffer is not complete state={}",
|
||||
.{fbstatus},
|
||||
);
|
||||
return error.InvalidFramebuffer;
|
||||
}
|
||||
|
||||
// Create our uniform buffer that is shared across all
|
||||
// custom shaders
|
||||
const ubo = try gl.Buffer.create();
|
||||
@@ -79,9 +121,11 @@ pub const State = struct {
|
||||
return .{
|
||||
.programs = try programs.toOwnedSlice(),
|
||||
.uniforms = .{},
|
||||
.fbo = fbo,
|
||||
.ubo = ubo,
|
||||
.vao = vao,
|
||||
.ebo = ebo,
|
||||
.fb_texture = fb_tex,
|
||||
.last_frame_time = try std.time.Instant.now(),
|
||||
};
|
||||
}
|
||||
@@ -92,6 +136,8 @@ pub const State = struct {
|
||||
self.ubo.destroy();
|
||||
self.ebo.destroy();
|
||||
self.vao.destroy();
|
||||
self.fb_texture.destroy();
|
||||
self.fbo.destroy();
|
||||
}
|
||||
|
||||
pub fn setScreenSize(self: *State, size: ScreenSize) !void {
|
||||
@@ -137,6 +183,11 @@ pub const State = struct {
|
||||
// the global state.
|
||||
try self.ubo.bindBase(.uniform, UNIFORM_INDEX);
|
||||
|
||||
// Bind our texture that is shared amongst all
|
||||
try gl.Texture.active(gl.c.GL_TEXTURE0);
|
||||
var texbind = try self.fb_texture.bind(.@"2D");
|
||||
errdefer texbind.unbind();
|
||||
|
||||
const vao = try self.vao.bind();
|
||||
errdefer vao.unbind();
|
||||
|
||||
@@ -146,16 +197,19 @@ pub const State = struct {
|
||||
return .{
|
||||
.vao = vao,
|
||||
.ebo = ebo,
|
||||
.fb_texture = texbind,
|
||||
};
|
||||
}
|
||||
|
||||
pub const Binding = struct {
|
||||
vao: gl.VertexArray.Binding,
|
||||
ebo: gl.Buffer.Binding,
|
||||
fb_texture: gl.Texture.Binding,
|
||||
|
||||
pub fn unbind(self: Binding) void {
|
||||
self.ebo.unbind();
|
||||
self.vao.unbind();
|
||||
self.fb_texture.unbind();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
Reference in New Issue
Block a user