From 0154fe729d98fd01973a041903483d0362124e8c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 12 Oct 2022 13:37:53 +0200 Subject: [PATCH 01/10] Simplify struct name --- crates/fj-viewer/src/graphics/renderer.rs | 6 +++--- crates/fj-viewer/src/gui.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/fj-viewer/src/graphics/renderer.rs b/crates/fj-viewer/src/graphics/renderer.rs index 0b78bbe5e..8e52a5b6e 100644 --- a/crates/fj-viewer/src/graphics/renderer.rs +++ b/crates/fj-viewer/src/graphics/renderer.rs @@ -9,7 +9,7 @@ use wgpu_glyph::ab_glyph::InvalidFont; use crate::{ camera::Camera, - gui::EguiState, + gui::Gui, screen::{Screen, Size}, }; @@ -37,7 +37,7 @@ pub struct Renderer { pipelines: Pipelines, /// State required for integration with `egui`. - pub egui: EguiState, + pub egui: Gui, } impl Renderer { @@ -151,7 +151,7 @@ impl Renderer { let pipelines = Pipelines::new(&device, &bind_group_layout, color_format); - let egui = EguiState::new(&device, surface_config.format); + let egui = Gui::new(&device, surface_config.format); Ok(Self { surface, diff --git a/crates/fj-viewer/src/gui.rs b/crates/fj-viewer/src/gui.rs index 102fbab82..3d9e5fe35 100644 --- a/crates/fj-viewer/src/gui.rs +++ b/crates/fj-viewer/src/gui.rs @@ -23,13 +23,13 @@ pub struct EguiOptionsState { pub show_inspection_ui: bool, } -pub struct EguiState { +pub struct Gui { pub context: egui::Context, pub render_pass: egui_wgpu::renderer::RenderPass, pub options: EguiOptionsState, } -impl EguiState { +impl Gui { pub fn new( device: &wgpu::Device, texture_format: wgpu::TextureFormat, @@ -76,7 +76,7 @@ impl EguiState { } } -impl std::fmt::Debug for EguiState { +impl std::fmt::Debug for Gui { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str("EguiState {}") } From 0d587924c06b90d025ecd71cdddc1f1614181347 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 12 Oct 2022 13:38:20 +0200 Subject: [PATCH 02/10] Simplify struct name --- crates/fj-viewer/src/gui.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/fj-viewer/src/gui.rs b/crates/fj-viewer/src/gui.rs index 3d9e5fe35..ba9db562b 100644 --- a/crates/fj-viewer/src/gui.rs +++ b/crates/fj-viewer/src/gui.rs @@ -15,7 +15,7 @@ //! #[derive(Default)] -pub struct EguiOptionsState { +pub struct Options { pub show_trace: bool, pub show_layout_debug_on_hover: bool, pub show_debug_text_example: bool, @@ -26,7 +26,7 @@ pub struct EguiOptionsState { pub struct Gui { pub context: egui::Context, pub render_pass: egui_wgpu::renderer::RenderPass, - pub options: EguiOptionsState, + pub options: Options, } impl Gui { From 9d0b1ff55172f1fd004d9c93c68e3a1bd32bab40 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 12 Oct 2022 13:38:36 +0200 Subject: [PATCH 03/10] Update order of code Important stuff first, secondary stuff used by the important stuff second. --- crates/fj-viewer/src/gui.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/fj-viewer/src/gui.rs b/crates/fj-viewer/src/gui.rs index ba9db562b..a3cea286a 100644 --- a/crates/fj-viewer/src/gui.rs +++ b/crates/fj-viewer/src/gui.rs @@ -14,15 +14,6 @@ //! //! -#[derive(Default)] -pub struct Options { - pub show_trace: bool, - pub show_layout_debug_on_hover: bool, - pub show_debug_text_example: bool, - pub show_settings_ui: bool, - pub show_inspection_ui: bool, -} - pub struct Gui { pub context: egui::Context, pub render_pass: egui_wgpu::renderer::RenderPass, @@ -81,3 +72,12 @@ impl std::fmt::Debug for Gui { f.write_str("EguiState {}") } } + +#[derive(Default)] +pub struct Options { + pub show_trace: bool, + pub show_layout_debug_on_hover: bool, + pub show_debug_text_example: bool, + pub show_settings_ui: bool, + pub show_inspection_ui: bool, +} From afc981e15da993ae3c5fad54d898183e45a226ba Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 12 Oct 2022 13:39:46 +0200 Subject: [PATCH 04/10] Simplify struct field name --- crates/fj-viewer/src/graphics/renderer.rs | 52 +++++++++++------------ crates/fj-window/src/run.rs | 2 +- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/crates/fj-viewer/src/graphics/renderer.rs b/crates/fj-viewer/src/graphics/renderer.rs index 8e52a5b6e..e4c35b453 100644 --- a/crates/fj-viewer/src/graphics/renderer.rs +++ b/crates/fj-viewer/src/graphics/renderer.rs @@ -37,7 +37,7 @@ pub struct Renderer { pipelines: Pipelines, /// State required for integration with `egui`. - pub egui: Gui, + pub gui: Gui, } impl Renderer { @@ -151,7 +151,7 @@ impl Renderer { let pipelines = Pipelines::new(&device, &bind_group_layout, color_format); - let egui = Gui::new(&device, surface_config.format); + let gui = Gui::new(&device, surface_config.format); Ok(Self { surface, @@ -168,7 +168,7 @@ impl Renderer { geometries, pipelines, - egui, + gui, }) } @@ -275,7 +275,7 @@ impl Renderer { } } - self.egui.context.begin_frame(egui_input); + self.gui.context.begin_frame(egui_input); fn get_bbox_size_text(aabb: &Aabb<3>) -> String { /* Render size of model bounding box */ @@ -291,7 +291,7 @@ impl Renderer { let line_drawing_available = self.is_line_drawing_available(); - egui::SidePanel::left("fj-left-panel").show(&self.egui.context, |ui| { + egui::SidePanel::left("fj-left-panel").show(&self.gui.context, |ui| { ui.add_space(16.0); ui.group(|ui| { @@ -316,11 +316,11 @@ impl Renderer { { ui.group(|ui| { ui.checkbox( - &mut self.egui.options.show_settings_ui, + &mut self.gui.options.show_settings_ui, "Show egui settings UI", ); - if self.egui.options.show_settings_ui { - self.egui.context.settings_ui(ui); + if self.gui.options.show_settings_ui { + self.gui.context.settings_ui(ui); } }); @@ -328,12 +328,12 @@ impl Renderer { ui.group(|ui| { ui.checkbox( - &mut self.egui.options.show_inspection_ui, + &mut self.gui.options.show_inspection_ui, "Show egui inspection UI", ); - if self.egui.options.show_inspection_ui { + if self.gui.options.show_inspection_ui { ui.indent("indent-inspection-ui", |ui| { - self.egui.context.inspection_ui(ui); + self.gui.context.inspection_ui(ui); }); } }); @@ -356,7 +356,7 @@ impl Renderer { ui.group(|ui| { let label_text = format!( "Show debug text demo.{}", - if self.egui.options.show_debug_text_example { + if self.gui.options.show_debug_text_example { " (Hover me.)" } else { "" @@ -367,11 +367,11 @@ impl Renderer { if ui .checkbox( - &mut self.egui.options.show_debug_text_example, + &mut self.gui.options.show_debug_text_example, label_text, ) .hovered() - && self.egui.options.show_debug_text_example + && self.gui.options.show_debug_text_example { let hover_pos = ui.input().pointer.hover_pos().unwrap_or_default(); @@ -396,29 +396,29 @@ impl Renderer { if ui .checkbox( - &mut self.egui.options.show_layout_debug_on_hover, + &mut self.gui.options.show_layout_debug_on_hover, "Show layout debug on hover.", ) .changed() { ui.ctx().set_debug_on_hover( - self.egui.options.show_layout_debug_on_hover, + self.gui.options.show_layout_debug_on_hover, ); } ui.scope(|ui| { - if self.egui.options.show_trace { + if self.gui.options.show_trace { egui::trace!(ui, format!("{:?}", &config)); } }); ui.indent("indent-show-trace", |ui| { ui.set_enabled( - self.egui.options.show_layout_debug_on_hover, + self.gui.options.show_layout_debug_on_hover, ); ui.checkbox( - &mut self.egui.options.show_trace, + &mut self.gui.options.show_trace, "Also show egui trace.", ); @@ -430,7 +430,7 @@ impl Renderer { ui.add_space(16.0); }); - egui::Area::new("fj-status-message").show(&self.egui.context, |ui| { + egui::Area::new("fj-status-message").show(&self.gui.context, |ui| { ui.group(|ui| { ui.add(egui::Label::new( egui::RichText::new(format!("Status:{}", status.status())) @@ -440,8 +440,8 @@ impl Renderer { }); // End the UI frame. We could now handle the output and draw the UI with the backend. - let egui_output = self.egui.context.end_frame(); - let egui_paint_jobs = self.egui.context.tessellate(egui_output.shapes); + let egui_output = self.gui.context.end_frame(); + let egui_paint_jobs = self.gui.context.tessellate(egui_output.shapes); self.paint_and_update_textures( // @@ -603,7 +603,7 @@ impl Renderer { }; for (id, image_delta) in &textures_delta.set { - self.egui.render_pass.update_texture( + self.gui.render_pass.update_texture( &self.device, &self.queue, *id, @@ -611,10 +611,10 @@ impl Renderer { ); } for id in &textures_delta.free { - self.egui.render_pass.free_texture(id); + self.gui.render_pass.free_texture(id); } - self.egui.render_pass.update_buffers( + self.gui.render_pass.update_buffers( &self.device, &self.queue, clipped_primitives, @@ -645,7 +645,7 @@ impl Renderer { }; // Record all render passes. - self.egui.render_pass.execute( + self.gui.render_pass.execute( encoder, output_view, clipped_primitives, diff --git a/crates/fj-window/src/run.rs b/crates/fj-window/src/run.rs index 2c01cfac1..2988fedfd 100644 --- a/crates/fj-window/src/run.rs +++ b/crates/fj-window/src/run.rs @@ -105,7 +105,7 @@ pub fn run( // The primary visible impact of this currently is that if you drag // a title bar that overlaps the model then both the model & window // get moved. - egui_winit_state.on_event(&renderer.egui.context, window_event); + egui_winit_state.on_event(&renderer.gui.context, window_event); } // fj-window events From 502258afae8bbf2564f83b56177e49a392f2cef2 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 12 Oct 2022 13:49:26 +0200 Subject: [PATCH 05/10] Remove redundant code --- crates/fj-viewer/src/graphics/renderer.rs | 27 +---------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/crates/fj-viewer/src/graphics/renderer.rs b/crates/fj-viewer/src/graphics/renderer.rs index e4c35b453..27d548c47 100644 --- a/crates/fj-viewer/src/graphics/renderer.rs +++ b/crates/fj-viewer/src/graphics/renderer.rs @@ -449,7 +449,6 @@ impl Renderer { // see: // scale_factor, - egui::Rgba::TRANSPARENT, &egui_paint_jobs, &egui_output.textures_delta, &color_view, @@ -587,7 +586,6 @@ impl Renderer { fn paint_and_update_textures( &mut self, pixels_per_point: f32, - clear_color: egui::Rgba, clipped_primitives: &[egui::ClippedPrimitive], textures_delta: &egui::TexturesDelta, output_view: &wgpu::TextureView, @@ -621,36 +619,13 @@ impl Renderer { &screen_descriptor, ); - // - // This approach is based on the original proof-of-concept - // integration which used `egui_wgpu_backend` and included - // the following comment for context: - // - // "Set this to `None` to overlay the UI on top of what's in the framebuffer" - // via - // - // Alternatively, for initial testing, you can use a colour without alpha - // (e.g. `Some(wgpu::Color {r:0.5, g:0.0, b:0.0, a:1.0})` ) in order - // to verify that the renderpass is doing *something*. - // - let clear_color_ = if clear_color == egui::Rgba::TRANSPARENT { - None - } else { - Some(wgpu::Color { - r: clear_color.r() as f64, - g: clear_color.g() as f64, - b: clear_color.b() as f64, - a: clear_color.a() as f64, - }) - }; - // Record all render passes. self.gui.render_pass.execute( encoder, output_view, clipped_primitives, &screen_descriptor, - clear_color_, + None, ); } } From 6a45b40d23eee02d94bae4992ead86441ca68a7e Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 12 Oct 2022 13:50:00 +0200 Subject: [PATCH 06/10] Remove comments --- crates/fj-viewer/src/graphics/renderer.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/fj-viewer/src/graphics/renderer.rs b/crates/fj-viewer/src/graphics/renderer.rs index 27d548c47..fef7cb783 100644 --- a/crates/fj-viewer/src/graphics/renderer.rs +++ b/crates/fj-viewer/src/graphics/renderer.rs @@ -591,7 +591,6 @@ impl Renderer { output_view: &wgpu::TextureView, encoder: &mut wgpu::CommandEncoder, ) { - // Upload all resources for the GPU. let screen_descriptor = egui_wgpu::renderer::ScreenDescriptor { size_in_pixels: [ self.surface_config.width, @@ -619,7 +618,6 @@ impl Renderer { &screen_descriptor, ); - // Record all render passes. self.gui.render_pass.execute( encoder, output_view, From 379c66704ad87cbb1f3cf532d9f14ea291ed9b16 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 12 Oct 2022 13:58:54 +0200 Subject: [PATCH 07/10] Add `Gui::draw` --- crates/fj-viewer/src/graphics/renderer.rs | 92 +++-------------------- crates/fj-viewer/src/gui.rs | 35 +++++++++ 2 files changed, 46 insertions(+), 81 deletions(-) diff --git a/crates/fj-viewer/src/graphics/renderer.rs b/crates/fj-viewer/src/graphics/renderer.rs index fef7cb783..49c6f38f8 100644 --- a/crates/fj-viewer/src/graphics/renderer.rs +++ b/crates/fj-viewer/src/graphics/renderer.rs @@ -439,20 +439,18 @@ impl Renderer { }) }); - // End the UI frame. We could now handle the output and draw the UI with the backend. - let egui_output = self.gui.context.end_frame(); - let egui_paint_jobs = self.gui.context.tessellate(egui_output.shapes); - - self.paint_and_update_textures( - // - // Note: `scale_factor` can be overridden via `WINIT_X11_SCALE_FACTOR` environment variable, - // see: - // - scale_factor, - &egui_paint_jobs, - &egui_output.textures_delta, - &color_view, + self.gui.draw( + &self.device, + &self.queue, &mut encoder, + &color_view, + egui_wgpu::renderer::ScreenDescriptor { + size_in_pixels: [ + self.surface_config.width, + self.surface_config.height, + ], + pixels_per_point: scale_factor, + }, ); let command_buffer = encoder.finish(); @@ -559,71 +557,3 @@ pub enum DrawError { #[error("Error drawing text: {0}")] Text(String), } - -impl Renderer { - // - // Note: `egui` changed how it handles updating textures on - // the GPU between v0.17.0 & v0.18.0, this means we can't - // use the same approach as original proof-of-concept used. - // - // Unfortunately we can't use the helper function provided - // by `egui` here, as it is tightly integrated with `Painter` - // which assumes it is handling surface creation itself. - // - // Additionally, subsequent code changes significantly - // changed the API but haven't yet been released. - // - // And, to top it all off, the `Painter::paint_and_update_textures()` - // as it currently exists doesn't support a transparent - // clear color, which we rely on to overlay the UI on the - // already rendered model. - // - // So, as an interim measure, this code is a copy of the - // texture update code from . - // - // Update: Added transparency workaround. - // - fn paint_and_update_textures( - &mut self, - pixels_per_point: f32, - clipped_primitives: &[egui::ClippedPrimitive], - textures_delta: &egui::TexturesDelta, - output_view: &wgpu::TextureView, - encoder: &mut wgpu::CommandEncoder, - ) { - let screen_descriptor = egui_wgpu::renderer::ScreenDescriptor { - size_in_pixels: [ - self.surface_config.width, - self.surface_config.height, - ], - pixels_per_point, - }; - - for (id, image_delta) in &textures_delta.set { - self.gui.render_pass.update_texture( - &self.device, - &self.queue, - *id, - image_delta, - ); - } - for id in &textures_delta.free { - self.gui.render_pass.free_texture(id); - } - - self.gui.render_pass.update_buffers( - &self.device, - &self.queue, - clipped_primitives, - &screen_descriptor, - ); - - self.gui.render_pass.execute( - encoder, - output_view, - clipped_primitives, - &screen_descriptor, - None, - ); - } -} diff --git a/crates/fj-viewer/src/gui.rs b/crates/fj-viewer/src/gui.rs index a3cea286a..19898eac7 100644 --- a/crates/fj-viewer/src/gui.rs +++ b/crates/fj-viewer/src/gui.rs @@ -65,6 +65,41 @@ impl Gui { options: Default::default(), } } + + pub fn draw( + &mut self, + device: &wgpu::Device, + queue: &wgpu::Queue, + encoder: &mut wgpu::CommandEncoder, + color_view: &wgpu::TextureView, + screen_descriptor: egui_wgpu::renderer::ScreenDescriptor, + ) { + let egui_output = self.context.end_frame(); + let clipped_primitives = self.context.tessellate(egui_output.shapes); + + for (id, image_delta) in &egui_output.textures_delta.set { + self.render_pass + .update_texture(device, queue, *id, image_delta); + } + for id in &egui_output.textures_delta.free { + self.render_pass.free_texture(id); + } + + self.render_pass.update_buffers( + device, + queue, + &clipped_primitives, + &screen_descriptor, + ); + + self.render_pass.execute( + encoder, + color_view, + &clipped_primitives, + &screen_descriptor, + None, + ); + } } impl std::fmt::Debug for Gui { From c4b83be39c0f4a04b28798b7f0a686deac85ba5d Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 12 Oct 2022 14:09:28 +0200 Subject: [PATCH 08/10] Remove outdated comment --- crates/fj-viewer/src/graphics/renderer.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/fj-viewer/src/graphics/renderer.rs b/crates/fj-viewer/src/graphics/renderer.rs index 49c6f38f8..aaa8b9e61 100644 --- a/crates/fj-viewer/src/graphics/renderer.rs +++ b/crates/fj-viewer/src/graphics/renderer.rs @@ -254,8 +254,6 @@ impl Renderer { ); } - // NOTE: This does not inform the user if the renderer cannot - // use the POLYGON_MODE_LINE feature. if self.features.contains(wgpu::Features::POLYGON_MODE_LINE) { if config.draw_mesh { drawables.mesh.draw( From e94372c02653b443563b8854694c3972b7503dab Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 12 Oct 2022 14:10:05 +0200 Subject: [PATCH 09/10] Consolidate duplicated code --- crates/fj-viewer/src/graphics/renderer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fj-viewer/src/graphics/renderer.rs b/crates/fj-viewer/src/graphics/renderer.rs index aaa8b9e61..5c77b1ee1 100644 --- a/crates/fj-viewer/src/graphics/renderer.rs +++ b/crates/fj-viewer/src/graphics/renderer.rs @@ -254,7 +254,7 @@ impl Renderer { ); } - if self.features.contains(wgpu::Features::POLYGON_MODE_LINE) { + if self.is_line_drawing_available() { if config.draw_mesh { drawables.mesh.draw( &mut encoder, From 3ee3404f09ed15e0f2dbd2a52d51b417c3f0e566 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Wed, 12 Oct 2022 14:19:45 +0200 Subject: [PATCH 10/10] Add `Gui::update` --- crates/fj-viewer/src/graphics/renderer.rs | 171 +-------------------- crates/fj-viewer/src/gui.rs | 176 ++++++++++++++++++++++ 2 files changed, 183 insertions(+), 164 deletions(-) diff --git a/crates/fj-viewer/src/graphics/renderer.rs b/crates/fj-viewer/src/graphics/renderer.rs index 5c77b1ee1..f79c507e0 100644 --- a/crates/fj-viewer/src/graphics/renderer.rs +++ b/crates/fj-viewer/src/graphics/renderer.rs @@ -273,170 +273,13 @@ impl Renderer { } } - self.gui.context.begin_frame(egui_input); - - fn get_bbox_size_text(aabb: &Aabb<3>) -> String { - /* Render size of model bounding box */ - let bbsize = aabb.size().components; - let info = format!( - "Model bounding box size:\n{:0.1} {:0.1} {:0.1}", - bbsize[0].into_f32(), - bbsize[1].into_f32(), - bbsize[2].into_f32() - ); - info - } - - let line_drawing_available = self.is_line_drawing_available(); - - egui::SidePanel::left("fj-left-panel").show(&self.gui.context, |ui| { - ui.add_space(16.0); - - ui.group(|ui| { - ui.checkbox(&mut config.draw_model, "Render model") - .on_hover_text_at_pointer("Toggle with 1"); - ui.add_enabled(line_drawing_available, egui::Checkbox::new(&mut config.draw_mesh, "Render mesh")) - .on_hover_text_at_pointer("Toggle with 2") - .on_disabled_hover_text( - "Rendering device does not have line rendering feature support", - ); - ui.add_enabled(line_drawing_available, egui::Checkbox::new(&mut config.draw_debug, "Render debug")) - .on_hover_text_at_pointer("Toggle with 3") - .on_disabled_hover_text( - "Rendering device does not have line rendering feature support" - ); - ui.add_space(16.0); - ui.strong(get_bbox_size_text(&self.geometries.aabb)); - }); - - ui.add_space(16.0); - - { - ui.group(|ui| { - ui.checkbox( - &mut self.gui.options.show_settings_ui, - "Show egui settings UI", - ); - if self.gui.options.show_settings_ui { - self.gui.context.settings_ui(ui); - } - }); - - ui.add_space(16.0); - - ui.group(|ui| { - ui.checkbox( - &mut self.gui.options.show_inspection_ui, - "Show egui inspection UI", - ); - if self.gui.options.show_inspection_ui { - ui.indent("indent-inspection-ui", |ui| { - self.gui.context.inspection_ui(ui); - }); - } - }); - } - - ui.add_space(16.0); - - { - // - // Originally this was only meant to be a simple demonstration - // of the `egui` `trace!()` macro... - // - // ...but it seems the trace feature can't be enabled - // separately from the layout debug feature, which all - // gets a bit messy... - // - // ...so, this instead shows one possible way to implement - // "trace only" style debug text on hover. - // - ui.group(|ui| { - let label_text = format!( - "Show debug text demo.{}", - if self.gui.options.show_debug_text_example { - " (Hover me.)" - } else { - "" - } - ); - - ui.style_mut().wrap = Some(false); - - if ui - .checkbox( - &mut self.gui.options.show_debug_text_example, - label_text, - ) - .hovered() - && self.gui.options.show_debug_text_example - { - let hover_pos = - ui.input().pointer.hover_pos().unwrap_or_default(); - ui.painter().debug_text( - hover_pos, - egui::Align2::LEFT_TOP, - egui::Color32::DEBUG_COLOR, - format!("{:#?}", &config), - ); - } - }); - } - - ui.add_space(16.0); - - { - // - // Demonstration of the `egui` layout debug functionality. - // - ui.group(|ui| { - // - - if ui - .checkbox( - &mut self.gui.options.show_layout_debug_on_hover, - "Show layout debug on hover.", - ) - .changed() - { - ui.ctx().set_debug_on_hover( - self.gui.options.show_layout_debug_on_hover, - ); - } - - ui.scope(|ui| { - if self.gui.options.show_trace { - egui::trace!(ui, format!("{:?}", &config)); - } - }); - - ui.indent("indent-show-trace", |ui| { - ui.set_enabled( - self.gui.options.show_layout_debug_on_hover, - ); - - ui.checkbox( - &mut self.gui.options.show_trace, - "Also show egui trace.", - ); - - // - }); - }); - } - - ui.add_space(16.0); - }); - - egui::Area::new("fj-status-message").show(&self.gui.context, |ui| { - ui.group(|ui| { - ui.add(egui::Label::new( - egui::RichText::new(format!("Status:{}", status.status())) - .color(egui::Color32::BLACK), - )) - }) - }); - + self.gui.update( + egui_input, + config, + &self.geometries.aabb, + status, + self.is_line_drawing_available(), + ); self.gui.draw( &self.device, &self.queue, diff --git a/crates/fj-viewer/src/gui.rs b/crates/fj-viewer/src/gui.rs index 19898eac7..eac9fa28f 100644 --- a/crates/fj-viewer/src/gui.rs +++ b/crates/fj-viewer/src/gui.rs @@ -14,6 +14,11 @@ //! //! +use fj_interop::status_report::StatusReport; +use fj_math::Aabb; + +use crate::graphics::DrawConfig; + pub struct Gui { pub context: egui::Context, pub render_pass: egui_wgpu::renderer::RenderPass, @@ -66,6 +71,177 @@ impl Gui { } } + pub fn update( + &mut self, + egui_input: egui::RawInput, + config: &mut DrawConfig, + aabb: &Aabb<3>, + status: &StatusReport, + line_drawing_available: bool, + ) { + self.context.begin_frame(egui_input); + + fn get_bbox_size_text(aabb: &Aabb<3>) -> String { + /* Render size of model bounding box */ + let bbsize = aabb.size().components; + let info = format!( + "Model bounding box size:\n{:0.1} {:0.1} {:0.1}", + bbsize[0].into_f32(), + bbsize[1].into_f32(), + bbsize[2].into_f32() + ); + info + } + + egui::SidePanel::left("fj-left-panel").show(&self.context, |ui| { + ui.add_space(16.0); + + ui.group(|ui| { + ui.checkbox(&mut config.draw_model, "Render model") + .on_hover_text_at_pointer("Toggle with 1"); + ui.add_enabled(line_drawing_available, egui::Checkbox::new(&mut config.draw_mesh, "Render mesh")) + .on_hover_text_at_pointer("Toggle with 2") + .on_disabled_hover_text( + "Rendering device does not have line rendering feature support", + ); + ui.add_enabled(line_drawing_available, egui::Checkbox::new(&mut config.draw_debug, "Render debug")) + .on_hover_text_at_pointer("Toggle with 3") + .on_disabled_hover_text( + "Rendering device does not have line rendering feature support" + ); + ui.add_space(16.0); + ui.strong(get_bbox_size_text(aabb)); + }); + + ui.add_space(16.0); + + { + ui.group(|ui| { + ui.checkbox( + &mut self.options.show_settings_ui, + "Show egui settings UI", + ); + if self.options.show_settings_ui { + self.context.settings_ui(ui); + } + }); + + ui.add_space(16.0); + + ui.group(|ui| { + ui.checkbox( + &mut self.options.show_inspection_ui, + "Show egui inspection UI", + ); + if self.options.show_inspection_ui { + ui.indent("indent-inspection-ui", |ui| { + self.context.inspection_ui(ui); + }); + } + }); + } + + ui.add_space(16.0); + + { + // + // Originally this was only meant to be a simple demonstration + // of the `egui` `trace!()` macro... + // + // ...but it seems the trace feature can't be enabled + // separately from the layout debug feature, which all + // gets a bit messy... + // + // ...so, this instead shows one possible way to implement + // "trace only" style debug text on hover. + // + ui.group(|ui| { + let label_text = format!( + "Show debug text demo.{}", + if self.options.show_debug_text_example { + " (Hover me.)" + } else { + "" + } + ); + + ui.style_mut().wrap = Some(false); + + if ui + .checkbox( + &mut self.options.show_debug_text_example, + label_text, + ) + .hovered() + && self.options.show_debug_text_example + { + let hover_pos = + ui.input().pointer.hover_pos().unwrap_or_default(); + ui.painter().debug_text( + hover_pos, + egui::Align2::LEFT_TOP, + egui::Color32::DEBUG_COLOR, + format!("{:#?}", &config), + ); + } + }); + } + + ui.add_space(16.0); + + { + // + // Demonstration of the `egui` layout debug functionality. + // + ui.group(|ui| { + // + + if ui + .checkbox( + &mut self.options.show_layout_debug_on_hover, + "Show layout debug on hover.", + ) + .changed() + { + ui.ctx().set_debug_on_hover( + self.options.show_layout_debug_on_hover, + ); + } + + ui.scope(|ui| { + if self.options.show_trace { + egui::trace!(ui, format!("{:?}", &config)); + } + }); + + ui.indent("indent-show-trace", |ui| { + ui.set_enabled( + self.options.show_layout_debug_on_hover, + ); + + ui.checkbox( + &mut self.options.show_trace, + "Also show egui trace.", + ); + + // + }); + }); + } + + ui.add_space(16.0); + }); + + egui::Area::new("fj-status-message").show(&self.context, |ui| { + ui.group(|ui| { + ui.add(egui::Label::new( + egui::RichText::new(format!("Status:{}", status.status())) + .color(egui::Color32::BLACK), + )) + }) + }); + } + pub fn draw( &mut self, device: &wgpu::Device,