ugli/
context.rs

1use super::*;
2
3pub(crate) struct UgliImpl {
4    pub(crate) raw: raw::Context,
5    phantom_data: PhantomData<*mut ()>,
6}
7
8#[derive(Clone)]
9pub struct Ugli {
10    pub(crate) inner: Rc<UgliImpl>,
11}
12
13#[cfg(target_arch = "wasm32")]
14#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
15#[serde(rename_all = "camelCase")]
16pub struct WebGLContextOptions {
17    pub alpha: bool,
18    pub preserve_drawing_buffer: bool,
19    pub stencil: bool,
20    pub premultiplied_alpha: bool,
21    pub power_preference: &'static str,
22    pub depth: bool,
23    pub antialias: bool,
24}
25
26#[cfg(target_arch = "wasm32")]
27impl Default for WebGLContextOptions {
28    fn default() -> Self {
29        Self {
30            alpha: false,
31            preserve_drawing_buffer: true,
32            stencil: false,
33            premultiplied_alpha: false,
34            power_preference: "high-performance",
35            depth: true,
36            antialias: false,
37        }
38    }
39}
40
41#[cfg(target_arch = "wasm32")]
42impl Ugli {
43    pub fn create_webgl(canvas: &web_sys::HtmlCanvasElement, options: WebGLContextOptions) -> Self {
44        let context_options = serde_wasm_bindgen::to_value(&options).unwrap();
45        let webgl;
46        if let Some(context) = canvas
47            .get_context_with_context_options("webgl", &context_options)
48            .unwrap()
49        {
50            webgl = context;
51        } else if let Some(context) = canvas
52            .get_context_with_context_options("experimental-webgl", &context_options)
53            .unwrap()
54        {
55            webgl = context;
56        } else {
57            panic!("Could not get webgl context");
58        }
59        let webgl: web_sys::WebGlRenderingContext = webgl.dyn_into().unwrap();
60        let ugli = Ugli {
61            inner: Rc::new(UgliImpl {
62                raw: raw::Context::new(webgl),
63                phantom_data: PhantomData,
64            }),
65        };
66        ugli.init();
67        ugli
68    }
69}
70
71#[cfg(not(target_arch = "wasm32"))]
72impl Ugli {
73    pub fn create_from_glutin<F: Fn(&str) -> *const std::os::raw::c_void>(
74        get_proc_address: F,
75    ) -> Self {
76        let ugli = Ugli {
77            inner: Rc::new(UgliImpl {
78                raw: raw::Context::new(get_proc_address),
79                phantom_data: PhantomData,
80            }),
81        };
82        ugli.init();
83        ugli
84    }
85}
86
87impl Ugli {
88    pub fn init(&self) {
89        let gl = &self.inner.raw;
90        log::info!("GL version: {:?}", gl.get_version_string());
91        gl.enable(raw::DEPTH_TEST);
92        #[cfg(not(any(target_arch = "wasm32", target_os = "android")))]
93        gl.enable(raw::PROGRAM_POINT_SIZE);
94        gl.pixel_store(raw::UNPACK_ALIGNMENT, 1);
95        self.check();
96    }
97}