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.

152 lines
4.8 KiB

  1. use glc::{
  2. matrix::Matrix4f,
  3. misc::Bindable,
  4. shader::{Program, Type},
  5. vector::{Vector2f, 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: Vector2f,
  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 = Vector2f::default();
  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.x as _, self.resolution.y as _);
  73. camera
  74. .resize(self.resolution.x, self.resolution.y)
  75. .error("Error while updating camera");
  76. }
  77. /* zoom */
  78. let events = mouse_events.read(&mut self.mouse_event_id);
  79. for event in events {
  80. match event {
  81. MouseEvent::ScrollY(delta) => {
  82. let s = config.input.camera_zoom_speed;
  83. let z = s / (s - delta);
  84. let m = Matrix4f::translate(input_state.mouse_pos)
  85. * Matrix4f::scale(z)
  86. * Matrix4f::translate(-input_state.mouse_pos);
  87. camera
  88. .update_with(move |v| m * v)
  89. .error("Error while zooming camera");
  90. }
  91. MouseEvent::Delta(x, y) if input_state.button_state(&[MouseButton::Right]) => {
  92. let m = Matrix4f::translate((*x, -*y, 0.0));
  93. camera
  94. .update_with(move |v| m * v)
  95. .error("Error while zooming camera");
  96. }
  97. MouseEvent::ButtonDown(b) if b == &config.input.camera_move_button => {
  98. control_events.single_write(ControlEvent::LockMouse);
  99. }
  100. MouseEvent::ButtonUp(b) if b == &config.input.camera_move_button => {
  101. control_events.single_write(ControlEvent::UnlockMouse);
  102. }
  103. _ => (),
  104. }
  105. }
  106. /* move camera */
  107. let up = input_state.key_state(&config.input.camera_move_key_up);
  108. let down = input_state.key_state(&config.input.camera_move_key_down);
  109. let left = input_state.key_state(&config.input.camera_move_key_left);
  110. let right = input_state.key_state(&config.input.camera_move_key_right);
  111. if up || down || left || right {
  112. let s = config.input.camera_move_speed * global.delta;
  113. let translate = Vector3f::new(
  114. if left { s } else { 0.0 } + if right { -s } else { 0.0 },
  115. if up { -s } else { 0.0 } + if down { s } else { 0.0 },
  116. 0.0,
  117. );
  118. let m = Matrix4f::translate(translate);
  119. camera
  120. .update_with(move |v| m * v)
  121. .error("Error while moving camera");
  122. }
  123. uniform
  124. .update()
  125. .error("Error while updating global uniform data");
  126. /* render background */
  127. self.program.bind();
  128. geometry.render_quad();
  129. self.program.unbind();
  130. }
  131. }