gl_struct_loader/
lib.rs

1#![no_std]
2#![warn(missing_docs)]
3#![allow(nonstandard_style)]
4#![cfg_attr(docs_rs, feature(doc_cfg))]
5
6//! Crate with a struct that can load GL function pointers, and that lets you
7//! call them.
8//!
9//! This Can Support:
10//! * All OpenGL functions in the "Core" profile up to 4.6 (`api="gl"`)
11//! * All OpenGL ES functions from 2.0 up to 3.2 (`api="gles2"`)
12//! * The `GL_KHR_debug` extension (which is a core part of both OpenGL 4.3 and
13//!   OpenGL ES 3.2, but has to be used as just an extension in earlier
14//!   versions).
15//!
16//! ## Typical Initialization
17//!
18//! ```rust,no_run
19//! # use gl_struct_loader::*;
20//! let gl = {
21//!   let user_loader = |name| unimplemented!("call some OS fn here");
22//!   let mut gl = GlFns::new_boxed();
23//!   unsafe { gl.load(user_loader) };
24//!   gl
25//! };
26//! ```
27//!
28//! The [new_boxed](GlFns::new_boxed) function makes the struct directly on the
29//! heap (it's kinda large to keep it on the stack), and requires the crate's
30//! `alloc` feature (which is on by default). If you somehow can use GL but
31//! can't use the `alloc` crate you can use the [`BLANK_GL_FNS`] constant to
32//! make an empty value of the struct.
33//!
34//! ## Global GL
35//!
36//! If you'd like to call the GL API from anywhere (like in a C program) it's
37//! still possible using this crate, though I'll admit it's a hair clunky.
38//!
39//! When the crate's `std` feature (on by default) is enabled there is a static
40//! [RwLock](std::sync::RwLock) available called [`GL`]:
41//!
42//! ```rust,no_run
43//! # use gl_struct_loader::*;
44//! unsafe {
45//!   // Grab a write lock to load the functions
46//!   GL.write().unwrap().load(|name| core::ptr::null());
47//!
48//!   // Then a read lock lets you call the functions
49//!   GL.read().unwrap().ClearColor(1.0, 0.0, 0.5, 1.0);
50//! }
51//! ```
52//!
53//! However you'd wrap up and hide the unsafety of the GL API can also just hide
54//! the lock grabbing and all that, so it's not too bad in practice.
55//!
56//! ## What Was Loaded
57//!
58//! If you attempt to call a function that is not loaded, it will cause a panic.
59//!
60//! If you want to check that a function is loaded you can call the
61//! [`has_loaded`](GlFns::has_loaded) method (giving a [`FnLoadedChecker`]) and
62//! then the method that you want to check the status of:
63//!
64//! ```rust
65//! # use gl_struct_loader::*;
66//! let gl = BLANK_GL_FNS;
67//! assert_eq!(gl.has_loaded().ClearColor(), false);
68//! ```
69//!
70//! That said, on some platforms it's *possible* for a function to load even
71//! though the current context's API level and allowed extensions don't actually
72//! let you legally call that function. As with most any improper uses of a C
73//! API, actually doing this is Undefined Behavior.
74//!
75//! **I want to be extra clear:** You should **only** call functions that are
76//! allowed by the current context's API level and extension list.
77
78#[cfg(feature = "alloc")]
79extern crate alloc;
80
81#[cfg(feature = "std")]
82extern crate std;
83
84use gl_types::*;
85
86mod struct_decl;
87pub use struct_decl::*;
88
89mod creation;
90pub use creation::*;
91
92mod calling;
93
94mod fn_ty_aliases;
95use fn_ty_aliases::*;
96
97mod loaded_checker;
98pub use loaded_checker::*;