diff --git a/Cargo.lock b/Cargo.lock index 555503ef686..55dee5c1b43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1018,6 +1018,7 @@ dependencies = [ "dark-light", "egui", "epi", + "glow", "instant", "serde", "tracing", @@ -1219,6 +1220,7 @@ version = "0.17.0" dependencies = [ "directories-next", "egui", + "glow", "ron", "serde", "tracing", diff --git a/eframe/examples/custom_font.rs b/eframe/examples/custom_font.rs index 8ba2ced48d8..0192d32ca1f 100644 --- a/eframe/examples/custom_font.rs +++ b/eframe/examples/custom_font.rs @@ -22,6 +22,7 @@ impl epi::App for MyApp { ctx: &egui::Context, _frame: &epi::Frame, _storage: Option<&dyn epi::Storage>, + _gl: &std::rc::Rc, ) { // Start with the default fonts (we will be adding to them rather than replacing them). let mut fonts = egui::FontDefinitions::default(); diff --git a/egui-winit/Cargo.toml b/egui-winit/Cargo.toml index 1bf48fdad07..a7cde96f905 100644 --- a/egui-winit/Cargo.toml +++ b/egui-winit/Cargo.toml @@ -24,6 +24,12 @@ default = ["clipboard", "dark-light", "links"] # if disabled a clipboard will be simulated so you can still copy/paste within the egui app. clipboard = ["copypasta"] +# implement bytemuck on most types. +convert_bytemuck = ["egui/convert_bytemuck"] + +# Only for `egui_glow` - the official eframe/epi backend. +epi_backend = ["epi", "glow"] + # enable opening links in a browser when an egui hyperlink is clicked. links = ["webbrowser"] @@ -36,9 +42,6 @@ persistence = [ ] # can't add epi/persistence here because of https://github.com/rust-lang/cargo/issues/8832 serialize = ["egui/serialize", "serde"] -# implement bytemuck on most types. -convert_bytemuck = ["egui/convert_bytemuck"] - [dependencies] egui = { version = "0.17.0", path = "../egui", default-features = false, features = [ @@ -53,6 +56,7 @@ epi = { version = "0.17.0", path = "../epi", optional = true } copypasta = { version = "0.7", optional = true } dark-light = { version = "0.2.1", optional = true } # detect dark mode system preference +glow = { version = "0.11", optional = true } serde = { version = "1.0", optional = true, features = ["derive"] } webbrowser = { version = "0.6", optional = true } diff --git a/egui-winit/src/epi.rs b/egui-winit/src/epi.rs index fd6711319fa..d257ca21edd 100644 --- a/egui-winit/src/epi.rs +++ b/egui-winit/src/epi.rs @@ -232,6 +232,7 @@ impl EpiIntegration { integration_name: &'static str, max_texture_side: usize, window: &winit::window::Window, + gl: &std::rc::Rc, repaint_signal: std::sync::Arc, persistence: crate::epi::Persistence, app: Box, @@ -271,7 +272,7 @@ impl EpiIntegration { can_drag_window: false, }; - slf.setup(window); + slf.setup(window, gl); if slf.app.warm_up_enabled() { slf.warm_up(window); } @@ -279,9 +280,9 @@ impl EpiIntegration { slf } - fn setup(&mut self, window: &winit::window::Window) { + fn setup(&mut self, window: &winit::window::Window, gl: &std::rc::Rc) { self.app - .setup(&self.egui_ctx, &self.frame, self.persistence.storage()); + .setup(&self.egui_ctx, &self.frame, self.persistence.storage(), gl); let app_output = self.frame.take_app_output(); if app_output.quit { diff --git a/egui_demo_lib/src/apps/demo/app.rs b/egui_demo_lib/src/apps/demo/app.rs index 063f29e751b..5544a51ad39 100644 --- a/egui_demo_lib/src/apps/demo/app.rs +++ b/egui_demo_lib/src/apps/demo/app.rs @@ -19,6 +19,7 @@ impl epi::App for DemoApp { _ctx: &egui::Context, _frame: &epi::Frame, _storage: Option<&dyn epi::Storage>, + _gl: &std::rc::Rc, ) { #[cfg(feature = "persistence")] if let Some(storage) = _storage { diff --git a/egui_demo_lib/src/wrap_app.rs b/egui_demo_lib/src/wrap_app.rs index ad752886bf6..0a1195978e9 100644 --- a/egui_demo_lib/src/wrap_app.rs +++ b/egui_demo_lib/src/wrap_app.rs @@ -47,6 +47,7 @@ impl epi::App for WrapApp { _ctx: &egui::Context, _frame: &epi::Frame, _storage: Option<&dyn epi::Storage>, + _gl: &std::rc::Rc, ) { #[cfg(feature = "persistence")] if let Some(storage) = _storage { diff --git a/egui_glow/Cargo.toml b/egui_glow/Cargo.toml index aa6ed64835b..924210a1eb9 100644 --- a/egui_glow/Cargo.toml +++ b/egui_glow/Cargo.toml @@ -69,7 +69,7 @@ tracing = "0.1" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] egui-winit = { version = "0.17.0", path = "../egui-winit", optional = true, default-features = false, features = [ "dark-light", - "epi", + "epi_backend", ] } glutin = { version = "0.28.0", optional = true } diff --git a/egui_glow/src/epi_backend.rs b/egui_glow/src/epi_backend.rs index 60b0c54cb3d..bbf8755066a 100644 --- a/egui_glow/src/epi_backend.rs +++ b/egui_glow/src/epi_backend.rs @@ -66,6 +66,7 @@ pub fn run(app: Box, native_options: &epi::NativeOptions) -> ! { "egui_glow", painter.max_texture_side(), gl_window.window(), + &gl, repaint_signal, persistence, app, diff --git a/egui_web/src/backend.rs b/egui_web/src/backend.rs index c50f0660984..0da078cf7e7 100644 --- a/egui_web/src/backend.rs +++ b/egui_web/src/backend.rs @@ -193,11 +193,10 @@ impl AppRunner { runner.input.raw.max_texture_side = Some(runner.painter.max_texture_side()); - { - runner - .app - .setup(&runner.egui_ctx, &runner.frame, Some(&runner.storage)); - } + let gl = runner.painter.painter.gl(); + runner + .app + .setup(&runner.egui_ctx, &runner.frame, Some(&runner.storage), gl); Ok(runner) } diff --git a/epi/Cargo.toml b/epi/Cargo.toml index 398e426cedd..4e894a62114 100644 --- a/epi/Cargo.toml +++ b/epi/Cargo.toml @@ -31,6 +31,7 @@ persistence = ["ron", "serde", "egui/persistence"] egui = { version = "0.17.0", path = "../egui", default-features = false, features = [ "single_threaded", ] } +glow = "0.11" tracing = "0.1" directories-next = { version = "2", optional = true } diff --git a/epi/src/lib.rs b/epi/src/lib.rs index 88171aaac84..033a4a7880c 100644 --- a/epi/src/lib.rs +++ b/epi/src/lib.rs @@ -94,6 +94,7 @@ pub mod file_storage; pub use egui; // Re-export for user convenience +pub use glow; // Re-export for user convenience use std::sync::{Arc, Mutex}; @@ -112,13 +113,23 @@ pub trait App { /// or call [`Frame::request_repaint`] at any time (e.g. from another thread). fn update(&mut self, ctx: &egui::Context, frame: &Frame); - /// Called once before the first frame. + /// Called exactly once at startup, before any call to [`Self::update`]. /// /// Allows you to do setup code, e.g to call [`egui::Context::set_fonts`], /// [`egui::Context::set_visuals`] etc. /// - /// Also allows you to restore state, if there is a storage (required the "persistence" feature). - fn setup(&mut self, _ctx: &egui::Context, _frame: &Frame, _storage: Option<&dyn Storage>) {} + /// Also allows you to restore state, if there is a storage (requires the "persistence" feature). + /// + /// The [`glow::Context`] allows you to initialize OpenGL resources (e.g. shaders) that + /// you might want to use later from a [`egui::PaintCallback`]. + fn setup( + &mut self, + _ctx: &egui::Context, + _frame: &Frame, + _storage: Option<&dyn Storage>, + _gl: &std::rc::Rc, + ) { + } /// Called on shutdown, and perhaps at regular intervals. Allows you to save state. ///