You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
4.9 KiB

  1. use glc::{
  2. matrix::Matrix4f,
  3. misc::Bindable,
  4. shader::{Program, Type},
  5. vector::Vector3f,
  6. };
  7. use shrev::{EventChannel, ReaderId};
  8. use space_crush_common::{
  9. misc::{LogResult, WorldHelper as _},
  10. resources::Global,
  11. };
  12. use specs::{prelude::*, ReadExpect, System, World, WriteExpect};
  13. use crate::{
  14. constants::{UNIFORM_BUFFER_INDEX_CAMERA, UNIFORM_BUFFER_INDEX_UNIFORM},
  15. misc::{ControlEvent, MouseButton, MouseEvent, WorldHelper},
  16. resources::{Camera, Config, Geometry, InputState, Uniform},
  17. Error,
  18. };
  19. pub struct Init {
  20. program: Program,
  21. resolution: (u32, u32),
  22. mouse_event_id: ReaderId<MouseEvent>,
  23. }
  24. impl Init {
  25. pub fn new(world: &mut World) -> Result<Self, Error> {
  26. let program = world.load_program(vec![
  27. (Type::Vertex, "resources/shader/noise/vert.glsl"),
  28. (Type::Fragment, "resources/shader/noise/frag.glsl"),
  29. ])?;
  30. let resolution = (0, 0);
  31. let mouse_event_id = world.register_event_reader::<MouseEvent>()?;
  32. world
  33. .resource::<Camera>()?
  34. .bind(UNIFORM_BUFFER_INDEX_CAMERA)?;
  35. world
  36. .resource::<Uniform>()?
  37. .bind(UNIFORM_BUFFER_INDEX_UNIFORM)?;
  38. Ok(Self {
  39. program,
  40. resolution,
  41. mouse_event_id,
  42. })
  43. }
  44. }
  45. #[derive(SystemData)]
  46. pub struct InitData<'a> {
  47. camera: WriteExpect<'a, Camera>,
  48. uniform: WriteExpect<'a, Uniform>,
  49. control_events: WriteExpect<'a, EventChannel<ControlEvent>>,
  50. global: ReadExpect<'a, Global>,
  51. config: ReadExpect<'a, Config>,
  52. geometry: ReadExpect<'a, Geometry>,
  53. input_state: ReadExpect<'a, InputState>,
  54. mouse_events: ReadExpect<'a, EventChannel<MouseEvent>>,
  55. }
  56. impl<'a> System<'a> for Init {
  57. type SystemData = InitData<'a>;
  58. fn run(&mut self, data: Self::SystemData) {
  59. let InitData {
  60. mut camera,
  61. mut uniform,
  62. mut control_events,
  63. global,
  64. config,
  65. geometry,
  66. input_state,
  67. mouse_events,
  68. } = data;
  69. /* screen size */
  70. if self.resolution != input_state.resolution {
  71. self.resolution = input_state.resolution;
  72. gl::viewport(0, 0, self.resolution.0 as _, self.resolution.1 as _);
  73. camera
  74. .resize(self.resolution.0 as _, self.resolution.1 as _)
  75. .error("Error while updating camera");
  76. }
  77. /* zoom */
  78. let mouse_pos = &input_state.mouse_pos;
  79. let events = mouse_events.read(&mut self.mouse_event_id);
  80. for event in events {
  81. match event {
  82. MouseEvent::ScrollY(delta) => {
  83. let s = config.input.camera_zoom_speed;
  84. let z = s / (s - delta);
  85. let m = Matrix4f::translate((mouse_pos.0, mouse_pos.1, 0.0).into())
  86. * Matrix4f::scale(z.into())
  87. * Matrix4f::translate((-mouse_pos.0, -mouse_pos.1, 0.0).into());
  88. camera
  89. .update_with(move |v| m * v)
  90. .error("Error while zooming camera");
  91. }
  92. MouseEvent::Delta(x, y) if input_state.button_state(&[MouseButton::Right]) => {
  93. let m = Matrix4f::translate((*x, -*y, 0.0).into());
  94. camera
  95. .update_with(move |v| m * v)
  96. .error("Error while zooming camera");
  97. }
  98. MouseEvent::ButtonDown(b) if b == &config.input.camera_move_button => {
  99. control_events.single_write(ControlEvent::LockMouse);
  100. }
  101. MouseEvent::ButtonUp(b) if b == &config.input.camera_move_button => {
  102. control_events.single_write(ControlEvent::UnlockMouse);
  103. }
  104. _ => (),
  105. }
  106. }
  107. /* move camera */
  108. let up = input_state.key_state(&config.input.camera_move_key_up);
  109. let down = input_state.key_state(&config.input.camera_move_key_down);
  110. let left = input_state.key_state(&config.input.camera_move_key_left);
  111. let right = input_state.key_state(&config.input.camera_move_key_right);
  112. if up || down || left || right {
  113. let s = config.input.camera_move_speed * global.delta;
  114. let translate = Vector3f::new(
  115. if left { s } else { 0.0 } + if right { -s } else { 0.0 },
  116. if up { -s } else { 0.0 } + if down { s } else { 0.0 },
  117. 0.0,
  118. );
  119. let m = Matrix4f::translate(translate);
  120. camera
  121. .update_with(move |v| m * v)
  122. .error("Error while moving camera");
  123. }
  124. uniform
  125. .update()
  126. .error("Error while updating global uniform data");
  127. /* render background */
  128. self.program.bind();
  129. geometry.render_quad();
  130. self.program.unbind();
  131. }
  132. }