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)
56 lines
1.5 KiB
Rust
56 lines
1.5 KiB
Rust
//! 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);
|
|
}
|
|
}
|