diff --git a/src/main.rs b/src/main.rs index 7f5a5a6..5b45c33 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,17 +3,16 @@ mod ecs; mod model; mod render; mod time; +mod ui; use anyhow::Result; use camera::Camera; use ecs::{MeshHandle, Transform}; -use glam::{Quat, Vec3}; +use glam::{Quat, Vec3, EulerRot}; use glium::backend::glutin::SimpleWindowBuilder; -use render::{Renderer, GliumRenderer}; +use render::GliumRenderer; fn main() -> Result<()> { - const ROTATION_SPEED: f32 = 1.0; - let event_loop = glium::winit::event_loop::EventLoop::builder() .build() .expect("create event-loop"); @@ -30,14 +29,17 @@ fn main() -> Result<()> { ecs::ECSRenderer::new(renderer, world) }; + // Dear ImGui integration + let mut gui = ui::Gui::new(&display, &window)?; + let mut time = time::Time::new(); let object_ent = { let mesh = model::load_gltf("resources/models/monkey.gltf", &display)?; ecsr.spawn_mesh(mesh, Transform { - translation: Vec3::ZERO, - rotation: Quat::IDENTITY, - scale: Vec3::ONE, + translation: Vec3::ZERO, + rotation: Quat::IDENTITY, + scale: Vec3::ONE, }) }; @@ -45,10 +47,10 @@ fn main() -> Result<()> { let camera_ent = { let (w, h): (u32, u32) = window.inner_size().into(); ecsr.world.spawn((Camera { - eye: Vec3::new(3.0, 2.0, 3.0), + eye: Vec3::new(0.0, 0.0, 2.0), center: Vec3::ZERO, up: Vec3::Y, - fovy: 45_f32.to_radians(), + fovy: 60_f32.to_radians(), aspect: w as f32 / h as f32, znear: 0.1, zfar: 100.0, @@ -59,6 +61,8 @@ fn main() -> Result<()> { .run(move |event, el| { use glium::winit::event::{Event, WindowEvent}; + gui.handle_event(&window, &event); + match event { Event::WindowEvent { event, .. } => match event { WindowEvent::CloseRequested => el.exit(), @@ -68,23 +72,42 @@ fn main() -> Result<()> { }); } WindowEvent::RedrawRequested => { - ecsr.render(); + let mut target = display.draw(); + + ecsr.render_into(&mut target); + + gui.render_with(&mut target, &window, |ui| { + if let Ok(mut tr) = ecsr.world.query_one_mut::<&mut Transform>(object_ent) { + // Translation controls + let mut translation = [tr.translation.x, tr.translation.y, tr.translation.z]; + if ui.input_float3("Translation", &mut translation).build() { + tr.translation = Vec3::from(translation); + } + + // Scale controls + let mut scale = [tr.scale.x, tr.scale.y, tr.scale.z]; + if ui.input_float3("Scale", &mut scale).build() { + tr.scale = Vec3::from(scale); + } + + // Rotation controls + let (yaw, pitch, roll) = tr.rotation.to_euler(EulerRot::YXZ); + let mut rotation_deg = [yaw.to_degrees(), pitch.to_degrees(), roll.to_degrees()]; + if ui.input_float3("Rotation (deg)", &mut rotation_deg).build() { + let yaw = rotation_deg[0].to_radians(); + let pitch = rotation_deg[1].to_radians(); + let roll = rotation_deg[2].to_radians(); + tr.rotation = Quat::from_euler(EulerRot::YXZ, yaw, pitch, roll); + } + } + }); + target.finish().unwrap(); } _ => {} }, Event::AboutToWait => { time.tick(); - let dt = time.delta_seconds(); - ecsr.world.query_one_mut::<&mut Transform>(object_ent).map(|mut object| { - object.rotation *= Quat::from_rotation_y(ROTATION_SPEED * dt); - }); - - // despawn the object after 3 seconds - if time.total_seconds() > 3.0 { - ecsr.despawn_mesh(object_ent); - } - - // ask for next frame + gui.prepare_frame(&window); window.request_redraw(); } _ => {}