split out some ui logic

This commit is contained in:
Robin Appelman 2022-03-20 15:31:56 +01:00
commit 3971120204
2 changed files with 98 additions and 68 deletions

View file

@ -1,6 +1,8 @@
mod camera; mod camera;
mod loader; mod loader;
mod ui;
use crate::ui::DebugUI;
use camera::FirstPerson; use camera::FirstPerson;
use itertools::Either; use itertools::Either;
use loader::Loader; use loader::Loader;
@ -86,7 +88,7 @@ fn main() -> Result<(), Error> {
) )
.unwrap(); .unwrap();
let mut control = FirstPerson::new(0.1); let mut control = FirstPerson::new(0.1);
let mut gui = three_d::GUI::new(&context).unwrap(); let mut gui = DebugUI::new(&context)?;
let material = PhysicalMaterial { let material = PhysicalMaterial {
albedo: Color { albedo: Color {
@ -120,60 +122,28 @@ fn main() -> Result<(), Error> {
..Default::default() ..Default::default()
}; };
// main loop
let mut shadows_enabled = false;
let mut directional_intensity = lights.directional[0].intensity();
let mut depth_max = 30.0;
let mut fov = 60.0;
let mut debug_type = DebugType::NORMAL;
window.render_loop(move |mut frame_input| { window.render_loop(move |mut frame_input| {
let mut change = frame_input.first_frame; let (ui_change, panel_width) = gui.update(&mut frame_input, &camera).unwrap();
let mut panel_width = frame_input.viewport.width; let mut change = frame_input.first_frame || ui_change;
change |= gui if change {
.update(&mut frame_input, |gui_context| { if gui.shadows_enabled {
use three_d::egui::*; lights.directional[0]
SidePanel::left("side_panel").show(gui_context, |ui| { .generate_shadow_map(4.0, 1024, 1024, &[&model])
ui.heading("Debug Panel"); .unwrap();
lights.directional[1]
ui.label("Light options"); .generate_shadow_map(4.0, 1024, 1024, &[&model])
ui.add( .unwrap();
Slider::new(&mut lights.ambient.as_mut().unwrap().intensity, 0.0..=1.0) } else {
.text("Ambient intensity"), lights.directional[0].clear_shadow_map();
); lights.directional[1].clear_shadow_map();
ui.add( }
Slider::new(&mut directional_intensity, 0.0..=1.0) lights.directional[0].set_intensity(gui.directional_intensity);
.text("Directional intensity"), lights.directional[1].set_intensity(gui.directional_intensity);
); lights.ambient.as_mut().unwrap().intensity = gui.ambient_intensity;
lights.directional[0].set_intensity(directional_intensity); camera
lights.directional[1].set_intensity(directional_intensity); .set_perspective_projection(degrees(gui.fov), camera.z_near(), camera.z_far())
if ui.checkbox(&mut shadows_enabled, "Shadows").clicked() { .unwrap();
if !shadows_enabled { }
lights.directional[0].clear_shadow_map();
lights.directional[1].clear_shadow_map();
}
}
ui.label("Debug options");
ui.radio_value(&mut debug_type, DebugType::NONE, "None");
ui.radio_value(&mut debug_type, DebugType::POSITION, "Position");
ui.radio_value(&mut debug_type, DebugType::NORMAL, "Normal");
ui.radio_value(&mut debug_type, DebugType::COLOR, "Color");
ui.radio_value(&mut debug_type, DebugType::DEPTH, "Depth");
ui.radio_value(&mut debug_type, DebugType::ORM, "ORM");
ui.label("View options");
ui.add(Slider::new(&mut depth_max, 1.0..=30.0).text("Depth max"));
ui.add(Slider::new(&mut fov, 45.0..=90.0).text("FOV"));
ui.label("Position");
ui.add(Label::new(format!("\tx: {}", camera.position().x)));
ui.add(Label::new(format!("\ty: {}", camera.position().y)));
ui.add(Label::new(format!("\tz: {}", camera.position().z)));
});
panel_width = gui_context.used_size().x as u32;
})
.unwrap();
let viewport = Viewport { let viewport = Viewport {
x: panel_width as i32, x: panel_width as i32,
@ -188,21 +158,9 @@ fn main() -> Result<(), Error> {
// Draw // Draw
{ {
camera
.set_perspective_projection(degrees(fov), camera.z_near(), camera.z_far())
.unwrap();
if shadows_enabled {
lights.directional[0]
.generate_shadow_map(4.0, 1024, 1024, &[&model])
.unwrap();
lights.directional[1]
.generate_shadow_map(4.0, 1024, 1024, &[&model])
.unwrap();
}
// Light pass // Light pass
Screen::write(&context, ClearState::default(), || { Screen::write(&context, ClearState::default(), || {
match debug_type { match gui.debug_type {
DebugType::NORMAL => { DebugType::NORMAL => {
model.render_with_material( model.render_with_material(
&NormalMaterial::from_physical_material(&model.material), &NormalMaterial::from_physical_material(&model.material),
@ -217,7 +175,7 @@ fn main() -> Result<(), Error> {
} }
DebugType::DEPTH => { DebugType::DEPTH => {
let mut depth_material = DepthMaterial::default(); let mut depth_material = DepthMaterial::default();
depth_material.max_distance = Some(depth_max); depth_material.max_distance = Some(gui.depth_max);
model.render_with_material(&depth_material, &camera, &lights)?; model.render_with_material(&depth_material, &camera, &lights)?;
props_model.render_with_material(&depth_material, &camera, &lights)?; props_model.render_with_material(&depth_material, &camera, &lights)?;
} }

72
src/ui.rs Normal file
View file

@ -0,0 +1,72 @@
use three_d::egui::*;
use three_d::{Camera, Context, DebugType, FrameInput, ThreeDResult, GUI};
pub struct DebugUI {
ui: GUI,
pub shadows_enabled: bool,
pub directional_intensity: f32,
pub ambient_intensity: f32,
pub depth_max: f32,
pub fov: f32,
pub debug_type: DebugType,
}
impl DebugUI {
pub fn new(context: &Context) -> ThreeDResult<Self> {
Ok(DebugUI {
ui: three_d::GUI::new(context)?,
shadows_enabled: false,
directional_intensity: 1.0,
ambient_intensity: 0.2,
depth_max: 30.0,
fov: 60.0,
debug_type: DebugType::NORMAL,
})
}
pub fn update(
&mut self,
frame_input: &mut FrameInput,
camera: &Camera,
) -> ThreeDResult<(bool, u32)> {
let mut panel_width = 0;
let change = self.ui.update(frame_input, |gui_context| {
SidePanel::left("side_panel").show(gui_context, |ui| {
ui.heading("Debug Panel");
ui.label("Light options");
ui.add(
Slider::new(&mut self.ambient_intensity, 0.0..=1.0).text("Ambient intensity"),
);
ui.add(
Slider::new(&mut self.directional_intensity, 0.0..=1.0)
.text("Directional intensity"),
);
ui.checkbox(&mut self.shadows_enabled, "Shadows");
ui.label("Debug options");
ui.radio_value(&mut self.debug_type, DebugType::NONE, "None");
ui.radio_value(&mut self.debug_type, DebugType::POSITION, "Position");
ui.radio_value(&mut self.debug_type, DebugType::NORMAL, "Normal");
ui.radio_value(&mut self.debug_type, DebugType::COLOR, "Color");
ui.radio_value(&mut self.debug_type, DebugType::DEPTH, "Depth");
ui.radio_value(&mut self.debug_type, DebugType::ORM, "ORM");
ui.label("View options");
ui.add(Slider::new(&mut self.depth_max, 1.0..=30.0).text("Depth max"));
ui.add(Slider::new(&mut self.fov, 45.0..=90.0).text("FOV"));
ui.label("Position");
ui.add(Label::new(format!("\tx: {}", camera.position().x)));
ui.add(Label::new(format!("\ty: {}", camera.position().y)));
ui.add(Label::new(format!("\tz: {}", camera.position().z)));
});
panel_width = gui_context.used_size().x as u32;
})?;
Ok((change, panel_width))
}
pub fn render(&mut self) -> ThreeDResult<()> {
self.ui.render()
}
}