#gl #function #pointers #load #loaded #opengl #loading-calling

no-std gl_struct_loader

Struct for loading/calling GL functions

2 releases

0.1.1 Feb 23, 2023
0.1.0 Feb 23, 2023

#923 in Graphics APIs


Used in 2 crates (via ezgl)

Zlib OR Apache-2.0 OR MIT

385KB
6.5K SLoC

gl_struct_loader

Struct for loading/calling GL functions


lib.rs:

Crate with a struct that can load GL function pointers, and that lets you call them.

This Can Support:

  • All OpenGL functions in the "Core" profile up to 4.6 (api="gl")
  • All OpenGL ES functions from 2.0 up to 3.2 (api="gles2")
  • The GL_KHR_debug extension (which is a core part of both OpenGL 4.3 and OpenGL ES 3.2, but has to be used as just an extension in earlier versions).

Typical Initialization

let gl = {
  let user_loader = |name| unimplemented!("call some OS fn here");
  let mut gl = GlFns::new_boxed();
  unsafe { gl.load(user_loader) };
  gl
};

The new_boxed function makes the struct directly on the heap (it's kinda large to keep it on the stack), and requires the crate's alloc feature (which is on by default). If you somehow can use GL but can't use the alloc crate you can use the BLANK_GL_FNS constant to make an empty value of the struct.

Global GL

If you'd like to call the GL API from anywhere (like in a C program) it's still possible using this crate, though I'll admit it's a hair clunky.

When the crate's std feature (on by default) is enabled there is a static RwLock available called [GL]:

unsafe {
  // Grab a write lock to load the functions
  GL.write().unwrap().load(|name| core::ptr::null());

  // Then a read lock lets you call the functions
  GL.read().unwrap().ClearColor(1.0, 0.0, 0.5, 1.0);
}

However you'd wrap up and hide the unsafety of the GL API can also just hide the lock grabbing and all that, so it's not too bad in practice.

What Was Loaded

If you attempt to call a function that is not loaded, it will cause a panic.

If you want to check that a function is loaded you can call the has_loaded method (giving a FnLoadedChecker) and then the method that you want to check the status of:

let gl = BLANK_GL_FNS;
assert_eq!(gl.has_loaded().ClearColor(), false);

That said, on some platforms it's possible for a function to load even though the current context's API level and allowed extensions don't actually let you legally call that function. As with most any improper uses of a C API, actually doing this is Undefined Behavior.

I want to be extra clear: You should only call functions that are allowed by the current context's API level and extension list.

Dependencies