feat(renderer): port the OpenGL backend, shaders and size math
Ports the terminal-independent half of ZIG/src/renderer (OpenGL only): - opengl/*: buffers, frames, pipelines, render passes, samplers, targets, textures and the OpenGL GraphicsAPI backend on top of glow; the GTK GLArea glue is replaced by a get_proc_address loader closure - the GLSL shaders, copied verbatim and embedded; uniform/vertex structs as bytemuck Pod types with std140 offsets asserted in tests - shadertoy custom shaders converted with naga (GLSL in -> validate -> GLSL 430 out) instead of glslang + spirv-cross - size (screen/grid/cell/padding math), cursor style logic, backend health, options and message types The crate opts into unsafe_code = "deny"; unsafe glow calls live only in opengl/gl.rs. A headless EGL integration test builds every pipeline and the converted shadertoy shaders on Mesa and reads back rendered pixels. Note: Zig's shadertoy Uniforms order the selection background/foreground colors opposite to the GLSL block (likely an upstream bug); kept as in Zig for parity and recorded in the notes. Deferred to the next renderer pass: generic, cell, image, link, row, State, Thread, Overlay (need terminal render state). Test Plan: - cargo test -p ghostty-renderer (33 tests incl. tests/egl_headless.rs)
This commit is contained in:
1 parent
5a5fa7893b
commit
568ce784f9
35 files changed
+5477
-5
No files matched your search
@@ -0,0 +1,55 @@
|
||||
//! Wrapper for handling samplers (`opengl/Sampler.zig`).
|
||||
use super::gl::{self, Gl, MagFilter, MinFilter, RawSampler, Wrap};
|
||||
|
||||
/// Options for initializing a sampler.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct Options {
|
||||
pub min_filter: MinFilter,
|
||||
pub mag_filter: MagFilter,
|
||||
pub wrap_s: Wrap,
|
||||
pub wrap_t: Wrap,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
/// An OpenGL API call failed.
|
||||
#[error("OpenGL call failed")]
|
||||
OpenGLFailed,
|
||||
}
|
||||
|
||||
pub struct Sampler {
|
||||
gl: Gl,
|
||||
sampler: RawSampler,
|
||||
}
|
||||
|
||||
impl Sampler {
|
||||
/// The raw GL sampler handle.
|
||||
pub fn raw(&self) -> RawSampler {
|
||||
self.sampler
|
||||
}
|
||||
|
||||
/// Initialize a sampler
|
||||
pub fn init(gl: &Gl, opts: Options) -> Result<Sampler, Error> {
|
||||
let sampler = gl.create_sampler().map_err(|_| Error::OpenGLFailed)?;
|
||||
// Dropped (and destroyed) on error.
|
||||
let this = Sampler {
|
||||
gl: gl.clone(),
|
||||
sampler,
|
||||
};
|
||||
let p = |name, v| gl.sampler_parameter_i32(sampler, name, v);
|
||||
(|| -> gl::Result<()> {
|
||||
p(gl::param::WRAP_S, opts.wrap_s as i32)?;
|
||||
p(gl::param::WRAP_T, opts.wrap_t as i32)?;
|
||||
p(gl::param::MIN_FILTER, opts.min_filter as i32)?;
|
||||
p(gl::param::MAG_FILTER, opts.mag_filter as i32)
|
||||
})()
|
||||
.map_err(|_| Error::OpenGLFailed)?;
|
||||
Ok(this)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Sampler {
|
||||
fn drop(&mut self) {
|
||||
self.gl.delete_sampler(self.sampler);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user