From a9fd03709ea47ca97e803937be6160fca8318f77 Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 23 Mar 2022 11:13:57 +0100 Subject: [PATCH] Add new NativeOptions: vsync multisampling depth_buffer stencil_buffer These are useful when embedding 3D into eframe. --- CHANGELOG.md | 2 +- eframe/CHANGELOG.md | 1 + eframe/examples/custom_3d_glow.rs | 18 +++++++++-------- eframe/examples/custom_3d_three-d.rs | 3 ++- egui-winit/src/epi.rs | 4 ++++ egui_glow/CHANGELOG.md | 2 ++ egui_glow/src/epi_backend.rs | 12 ++++++----- epi/src/lib.rs | 30 ++++++++++++++++++++++++++++ 8 files changed, 57 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08a352ab..9dbbcd0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ NOTE: [`epaint`](epaint/CHANGELOG.md), [`eframe`](eframe/CHANGELOG.md), [`egui_w ## Unreleased ### Added ⭐ -* Added `Shape::Callback` for backend-specific painting ([#1351](https://github.com/emilk/egui/pull/1351)). +* Added `Shape::Callback` for backend-specific painting, [with an example](https://github.com/emilk/egui/blob/master/eframe/examples/custom_3d_three-d.rs) ([#1351](https://github.com/emilk/egui/pull/1351)). * Added `Frame::canvas` ([#1362](https://github.com/emilk/egui/pull/1362)). * `Context::request_repaint` will wake up UI thread, if integrations has called `Context::set_request_repaint_callback` ([#1366](https://github.com/emilk/egui/pull/1366)). * Added `Ui::push_id` ([#1374](https://github.com/emilk/egui/pull/1374)). diff --git a/eframe/CHANGELOG.md b/eframe/CHANGELOG.md index a03be5de..580fc090 100644 --- a/eframe/CHANGELOG.md +++ b/eframe/CHANGELOG.md @@ -9,6 +9,7 @@ NOTE: [`egui_web`](../egui_web/CHANGELOG.md), [`egui-winit`](../egui-winit/CHANG * Remove the `egui_glium` feature. `eframe` will now always use `egui_glow` as the native backend ([#1357](https://github.com/emilk/egui/pull/1357)). * Removed `Frame::request_repaint` - just call `egui::Context::request_repaint` for the same effect ([#1366](https://github.com/emilk/egui/pull/1366)). * Use full browser width by default ([#1378](https://github.com/emilk/egui/pull/1378)). +* Add new `NativeOptions`: `vsync`, `multisampling`, `depth_buffer`, `stencil_buffer`. ## 0.17.0 - 2022-02-22 diff --git a/eframe/examples/custom_3d_glow.rs b/eframe/examples/custom_3d_glow.rs index f352367f..20b3d3cd 100644 --- a/eframe/examples/custom_3d_glow.rs +++ b/eframe/examples/custom_3d_glow.rs @@ -18,9 +18,13 @@ use egui::mutex::Mutex; use std::sync::Arc; fn main() { - let options = eframe::NativeOptions::default(); + let options = eframe::NativeOptions { + initial_window_size: Some(egui::vec2(350.0, 380.0)), + multisampling: 8, + ..Default::default() + }; eframe::run_native( - "Custom 3D painting in eframe", + "Custom 3D painting in eframe using glow", options, Box::new(|cc| Box::new(MyApp::new(cc))), ); @@ -51,12 +55,10 @@ impl eframe::App for MyApp { ui.label(" (OpenGL)."); }); - egui::ScrollArea::both().show(ui, |ui| { - egui::Frame::canvas(ui.style()).show(ui, |ui| { - self.custom_painting(ui); - }); - ui.label("Drag to rotate!"); + egui::Frame::canvas(ui.style()).show(ui, |ui| { + self.custom_painting(ui); }); + ui.label("Drag to rotate!"); }); } @@ -68,7 +70,7 @@ impl eframe::App for MyApp { impl MyApp { fn custom_painting(&mut self, ui: &mut egui::Ui) { let (rect, response) = - ui.allocate_exact_size(egui::Vec2::splat(256.0), egui::Sense::drag()); + ui.allocate_exact_size(egui::Vec2::splat(300.0), egui::Sense::drag()); self.angle += response.drag_delta().x * 0.01; diff --git a/eframe/examples/custom_3d_three-d.rs b/eframe/examples/custom_3d_three-d.rs index 606560ce..5be84631 100644 --- a/eframe/examples/custom_3d_three-d.rs +++ b/eframe/examples/custom_3d_three-d.rs @@ -16,6 +16,7 @@ use eframe::egui; fn main() { let options = eframe::NativeOptions { initial_window_size: Some(egui::vec2(550.0, 610.0)), + multisampling: 8, ..Default::default() }; eframe::run_native( @@ -31,7 +32,7 @@ struct MyApp { impl MyApp { fn new(_cc: &eframe::CreationContext<'_>) -> Self { - Self { angle: 0.0 } + Self { angle: 0.2 } } } diff --git a/egui-winit/src/epi.rs b/egui-winit/src/epi.rs index 2674db33..1a82de17 100644 --- a/egui-winit/src/epi.rs +++ b/egui-winit/src/epi.rs @@ -21,6 +21,10 @@ pub fn window_builder( max_window_size, resizable, transparent, + vsync: _, // used in `fn create_display` + multisampling: _, // used in `fn create_display` + depth_buffer: _, // used in `fn create_display` + stencil_buffer: _, // used in `fn create_display` } = native_options; let window_icon = icon_data.clone().and_then(load_icon); diff --git a/egui_glow/CHANGELOG.md b/egui_glow/CHANGELOG.md index 0c470c64..60aa349e 100644 --- a/egui_glow/CHANGELOG.md +++ b/egui_glow/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to the `egui_glow` integration will be noted in this file. ## Unreleased +* Improved logging on rendering failures. +* Add new `NativeOptions`: `vsync`, `multisampling`, `depth_buffer`, `stencil_buffer`. ## 0.17.0 - 2022-02-22 diff --git a/egui_glow/src/epi_backend.rs b/egui_glow/src/epi_backend.rs index 2e16e7ae..3d74a956 100644 --- a/egui_glow/src/epi_backend.rs +++ b/egui_glow/src/epi_backend.rs @@ -5,6 +5,7 @@ struct RequestRepaintEvent; #[allow(unsafe_code)] fn create_display( + native_options: &NativeOptions, window_builder: winit::window::WindowBuilder, event_loop: &winit::event_loop::EventLoop, ) -> ( @@ -13,10 +14,11 @@ fn create_display( ) { let gl_window = unsafe { glutin::ContextBuilder::new() - .with_depth_buffer(0) - .with_srgb(true) - .with_stencil_buffer(0) - .with_vsync(true) + .with_depth_buffer(native_options.depth_buffer) + .with_multisampling(native_options.multisampling) + .with_srgb(native_options.vsync) + .with_stencil_buffer(native_options.stencil_buffer) + .with_vsync(native_options.vsync) .build_windowed(window_builder, event_loop) .unwrap() .make_current() @@ -40,7 +42,7 @@ pub fn run(app_name: &str, native_options: &epi::NativeOptions, app_creator: epi let window_builder = egui_winit::epi::window_builder(native_options, &window_settings).with_title(app_name); let event_loop = winit::event_loop::EventLoop::with_user_event(); - let (gl_window, gl) = create_display(window_builder, &event_loop); + let (gl_window, gl) = create_display(native_options, window_builder, &event_loop); let gl = std::rc::Rc::new(gl); let mut painter = crate::Painter::new(gl.clone(), None, "") diff --git a/epi/src/lib.rs b/epi/src/lib.rs index 9359ccca..dac19301 100644 --- a/epi/src/lib.rs +++ b/epi/src/lib.rs @@ -183,6 +183,32 @@ pub struct NativeOptions { /// You control the transparency with [`App::clear_color()`]. /// You should avoid having a [`egui::CentralPanel`], or make sure its frame is also transparent. pub transparent: bool, + + /// Turn on vertical syncing, limiting the FPS to the display refresh rate. + /// + /// The default is `true`. + pub vsync: bool, + + /// Set the level of the multisampling anti-aliasing (MSAA). + /// + /// Must be a power-of-two. Higher = more smooth 3D. + /// + /// A value of `0` turns it off (default). + /// + /// `egui` already performs anti-aliasing via "feathering" + /// (controlled by [`egui::epaint::TessellationOptions`]), + /// but if you are embedding 3D in egui you may want to turn on multisampling. + pub multisampling: u16, + + /// Sets the number of bits in the depth buffer. + /// + /// `egui` doesn't need the depth buffer, so the default value is 0. + pub depth_buffer: u8, + + /// Sets the number of bits in the stencil buffer. + /// + /// `egui` doesn't need the stencil buffer, so the default value is 0. + pub stencil_buffer: u8, } impl Default for NativeOptions { @@ -199,6 +225,10 @@ impl Default for NativeOptions { max_window_size: None, resizable: true, transparent: false, + vsync: true, + multisampling: 0, + depth_buffer: 0, + stencil_buffer: 0, } } }