mirror of https://github.com/hannobraun/Fornjot
Remove GUI code
This commit is contained in:
parent
2c3fad7744
commit
be5023bbb8
|
@ -6,7 +6,6 @@ use wgpu::util::DeviceExt as _;
|
|||
|
||||
use crate::{
|
||||
camera::Camera,
|
||||
gui::Gui,
|
||||
screen::{Screen, ScreenSize},
|
||||
};
|
||||
|
||||
|
@ -213,10 +212,6 @@ impl Renderer {
|
|||
})
|
||||
}
|
||||
|
||||
pub(crate) fn init_gui(&self) -> Gui {
|
||||
Gui::new(&self.device, self.surface_config.format)
|
||||
}
|
||||
|
||||
/// Updates the geometry of the model being rendered.
|
||||
pub fn update_geometry(&mut self, mesh: Vertices, lines: Vertices) {
|
||||
self.geometries = Geometries::new(&self.device, &mesh, &lines);
|
||||
|
@ -243,8 +238,6 @@ impl Renderer {
|
|||
&mut self,
|
||||
camera: &Camera,
|
||||
config: &DrawConfig,
|
||||
scale_factor: f32,
|
||||
gui: &mut Gui,
|
||||
) -> Result<(), DrawError> {
|
||||
let aspect_ratio = f64::from(self.surface_config.width)
|
||||
/ f64::from(self.surface_config.height);
|
||||
|
@ -281,20 +274,6 @@ impl Renderer {
|
|||
&wgpu::CommandEncoderDescriptor { label: None },
|
||||
);
|
||||
|
||||
let screen_descriptor = egui_wgpu::renderer::ScreenDescriptor {
|
||||
size_in_pixels: [
|
||||
self.surface_config.width,
|
||||
self.surface_config.height,
|
||||
],
|
||||
pixels_per_point: scale_factor,
|
||||
};
|
||||
let clipped_primitives = gui.prepare_draw(
|
||||
&self.device,
|
||||
&self.queue,
|
||||
&mut encoder,
|
||||
&screen_descriptor,
|
||||
);
|
||||
|
||||
// Need this block here, as a render pass only takes effect once it's
|
||||
// dropped.
|
||||
{
|
||||
|
@ -339,8 +318,6 @@ impl Renderer {
|
|||
drawables.lines.draw(&mut render_pass);
|
||||
}
|
||||
}
|
||||
|
||||
gui.draw(&mut render_pass, &clipped_primitives, &screen_descriptor);
|
||||
}
|
||||
|
||||
self.navigation_cube_renderer.draw(
|
||||
|
|
|
@ -1,365 +0,0 @@
|
|||
//! GUI-related code
|
||||
//!
|
||||
//! If at some point you use `Painter` or similar and you get this error:
|
||||
//!
|
||||
//! `VK_ERROR_NATIVE_WINDOW_IN_USE_KHR`
|
||||
//!
|
||||
//! and/or:
|
||||
//!
|
||||
//! `wgpu_core::device: surface configuration failed: Native window is in use`
|
||||
//!
|
||||
//! it's *probably(?)* because the swap chain has already been created for the
|
||||
//! window (e.g. by an integration) and *not* because of a regression of this
|
||||
//! issue (probably):
|
||||
//!
|
||||
//! <https://github.com/gfx-rs/wgpu/issues/1492>
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use std::env::current_dir;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use rfd::FileDialog;
|
||||
|
||||
use fj_math::{Aabb, Scalar};
|
||||
|
||||
use crate::{
|
||||
graphics::{DrawConfig, DEPTH_FORMAT, SAMPLE_COUNT},
|
||||
StatusReport,
|
||||
};
|
||||
|
||||
/// The GUI
|
||||
pub struct Gui {
|
||||
context: egui::Context,
|
||||
renderer: egui_wgpu::Renderer,
|
||||
options: Options,
|
||||
egui_output: Option<egui::FullOutput>,
|
||||
}
|
||||
|
||||
impl Gui {
|
||||
pub(crate) fn new(
|
||||
device: &wgpu::Device,
|
||||
texture_format: wgpu::TextureFormat,
|
||||
) -> Self {
|
||||
// The implementation of the integration with `egui` is likely to need
|
||||
// to change "significantly" depending on what architecture approach is
|
||||
// chosen going forward.
|
||||
//
|
||||
// The current implementation is somewhat complicated by virtue of
|
||||
// "sitting somewhere in the middle" in relation to being neither a
|
||||
// standalone integration nor fully using `egui` as a framework.
|
||||
//
|
||||
// This is a result of a combination of the current integration being
|
||||
// "proof of concept" level, and using `egui-winit` & `egui-wgpu`, which
|
||||
// are both relatively new additions to the core `egui` ecosystem.
|
||||
//
|
||||
// It is recommended to read the following for additional helpful
|
||||
// context for choosing an architecture:
|
||||
//
|
||||
// - https://github.com/emilk/egui/blob/eeae485629fca24a81a7251739460b671e1420f7/README.md#what-is-the-difference-between-egui-and-eframe
|
||||
// - https://github.com/emilk/egui/blob/eeae485629fca24a81a7251739460b671e1420f7/README.md#how-do-i-render-3d-stuff-in-an-egui-area
|
||||
|
||||
let context = egui::Context::default();
|
||||
let renderer = egui_wgpu::Renderer::new(
|
||||
device,
|
||||
texture_format,
|
||||
Some(DEPTH_FORMAT),
|
||||
SAMPLE_COUNT,
|
||||
);
|
||||
|
||||
Self {
|
||||
context,
|
||||
renderer,
|
||||
options: Options::default(),
|
||||
egui_output: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Access the egui context
|
||||
pub fn context(&self) -> &egui::Context {
|
||||
&self.context
|
||||
}
|
||||
|
||||
pub(crate) fn update(
|
||||
&mut self,
|
||||
pixels_per_point: f32,
|
||||
egui_input: egui::RawInput,
|
||||
config: &mut DrawConfig,
|
||||
aabb: &Aabb<3>,
|
||||
line_drawing_available: bool,
|
||||
state: GuiState,
|
||||
) -> Option<PathBuf> {
|
||||
self.context.set_pixels_per_point(pixels_per_point);
|
||||
self.context.begin_frame(egui_input);
|
||||
|
||||
let bounding_box_size = {
|
||||
let [x, y, z] = aabb.size().components.map(Scalar::into_f32);
|
||||
format!("Model bounding box size:\n{x:0.1} {y:0.1} {z:0.1}")
|
||||
};
|
||||
|
||||
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(bounding_box_size);
|
||||
});
|
||||
|
||||
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(|input| 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::Window::new("Status")
|
||||
.min_width(400.0)
|
||||
.min_height(200.0)
|
||||
.collapsible(true)
|
||||
.resizable(true)
|
||||
.show(&self.context, |ui| {
|
||||
egui::ScrollArea::both().show(ui, |ui| {
|
||||
ui.add(egui::Label::new(
|
||||
egui::RichText::new(state.status.status())
|
||||
.monospace()
|
||||
.color(egui::Color32::WHITE),
|
||||
))
|
||||
});
|
||||
});
|
||||
|
||||
let mut new_model_path = None;
|
||||
|
||||
if !state.model_available {
|
||||
egui::Area::new("ask-model")
|
||||
.anchor(egui::Align2::CENTER_CENTER, [0_f32, -5_f32])
|
||||
.show(&self.context, |ui| {
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.label(egui::RichText::new(
|
||||
"No model selected please choose a model to view.",
|
||||
).color(egui::Color32::BLACK)
|
||||
.background_color(egui::Color32::WHITE));
|
||||
if ui
|
||||
.button(egui::RichText::new("Pick a model"))
|
||||
.clicked()
|
||||
{
|
||||
new_model_path = show_file_dialog();
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// Even though the output is not used here, `end_frame` must be called
|
||||
// at the end of this function. If we don't, and we get into a situation
|
||||
// where `update` is called, but `prepare_draw` isn't for a while, the
|
||||
// context will keep accumulating output.
|
||||
//
|
||||
// That might end up being too much output to handle. This can lead to
|
||||
// a crash, because a index/vertex buffer gets too full.
|
||||
self.egui_output = Some(self.context.end_frame());
|
||||
|
||||
new_model_path
|
||||
}
|
||||
|
||||
pub(crate) fn prepare_draw(
|
||||
&mut self,
|
||||
device: &wgpu::Device,
|
||||
queue: &wgpu::Queue,
|
||||
encoder: &mut wgpu::CommandEncoder,
|
||||
screen_descriptor: &egui_wgpu::renderer::ScreenDescriptor,
|
||||
) -> Vec<egui::ClippedPrimitive> {
|
||||
let Some(egui_output) = self.egui_output.take() else {
|
||||
return Vec::new()
|
||||
};
|
||||
let clipped_primitives = self.context.tessellate(egui_output.shapes);
|
||||
|
||||
for (id, image_delta) in &egui_output.textures_delta.set {
|
||||
self.renderer
|
||||
.update_texture(device, queue, *id, image_delta);
|
||||
}
|
||||
for id in &egui_output.textures_delta.free {
|
||||
self.renderer.free_texture(id);
|
||||
}
|
||||
|
||||
self.renderer.update_buffers(
|
||||
device,
|
||||
queue,
|
||||
encoder,
|
||||
&clipped_primitives,
|
||||
screen_descriptor,
|
||||
);
|
||||
|
||||
clipped_primitives
|
||||
}
|
||||
|
||||
pub(crate) fn draw<'s: 'r, 'r>(
|
||||
&'s mut self,
|
||||
render_pass: &mut wgpu::RenderPass<'r>,
|
||||
clipped_primitives: &[egui::ClippedPrimitive],
|
||||
screen_descriptor: &egui_wgpu::renderer::ScreenDescriptor,
|
||||
) {
|
||||
self.renderer.render(
|
||||
render_pass,
|
||||
clipped_primitives,
|
||||
screen_descriptor,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn show_file_dialog() -> Option<PathBuf> {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
return FileDialog::new()
|
||||
.set_directory(current_dir().unwrap_or_else(|_| PathBuf::from("/")))
|
||||
.pick_folder();
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
todo!("Picking folders does not work on wasm32")
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Gui {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str("Gui {}")
|
||||
}
|
||||
}
|
||||
|
||||
#[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,
|
||||
}
|
||||
|
||||
/// The current status of the GUI
|
||||
pub struct GuiState<'a> {
|
||||
/// Reference to the status messages
|
||||
pub status: &'a StatusReport,
|
||||
|
||||
/// Indicates whether a model is currently available
|
||||
pub model_available: bool,
|
||||
}
|
|
@ -17,7 +17,6 @@
|
|||
mod assets;
|
||||
mod camera;
|
||||
mod graphics;
|
||||
mod gui;
|
||||
mod input;
|
||||
mod screen;
|
||||
mod status_report;
|
||||
|
@ -26,7 +25,6 @@ mod viewer;
|
|||
pub use self::{
|
||||
camera::Camera,
|
||||
graphics::{DrawConfig, Renderer, RendererInitError},
|
||||
gui::{Gui, GuiState},
|
||||
input::{InputEvent, InputHandler},
|
||||
screen::{NormalizedScreenPosition, Screen, ScreenSize},
|
||||
status_report::StatusReport,
|
||||
|
|
|
@ -3,9 +3,8 @@ use fj_math::Aabb;
|
|||
use tracing::warn;
|
||||
|
||||
use crate::{
|
||||
camera::FocusPoint, gui::Gui, Camera, DrawConfig, GuiState, InputEvent,
|
||||
InputHandler, NormalizedScreenPosition, Renderer, RendererInitError,
|
||||
Screen, ScreenSize,
|
||||
camera::FocusPoint, Camera, DrawConfig, InputEvent, InputHandler,
|
||||
NormalizedScreenPosition, Renderer, RendererInitError, Screen, ScreenSize,
|
||||
};
|
||||
|
||||
/// The Fornjot model viewer
|
||||
|
@ -22,9 +21,6 @@ pub struct Viewer {
|
|||
/// The focus point
|
||||
pub focus_point: Option<FocusPoint>,
|
||||
|
||||
/// The GUI
|
||||
pub gui: Gui,
|
||||
|
||||
/// The input handler
|
||||
pub input_handler: InputHandler,
|
||||
|
||||
|
@ -39,14 +35,12 @@ impl Viewer {
|
|||
/// Construct a new instance of `Viewer`
|
||||
pub async fn new(screen: &impl Screen) -> Result<Self, RendererInitError> {
|
||||
let renderer = Renderer::new(screen).await?;
|
||||
let gui = renderer.init_gui();
|
||||
|
||||
Ok(Self {
|
||||
camera: Camera::default(),
|
||||
cursor: None,
|
||||
draw_config: DrawConfig::default(),
|
||||
focus_point: None,
|
||||
gui,
|
||||
input_handler: InputHandler::default(),
|
||||
renderer,
|
||||
shape: None,
|
||||
|
@ -112,12 +106,7 @@ impl Viewer {
|
|||
}
|
||||
|
||||
/// Draw the graphics
|
||||
pub fn draw(
|
||||
&mut self,
|
||||
pixels_per_point: f32,
|
||||
egui_input: egui::RawInput,
|
||||
gui_state: GuiState,
|
||||
) {
|
||||
pub fn draw(&mut self) {
|
||||
let aabb = self
|
||||
.shape
|
||||
.as_ref()
|
||||
|
@ -126,21 +115,7 @@ impl Viewer {
|
|||
|
||||
self.camera.update_planes(&aabb);
|
||||
|
||||
self.gui.update(
|
||||
pixels_per_point,
|
||||
egui_input,
|
||||
&mut self.draw_config,
|
||||
&aabb,
|
||||
self.renderer.is_line_drawing_available(),
|
||||
gui_state,
|
||||
);
|
||||
|
||||
if let Err(err) = self.renderer.draw(
|
||||
&self.camera,
|
||||
&self.draw_config,
|
||||
pixels_per_point,
|
||||
&mut self.gui,
|
||||
) {
|
||||
if let Err(err) = self.renderer.draw(&self.camera, &self.draw_config) {
|
||||
warn!("Draw error: {}", err);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue