summaryrefslogtreecommitdiff
path: root/opengl-bindings/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'opengl-bindings/src/lib.rs')
-rw-r--r--opengl-bindings/src/lib.rs119
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"));
+}