From 54e89a28bae6128710f335df381df4a5136fa59f Mon Sep 17 00:00:00 2001 From: mitchellhansen Date: Sun, 21 Feb 2021 21:06:02 -0800 Subject: [PATCH] I optimized for rendering, and made a horrific writing API, smh --- src/components.rs | 2 +- src/main.rs | 7 ++- src/physics/system.rs | 8 ++++ src/render/system.rs | 52 +++++++++++++++++----- src/runtime/system.rs | 100 +++++++++++++++++++++++++++--------------- 5 files changed, 119 insertions(+), 50 deletions(-) diff --git a/src/components.rs b/src/components.rs index c6af81f..233982c 100644 --- a/src/components.rs +++ b/src/components.rs @@ -14,7 +14,7 @@ use imgui::Ui; pub struct ImguiWindow<'a, T> { pub window: fn() -> imgui::Window<'a>, - pub func: fn(&Ui, &T), + pub func: fn(&Ui, Vec<&T>), } #[derive(Clone, Copy, Debug, PartialEq)] diff --git a/src/main.rs b/src/main.rs index b6a63cf..9038f71 100644 --- a/src/main.rs +++ b/src/main.rs @@ -61,6 +61,7 @@ use crate::owned_event::{OwnedEvent, OwnedEventExtension}; use crate::physics::state::PhysicsState; use crate::render::system::ImguiPerformanceProfilerLine; use crate::runtime::state::RuntimeState; +use winit_24::dpi::PhysicalSize; mod camera; mod components; @@ -134,11 +135,12 @@ fn main() { let mut load_schedule = Schedule::builder() .add_system(runtime::system::runtime_load_system()) .add_system(runtime::system::runtime_spawn_system()) + .flush() .build(); let mut render_schedule = Schedule::builder() .add_system(render::system::render_imgui_system()) - .add_system(render::system::render_test_system()) + .add_system(render::system::render_test_system(ImguiPerformanceProfilerLine::new("Render system".to_string()))) .build(); let mut update_schedule = Schedule::builder() @@ -151,10 +153,11 @@ fn main() { let mut event_schedule = Schedule::builder() .add_system(owned_event::event_dispatch_system()) .build(); - + let event_loop = EventLoop::::with_user_event(); let mut builder = winit_24::window::WindowBuilder::new(); builder = builder.with_title("MVGE"); + builder = builder.with_inner_size(PhysicalSize::new(1200,900)); let window = builder.build(&event_loop).unwrap(); diff --git a/src/physics/system.rs b/src/physics/system.rs index fd50577..6a86818 100644 --- a/src/physics/system.rs +++ b/src/physics/system.rs @@ -14,6 +14,7 @@ use crate::components::{Collider, LoopState, Mesh, Physics, Position, ImguiWindo use imgui::{FontSource, Condition}; use imgui::*; use crate::physics::state::PhysicsState; +use crate::render::system::ImguiGenericOutputLine; #[system] @@ -78,12 +79,18 @@ pub fn run_physics( #[system] #[write_component(Camera)] #[write_component(CameraController)] +#[write_component(ImguiGenericOutputLine)] pub fn update_camera(world: &mut SubWorld, #[resource] loop_state: &mut LoopState) { let mut query = <(&mut Camera, &mut CameraController)>::query(); for (mut camera, controller) in query.iter_mut(world) { controller.update_camera(&mut camera, loop_state.step_size) } + let mut query = <(&mut Camera, &mut CameraController, &mut ImguiGenericOutputLine)>::query(); + for (mut camera, controller, ui_entry) in query.iter_mut(world) { + ui_entry.label = format!("Camera: {:.2}, {:.2}, {:.2}", camera.position.x, camera.position.y, camera.position.z); + } + } #[system] @@ -96,6 +103,7 @@ pub fn update_models( #[resource] physics_state: &mut PhysicsState, #[resource] physics_pipeline: &mut PhysicsPipeline, ) { + // Make sure all the entities we care about are added to the system let mut query = <(&mut Collider, &mut Physics, &mut Mesh, &mut Position)>::query(); for (collider, physics, mesh, position) in query.iter_mut(world) { diff --git a/src/render/system.rs b/src/render/system.rs index d2ea7d5..7be2d7d 100644 --- a/src/render/system.rs +++ b/src/render/system.rs @@ -55,22 +55,55 @@ pub fn imgui_prepare( unsafe { crate::CURRENT_UI = Some(std::mem::transmute(imgui_context.frame())) } } + +fn run_imgui_render_step(world: &mut SubWorld, ui: &Ui) { + + let mut component_query = <(&G)>::query(); + let mut window_query = <(&ImguiWindow)>::query(); + + let mut window_data = None; + let mut window_func = None; + for (window) in window_query.iter(world) { + window_data = Some((window.window)()); + window_func = Some(window.func); + } + + if window_data.is_some() { + let mut v = Vec::new(); + for (component_state) in component_query.iter(world) { + v.push(component_state) + } + window_data.unwrap().build(&ui, || { (window_func.unwrap())(ui, v) }); + } +} /// Go through each "global" window-data component and render it's data #[system] #[write_component(ImguiWindow)] #[write_component(ImguiPerformanceProfilerLine)] +#[write_component(ImguiWindow)] +#[write_component(ImguiGenericOutputLine)] pub fn render_imgui(world: &mut SubWorld, #[resource] loop_state: &mut LoopState) { let ui = unsafe { crate::current_ui().unwrap() }; - let mut query = <(&ImguiPerformanceProfilerLine, &mut ImguiWindow)>::query(); - for (state, mut window) in query.iter_mut(world) { - let new_window = (window.window)(); - new_window.build(&ui, || { (window.func)(ui, state) }); + // Pull out the window associated with this type, and render each of the components in the sytem + run_imgui_render_step::(world, &ui); + run_imgui_render_step::(world, &ui); +} - } + +// This would be the shared state for all imgui generic output things +pub struct ImguiGenericOutputLine { + pub label: String, } +impl ImguiGenericOutputLine { + pub fn new(label: String) -> ImguiGenericOutputLine { + ImguiGenericOutputLine { + label + } + } +} // This would be the shared state for all imgui performance window things pub struct ImguiPerformanceProfilerLine { @@ -128,6 +161,7 @@ impl ImguiPerformanceProfilerLine { #[write_component(DirectionalLight)] pub fn render_test( world: &mut SubWorld, + #[state] performance_profiler_line: &mut ImguiPerformanceProfilerLine, #[resource] loop_state: &mut LoopState, #[resource] renderer: &mut RenderState, #[resource] winit_window: &mut Window, @@ -135,11 +169,8 @@ pub fn render_test( #[resource] imgui_platform: &mut Arc>, ) { - let mut query = <(&mut ImguiPerformanceProfilerLine)>::query(); - for (mut profiler) in query.iter_mut(world) { - let delta_time = loop_state.delta_time.as_secs_f32(); - profiler.add_sample(delta_time); - } + let delta_time = loop_state.delta_time.as_secs_f32(); + performance_profiler_line.add_sample(delta_time); let mut encoder = renderer .device @@ -147,7 +178,6 @@ pub fn render_test( push_debug_group_checked("start render function", &mut encoder); - let frame = renderer.get_current_frame(); // Update the camera uniform buffers, need to make it support selection of diff --git a/src/runtime/system.rs b/src/runtime/system.rs index 04b941e..6272cc6 100644 --- a/src/runtime/system.rs +++ b/src/runtime/system.rs @@ -22,7 +22,7 @@ use crate::components::{Collider, ImguiWindow, LoopState, Mesh, Physics, Positio use crate::geometry::RawMesh; use crate::physics::state::PhysicsState; use crate::render::state::RenderState; -use crate::render::system::ImguiPerformanceProfilerLine; +use crate::render::system::{ImguiGenericOutputLine, ImguiPerformanceProfilerLine}; use crate::runtime::state::RuntimeState; pub fn quad_color(color: [f32; 4]) -> [[f32; 4]; 4] { @@ -38,35 +38,38 @@ pub fn runtime_load( ) { runtime_state.preload_meshes(PathBuf::from("./resources")); - let entity: Entity = cmd.push(( - ImguiWindow { - // a window that does everything for the performance profiler - window: || { - imgui::Window::new(im_str!("Performance Profiler")) - .size([400.0, 500.0], Condition::FirstUseEver) - .position([50.0, 50.0], Condition::FirstUseEver) - }, - func: |ui: &Ui, a: &ImguiPerformanceProfilerLine| { - ui.text(im_str!("Performance Graph")); - - let draw_list = ui.get_window_draw_list(); - let top_left = ui.cursor_screen_pos(); - let region_size = ui.content_region_avail(); - - // Fill rect - let qcolor = quad_color([0.5, 0.5, 1.0, 0.1]); - draw_list.add_rect_filled_multicolor( - top_left, - [top_left[0] + (region_size[0] - region_size[0]/5.0), top_left[1] + region_size[1]], - qcolor[0], - qcolor[1], - qcolor[2], - qcolor[3], - ); + let entity: Entity = cmd.push((ImguiWindow { + // a window that does everything for the performance profiler + window: || { + imgui::Window::new(im_str!("Performance Profiler")) + .size([400.0, 200.0], Condition::FirstUseEver) + .position([10.0, 10.0], Condition::FirstUseEver) + }, + func: |ui: &Ui, a: Vec<&ImguiPerformanceProfilerLine>| { + // ui.text(im_str!("Performance Graph")); + + let draw_list = ui.get_window_draw_list(); + let top_left = ui.cursor_screen_pos(); + let region_size = ui.content_region_avail(); - let x_scale = (region_size[0] - region_size[0]/5.0) / 400.0; - let y_scale = region_size[1] / a.scale_max; - a.iter_data_from_head() + let region_size = [region_size[0] * 0.80, region_size[1]]; + + // Fill rect + let qcolor = quad_color([0.5, 0.5, 1.0, 0.1]); + draw_list.add_rect_filled_multicolor( + top_left, + [top_left[0] + (region_size[0]), top_left[1] + region_size[1]], + qcolor[0], + qcolor[1], + qcolor[2], + qcolor[3], + ); + + for profiler_line in a { + let x_scale = (region_size[0]) / 400.0; + let y_scale = region_size[1] / profiler_line.scale_max; + profiler_line + .iter_data_from_head() .fold((0, 0.0f32), |accum, &fps_val| { let x1 = accum.0 as f32 * x_scale + top_left[0]; let y1 = top_left[1] + region_size[1] - accum.1 * y_scale; @@ -75,19 +78,42 @@ pub fn runtime_load( let p1 = [x1, y1]; let p2 = [x2, y2]; draw_list - .add_line(p1, p2, [1.0, 1.0, 0.0]) + .add_line(p1, p2, [1.0, 1.0, 0.0, 0.8]) .thickness(1.0) .build(); (accum.0 + 1, fps_val) }); - let text_x = (region_size[0] - region_size[0]/5.0 + 75.0); - let text_y = top_left[1] + region_size[1] - a.current_average_label().0 * y_scale; - draw_list.add_text([text_x, text_y], [1.0,1.0,0.0,1.0], format!("{} {:.0}",a.current_average_label().1, 1.0/a.current_average_label().0)); - }, + let text_x = (region_size[0] + top_left[0]); + let text_y = top_left[1] + region_size[1] + - profiler_line.current_average_label().0 * y_scale; + draw_list.add_text( + [text_x, text_y], + [1.0, 1.0, 0.0, 1.0], + format!( + "{} {:.0}", + profiler_line.current_average_label().1, + 1.0 / profiler_line.current_average_label().0 + ), + ); + } + }, + },)); + let entity: Entity = cmd.push((ImguiPerformanceProfilerLine::new("RenderFPS".to_string()),)); + + let entity: Entity = cmd.push((ImguiWindow { + // a window that does everything for the performance profiler + window: || { + imgui::Window::new(im_str!("Generic Output")) + .size([400.0, 500.0], Condition::FirstUseEver) + .position([50.0, 250.0], Condition::FirstUseEver) + }, + func: |ui: &Ui, a: Vec<&ImguiGenericOutputLine>| { + for label in a { + ui.text(im_str!("{}", label.label)); + } }, - ImguiPerformanceProfilerLine::new("RenderFFS".to_string()), - )); + },)); } #[system] @@ -149,6 +175,7 @@ pub fn runtime_spawn( collider: collider, collider_handle: None, }, + ImguiGenericOutputLine::new("wahoo! from a physics entity".to_string()), )); } "Terrain" => { @@ -214,6 +241,7 @@ pub fn runtime_spawn( pitch: Rad(PI / 2.0 + 25.0), }, CameraController::new(5.0, 1.0), + ImguiGenericOutputLine::new("wahoo! from a camera".to_string()), )); } "Light" => {