diff options
author | HampusM <hampus@hampusmat.com> | 2025-09-19 16:36:57 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2025-10-02 16:55:33 +0200 |
commit | ea1d70c8c28e3b96da6264021fa1c62e28fcd8e4 (patch) | |
tree | 62ae9b75ee84602899b51483ed26fa664df36888 /opengl-bindings/src/lib.rs | |
parent | 0008b374c7f3a9ef6b30ea31a4a8c98bce64649f (diff) |
feat: add OpenGL bindings crate
Diffstat (limited to 'opengl-bindings/src/lib.rs')
-rw-r--r-- | opengl-bindings/src/lib.rs | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/opengl-bindings/src/lib.rs b/opengl-bindings/src/lib.rs new file mode 100644 index 0000000..7fd9933 --- /dev/null +++ b/opengl-bindings/src/lib.rs @@ -0,0 +1,119 @@ +#![deny(clippy::all, clippy::pedantic)] +use std::ffi::CString; +use std::process::abort; + +use glutin::context::{NotCurrentContext, PossiblyCurrentContext}; +use glutin::display::GetGlDisplay; +use glutin::prelude::{GlDisplay, NotCurrentGlContext, PossiblyCurrentGlContext}; +use glutin::surface::{Surface, SurfaceTypeTrait}; + +pub mod buffer; +pub mod data_types; +pub mod debug; +pub mod misc; +pub mod shader; +pub mod texture; +pub mod vertex_array; + +pub struct ContextWithFns +{ + context: PossiblyCurrentContext, + fns: Box<sys::Gl>, +} + +impl ContextWithFns +{ + /// Returns a new `ContextWithFns`. + /// + /// # Errors + /// Returns `Err` if making this context current fails. + pub fn new<SurfaceType: SurfaceTypeTrait>( + context: NotCurrentContext, + surface: &Surface<SurfaceType>, + ) -> Result<Self, Error> + { + let context = context + .make_current(surface) + .map_err(Error::MakeContextCurrentFailed)?; + + let display = context.display(); + + let gl = sys::Gl::load_with(|symbol| { + let Ok(symbol) = CString::new(symbol) else { + eprintln!("GL symbol contains nul byte"); + abort(); + }; + + display.get_proc_address(&symbol) + }); + + Ok(Self { context, fns: Box::new(gl) }) + } + + /// Attempts to make this context current. + /// + /// # Errors + /// Returns `Err` if making this context current fails. + pub fn make_current<SurfaceType: SurfaceTypeTrait>( + &self, + surface: &Surface<SurfaceType>, + ) -> Result<CurrentContextWithFns<'_>, Error> + { + if !self.context.is_current() { + self.context + .make_current(surface) + .map_err(Error::MakeContextCurrentFailed)?; + } + + Ok(CurrentContextWithFns { ctx: self }) + } + + #[must_use] + pub fn context(&self) -> &PossiblyCurrentContext + { + &self.context + } + + #[must_use] + pub fn context_mut(&mut self) -> &mut PossiblyCurrentContext + { + &mut self.context + } +} + +pub struct CurrentContextWithFns<'ctx> +{ + ctx: &'ctx ContextWithFns, +} + +impl CurrentContextWithFns<'_> +{ + #[inline] + pub(crate) fn fns(&self) -> &sys::Gl + { + &self.ctx.fns + } +} + +#[derive(Debug, thiserror::Error)] +pub enum Error +{ + #[error("Failed to make context current")] + MakeContextCurrentFailed(#[source] glutin::error::Error), +} + +mod sys +{ + #![allow( + clippy::missing_safety_doc, + clippy::missing_transmute_annotations, + clippy::too_many_arguments, + clippy::unused_unit, + clippy::upper_case_acronyms, + clippy::doc_markdown, + clippy::unreadable_literal, + unsafe_op_in_unsafe_fn + )] + + include!(concat!(env!("OUT_DIR"), "/bindings.rs")); +} |