egui_glow/
lib.rs

1//! [`egui`] bindings for [`glow`](https://github.com/grovesNL/glow).
2//!
3//! The main type you want to look at is [`Painter`].
4//!
5//! If you are writing an app, you may want to look at [`eframe`](https://docs.rs/eframe) instead.
6//!
7//! ## Feature flags
8#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
9//!
10
11#![expect(clippy::undocumented_unsafe_blocks)]
12
13pub mod painter;
14pub use glow;
15pub use painter::{CallbackFn, Painter, PainterError};
16mod misc_util;
17mod shader_version;
18mod vao;
19
20pub use shader_version::ShaderVersion;
21
22#[cfg(feature = "winit")]
23pub mod winit;
24#[cfg(feature = "winit")]
25pub use winit::*;
26
27/// Check for OpenGL error and report it using `log::error`.
28///
29/// Only active in debug builds!
30///
31/// ``` no_run
32/// # let glow_context = todo!();
33/// use egui_glow::check_for_gl_error;
34/// check_for_gl_error!(glow_context);
35/// check_for_gl_error!(glow_context, "during painting");
36/// ```
37#[macro_export]
38macro_rules! check_for_gl_error {
39    ($gl: expr) => {{
40        if cfg!(debug_assertions) {
41            $crate::check_for_gl_error_impl($gl, file!(), line!(), "")
42        }
43    }};
44    ($gl: expr, $context: literal) => {{
45        if cfg!(debug_assertions) {
46            $crate::check_for_gl_error_impl($gl, file!(), line!(), $context)
47        }
48    }};
49}
50
51/// Check for OpenGL error and report it using `log::error`.
52///
53/// WARNING: slow! Only use during setup!
54///
55/// ``` no_run
56/// # let glow_context = todo!();
57/// use egui_glow::check_for_gl_error_even_in_release;
58/// check_for_gl_error_even_in_release!(glow_context);
59/// check_for_gl_error_even_in_release!(glow_context, "during painting");
60/// ```
61#[macro_export]
62macro_rules! check_for_gl_error_even_in_release {
63    ($gl: expr) => {{ $crate::check_for_gl_error_impl($gl, file!(), line!(), "") }};
64    ($gl: expr, $context: literal) => {{ $crate::check_for_gl_error_impl($gl, file!(), line!(), $context) }};
65}
66
67#[doc(hidden)]
68pub fn check_for_gl_error_impl(gl: &glow::Context, file: &str, line: u32, context: &str) {
69    use glow::HasContext as _;
70    #[expect(unsafe_code)]
71    let error_code = unsafe { gl.get_error() };
72    if error_code != glow::NO_ERROR {
73        let error_str = match error_code {
74            glow::INVALID_ENUM => "GL_INVALID_ENUM",
75            glow::INVALID_VALUE => "GL_INVALID_VALUE",
76            glow::INVALID_OPERATION => "GL_INVALID_OPERATION",
77            glow::STACK_OVERFLOW => "GL_STACK_OVERFLOW",
78            glow::STACK_UNDERFLOW => "GL_STACK_UNDERFLOW",
79            glow::OUT_OF_MEMORY => "GL_OUT_OF_MEMORY",
80            glow::INVALID_FRAMEBUFFER_OPERATION => "GL_INVALID_FRAMEBUFFER_OPERATION",
81            glow::CONTEXT_LOST => "GL_CONTEXT_LOST",
82            0x8031 => "GL_TABLE_TOO_LARGE1",
83            0x9242 => "CONTEXT_LOST_WEBGL",
84            _ => "<unknown>",
85        };
86
87        if context.is_empty() {
88            log::error!(
89                "GL error, at {file}:{line}: {error_str} (0x{error_code:X}). Please file a bug at https://github.com/emilk/egui/issues"
90            );
91        } else {
92            log::error!(
93                "GL error, at {file}:{line} ({context}): {error_str} (0x{error_code:X}). Please file a bug at https://github.com/emilk/egui/issues"
94            );
95        }
96    }
97}