glitz 0.4.0

GL Bindings thing.
Documentation
#![no_std]

//! The GL docs here are adapted from the official Khronos GL documentation
//! ([license](https://khronos.org/registry/OpenGL-Refpages/LICENSES/LicenseRef-FreeB.txt)).
//!
//! This is a crate for using "raw" GL calls, with all GL functions stored in a
//! [GlFns] struct.
//!
//! The struct has one method per function pointer. Every method just calls the
//! appropriate function pointer held inside. The method names match the usual
//! GL function names with the "gl" prefix removed. It's expected that you'll
//! bind the struct itself to a variable named `gl`, and then call a function
//! such as `glClear` with `gl.Clear`.
//!
//! All of the pointers in `GlFns` are non-nullable function pointers. This
//! skips the program needing to do a null check on every single GL function
//! call. The downside is that if any expected function pointer fails to load,
//! the entire loading process will fail.
//!
//! The current list of functions supported by this crate is much less than all
//! possible GL functions. Right now the crate assumes OpenGL 3.3 +
//! `GL_KHR_debug` is available. This configuration is widely supported on
//! Windows, Mac, and Linux. Even then, the exact list of functions that are
//! loaded is only a subset of the full possibilities.
//!
//! In the future, the crate might offer a way to more precisely configure at
//! compile time which functions are included or not.
//!
//! ## Example Usage
//!
//! ```no_run
//! use glitz::*;
//!
//! unimplemented!("set up the GL context and be ready to load functions");
//!
//! let loader_fn = |c_str: *const u8| {
//!   // The loader fn is intended to accept a null-termianted-pointer.
//!   // This matches up with SDL_GL_GetProcAddress, wglGetProcAddress,
//!   // GetProcAddress, and similar.
//!   unimplemented!("use the OS or a lib to load a fn by name.");
//!
//!   // If you're using a rust lib that expects `&str` values, you can
//!   // convert the pointer like this:
//!   let _s: &str =
//!     unsafe { std::ffi::CStr::from_ptr(c_str.cast()).to_str().unwrap() };
//! };
//!
//! let gl = unsafe { GlFns::from_loader(&loader_fn).unwrap() };
//!
//! gl.ClearColor(0.5, 0.5, 0.5, 1.0);
//! gl.Clear(GL_COLOR_BUFFER_BIT);
//! ```

#[cfg(feature = "std")]
extern crate std;

#[path = "../generator/src/gl_fn_types.rs"]
mod gl_fn_types;
mod gl_struct;

pub mod gl_constants;
pub mod gl_types;
#[allow(unused)]
use core::ffi::c_void;

pub use gl_constants::*;
pub use gl_struct::*;
pub use gl_types::*;

#[cfg(feature = "std")]
pub unsafe extern "system" fn println_gl_debug_callback(
  source: GLenum, type_: GLenum, id: GLuint, severity: GLenum, length: GLsizei,
  message: *const GLchar, _user_param: *const c_void,
) {
  let source = match source {
    GL_DEBUG_SOURCE_API => "API",
    GL_DEBUG_SOURCE_WINDOW_SYSTEM => "WindowSystem",
    GL_DEBUG_SOURCE_SHADER_COMPILER => "ShaderCompiler",
    GL_DEBUG_SOURCE_THIRD_PARTY => "ThirdParty",
    GL_DEBUG_SOURCE_APPLICATION => "Application",
    GL_DEBUG_SOURCE_OTHER => "Other",
    _ => "Unknown",
  };
  let type_ = match type_ {
    GL_DEBUG_TYPE_ERROR => "Error",
    GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR => "DeprecatedBehavior",
    GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR => "UndefinedBehavior",
    GL_DEBUG_TYPE_PORTABILITY => "Portability",
    GL_DEBUG_TYPE_PERFORMANCE => "Performance",
    GL_DEBUG_TYPE_OTHER => "Other",
    GL_DEBUG_TYPE_MARKER => "Marker",
    _ => "Unknown",
  };
  let severity = match severity {
    GL_DEBUG_SEVERITY_HIGH => "High",
    GL_DEBUG_SEVERITY_MEDIUM => "Medium",
    GL_DEBUG_SEVERITY_LOW => "Low",
    GL_DEBUG_SEVERITY_NOTIFICATION => "Note",
    _ => "Unknown",
  };

  std::println!(
    "[src:{source}][ty:{type_}][id:{id}][severity:{severity}]: {msg}",
    source = source,
    type_ = type_,
    id = id,
    severity = severity,
    msg = core::str::from_utf8(core::slice::from_raw_parts(
      message as *const u8,
      length as usize,
    ))
    .unwrap_or("message was not utf8")
  );
}