diff --git a/airplane.iqm b/airplane.iqm new file mode 100644 index 0000000..bc08835 Binary files /dev/null and b/airplane.iqm differ diff --git a/src/bin/pumpkin.rs b/src/bin/pumpkin.rs index 4467469..8896625 100644 --- a/src/bin/pumpkin.rs +++ b/src/bin/pumpkin.rs @@ -77,13 +77,13 @@ impl Default for EulerAngles { impl EulerAngles { pub fn to_vec3 (&self) -> Vec3 { - let alt = self.altitude * std::f32::consts::PI / 180.0; - let azi = self.azimuth * std::f32::consts::PI / 180.0; + let alt = self.altitude.to_radians (); + let azi = self.azimuth.to_radians (); let z = alt.sin (); let xy_len = alt.cos (); - let x = xy_len * azi.sin (); + let x = xy_len * -azi.sin (); let y = xy_len * azi.cos (); (x, y, z).into () @@ -93,6 +93,8 @@ impl EulerAngles { struct WorldState { camera: EulerAngles, wind: EulerAngles, + airplane: EulerAngles, + sunlight: EulerAngles, spin_speed: i32, } @@ -101,6 +103,11 @@ impl WorldState { Self { camera: Default::default (), wind: Default::default (), + airplane: Default::default (), + sunlight: EulerAngles { + altitude: 90.0, + azimuth: 0.0, + }, spin_speed: 0, } } @@ -117,6 +124,8 @@ impl WorldState { let controlled_angle = match user_control { UserControl::Camera => &mut self.camera, UserControl::Wind => &mut self.wind, + UserControl::Airplane => &mut self.airplane, + UserControl::Sunlight => &mut self.sunlight, }; if controller.is_pressed (KEY_LEFT) { @@ -537,7 +546,7 @@ struct GameGraphics { shaders: Vec , shader_lookup: HashMap , - mesh_pumpkin: RenderableModel, + mesh_airplane: RenderableModel, mesh_sky: RenderableModel, mesh_pitch: RenderableModel, mesh_arrow: RenderableModel, @@ -600,7 +609,7 @@ impl GameGraphics { glezz::enable_vertex_attrib_array (attrs [NORMAL]); }); - let mesh_pumpkin = renderable_from_iqm_file ("pumpking.iqm"); + let mesh_airplane = renderable_from_iqm_file ("airplane.iqm"); let mesh_sky = renderable_from_iqm_file ("sky-sphere.iqm"); let mesh_pitch = renderable_from_iqm_file ("pitch.iqm"); let mesh_arrow = renderable_from_iqm_file ("arrow.iqm"); @@ -825,7 +834,7 @@ impl GameGraphics { shaders, shader_lookup, - mesh_pumpkin, + mesh_airplane, mesh_sky, mesh_pitch, mesh_arrow, @@ -862,9 +871,11 @@ impl GameGraphics { let proj_mat = Mat4::perspective_rh_gl (30.0f32.to_radians (), 1280.0 / 720.0, 0.5, 500.0); + let light = state.sunlight.to_vec3 (); + let shadow_mat = { let mut mat = Mat4::identity (); - mat.set_z_axis ((-0.25, 0.125, 0.0, 0.0).into ()); + mat.set_z_axis ((-light.x () / light.z (), -light.y () / light.z (), 0.0, 0.0).into ()); mat }; @@ -877,8 +888,6 @@ impl GameGraphics { let sky_mvp_mat = view_mat * Mat4::from_scale ((16.0, 16.0, 16.0).into ()); - let light = Vec3::from ((0.25, -0.125, 1.0)).normalize (); - //println! ("Started frame"); let mut passes = self.passes.iter (); @@ -888,14 +897,15 @@ impl GameGraphics { glezz::clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT); }); - let pumpkin_model_mat = + let airplane_model_mat = Mat4::from_translation ((0.0, 0.0, 2.7 * 0.5).into ()) * Mat4::from_scale ((0.125, 0.125, 0.125).into ()) * - Mat4::from_translation ((0.0, 0.0, -2.7 * 0.5).into ()) + Mat4::from_rotation_z (state.airplane.azimuth.to_radians ()) * + Mat4::from_rotation_x (state.airplane.altitude.to_radians ()) ; let world_model_mat = Mat4::identity (); - let inverse_pumpkin = pumpkin_model_mat.inverse (); + let inverse_pumpkin = airplane_model_mat.inverse (); use uniforms::*; @@ -905,7 +915,7 @@ impl GameGraphics { let unis = shader_vars.unis; let attrs = shader_vars.attrs; - let mvp = view_mat * pumpkin_model_mat; + let mvp = view_mat * airplane_model_mat; glezz::uniform_matrix_4fv (unis [&MVP], &mvp); let object_space_light = make_object_space_vec (&inverse_pumpkin, &light); @@ -917,13 +927,17 @@ impl GameGraphics { glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light); glezz::uniform_3fv (unis [&OBJECT_SPACE_SKY], &object_space_sky); - self.mesh_pumpkin.draw_all (attrs, |i| { - glezz::uniform_3fv (unis [&ALBEDO], &pumpkin_colors [i]); + let gunmetal_grey = color_from_255 ((133.0, 149.0, 161.0)); + glezz::uniform_3fv (unis [&ALBEDO], &gunmetal_grey); + + self.mesh_airplane.draw_all (attrs, |i| { true }); let mvp = view_mat * world_model_mat; glezz::uniform_matrix_4fv (unis [&MVP], &mvp); + glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &light); + glezz::uniform_3fv (unis [&OBJECT_SPACE_SKY], &Vec3::from ((0.0, 0.0, 1.0))); self.mesh_pitch.draw_all (attrs, |i| { glezz::uniform_3fv (unis [&ALBEDO], &self.pitch_colors [i]); @@ -951,10 +965,10 @@ impl GameGraphics { let view_mat = view_mat * shadow_mat; - let mvp = view_mat * pumpkin_model_mat; + let mvp = view_mat * airplane_model_mat; glezz::uniform_matrix_4fv (unis [&MVP], &mvp); - self.mesh_pumpkin.draw_all (attrs, |_| true); + self.mesh_airplane.draw_all (attrs, |_| true); let mvp = view_mat * world_model_mat; glezz::uniform_matrix_4fv (unis [&MVP], &mvp); @@ -969,21 +983,16 @@ impl GameGraphics { } }); - let object_space_light = make_object_space_vec (&inverse_pumpkin, &light); - // Draw unlit ground passes.next ().unwrap ().with_shader (gl_state, self, |shader_vars| { let unis = shader_vars.unis; let attrs = shader_vars.attrs; - let inverse_pumpkin = pumpkin_model_mat.inverse (); - - let object_space_sky = make_object_space_vec (&inverse_pumpkin, &Vec3::from ((0.0, 0.0, 1.0))); - glezz::uniform_3fv (unis [&MIN_BRIGHT], &black); glezz::uniform_3fv (unis [&MIN_ALBEDO], &white); - glezz::uniform_3fv (unis [&OBJECT_SPACE_SKY], &object_space_sky); + glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &light); + glezz::uniform_3fv (unis [&OBJECT_SPACE_SKY], &Vec3::from ((0.0, 0.0, 1.0))); let mvp = view_mat * world_model_mat; glezz::uniform_matrix_4fv (unis [&MVP], &mvp); @@ -1000,7 +1009,8 @@ impl GameGraphics { let unis = shader_vars.unis; let attrs = shader_vars.attrs; - glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light); + glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &light); + glezz::uniform_3fv (unis [&OBJECT_SPACE_SKY], &Vec3::from ((0.0, 0.0, 1.0))); self.mesh_pitch.draw (attrs, self.grass_index); }); @@ -1038,6 +1048,8 @@ impl GameGraphics { enum UserControl { Camera, Wind, + Airplane, + Sunlight, } fn main () { @@ -1087,6 +1099,12 @@ fn main () { Event::KeyDown { keycode: Some (Keycode::W), .. } => { user_control = UserControl::Wind; }, + Event::KeyDown { keycode: Some (Keycode::P), .. } => { + user_control = UserControl::Airplane; + }, + Event::KeyDown { keycode: Some (Keycode::L), .. } => { + user_control = UserControl::Sunlight; + }, _ => (), } } @@ -1113,6 +1131,15 @@ fn main () { (1.0, 0.0, 0.0).into () }; + let get_flash = |control_type, default_color| { + if user_control == control_type { + control_flash + } + else { + default_color + } + }; + let arrows = vec![ Arrow { origin: (0.0, 0.0, 1.35).into (), @@ -1122,18 +1149,18 @@ fn main () { Arrow { origin: origin + wind * -2.0, direction: wind, - color: if user_control == UserControl::Wind { - control_flash - } - else { - purple - }, + color: get_flash (UserControl::Wind, purple), }, Arrow { origin: origin, direction: wind_force, color: purple, }, + Arrow { + origin: origin, + direction: state.airplane.to_vec3 () * 0.5, + color: get_flash (UserControl::Airplane, (0.0, 0.0, 0.0).into ()), + } ]; let renderable_arrows: Vec <_> = arrows.iter ().map (|arrow| {