luminance_glow/
lib.rs

1//! Glow backend for Luminance
2//!
3//! This crate provides a [glow] backend for [luminance]. It is capable of targeting desktop using
4//! OpenGL and web using both WebGL 2 and WebGL 1 ( though WebGL 1 has some caveats such as
5//! supported texture formats ).
6//!
7//! [luminance]: https://crates.io/crates/luminance
8//!
9//! [glow]: https://github.com/grovesNL/glow
10
11use std::cell::RefCell;
12use std::rc::Rc;
13
14#[macro_use]
15mod slice;
16
17mod buffer;
18mod framebuffer;
19mod pipeline;
20mod pixel;
21mod shader;
22mod state;
23mod tess;
24mod texture;
25
26use glow::Context as GlowContext;
27
28use state::GlowState;
29pub use state::StateQueryError;
30
31/// The GLSL shader version to use
32///
33/// This effects the version heading added automatically to the top of the shader strings provided
34/// to luminance.
35#[derive(Debug, Clone, Copy)]
36pub enum ShaderVersion {
37    Gles3,
38    Gles1,
39}
40
41/// The graphics context which must be provided to create a [`Glow`] backend
42pub struct Context {
43    glow_context: GlowContext,
44    is_webgl1: bool,
45    shader_version: ShaderVersion,
46}
47
48impl Context {
49    /// Create a native context from a GL loader function
50    #[cfg(not(wasm))]
51    pub unsafe fn from_loader_function<F>(loader_function: F, shader_version: ShaderVersion) -> Self
52    where
53        F: FnMut(&str) -> *const std::os::raw::c_void,
54    {
55        Self {
56            glow_context: GlowContext::from_loader_function(loader_function),
57            is_webgl1: false,
58            shader_version,
59        }
60    }
61
62    /// Create a WebGL 1 context
63    ///
64    /// > ⚠️ **Warning:** The WebGL 1 backend has limitations that the native and WebGL 2 bakcends
65    /// > to not have. The exact limitations are outside of the scope of this note, but include
66    /// > things like limited support for different pixel formats, etc.
67    #[cfg(wasm)]
68    pub fn from_webgl1_context(context: web_sys::WebGlRenderingContext) -> Self {
69        Self {
70            glow_context: GlowContext::from_webgl1_context(context),
71            is_webgl1: true,
72            shader_version: ShaderVersion::Gles1,
73        }
74    }
75
76    /// Create a WebGL 2 context
77    #[cfg(wasm)]
78    pub fn from_webgl2_context(
79        context: web_sys::WebGl2RenderingContext,
80        shader_version: ShaderVersion,
81    ) -> Self {
82        Self {
83            glow_context: GlowContext::from_webgl2_context(context),
84            is_webgl1: false,
85            shader_version,
86        }
87    }
88}
89
90/// The Luminance Glow backend
91#[derive(Debug)]
92pub struct Glow {
93    pub(crate) state: Rc<RefCell<GlowState>>,
94}
95
96impl Glow {
97    /// Create a glow backend instance from a `glow` [`Context`][glow::Context]
98    pub fn from_context(ctx: Context) -> Result<Self, StateQueryError> {
99        let Context {
100            glow_context,
101            is_webgl1,
102            shader_version,
103        } = ctx;
104        GlowState::new(glow_context, is_webgl1, shader_version).map(|state| Glow {
105            state: Rc::new(RefCell::new(state)),
106        })
107    }
108}