|
- use glc::{
- matrix::Matrix4f,
- misc::Bindable,
- shader::{Program, Type},
- vector::{Vector2f, Vector3f},
- };
- use shrev::{EventChannel, ReaderId};
- use space_crush_common::{
- misc::{LogResult, WorldHelper as _},
- resources::Global,
- };
- use specs::{prelude::*, ReadExpect, System, World, WriteExpect};
-
- use crate::{
- constants::{UNIFORM_BUFFER_INDEX_CAMERA, UNIFORM_BUFFER_INDEX_UNIFORM},
- misc::{ControlEvent, MouseButton, MouseEvent, WorldHelper},
- resources::{Camera, Config, Geometry, InputState, Uniform},
- Error,
- };
-
- pub struct Init {
- program: Program,
- resolution: Vector2f,
- mouse_event_id: ReaderId<MouseEvent>,
- }
-
- impl Init {
- pub fn new(world: &mut World) -> Result<Self, Error> {
- let program = world.load_program(vec![
- (Type::Vertex, "resources/shader/noise/vert.glsl"),
- (Type::Fragment, "resources/shader/noise/frag.glsl"),
- ])?;
- let resolution = Vector2f::default();
- let mouse_event_id = world.register_event_reader::<MouseEvent>()?;
-
- world
- .resource::<Camera>()?
- .bind(UNIFORM_BUFFER_INDEX_CAMERA)?;
- world
- .resource::<Uniform>()?
- .bind(UNIFORM_BUFFER_INDEX_UNIFORM)?;
-
- Ok(Self {
- program,
- resolution,
- mouse_event_id,
- })
- }
- }
-
- #[derive(SystemData)]
- pub struct InitData<'a> {
- camera: WriteExpect<'a, Camera>,
- uniform: WriteExpect<'a, Uniform>,
- control_events: WriteExpect<'a, EventChannel<ControlEvent>>,
-
- global: ReadExpect<'a, Global>,
- config: ReadExpect<'a, Config>,
- geometry: ReadExpect<'a, Geometry>,
- input_state: ReadExpect<'a, InputState>,
- mouse_events: ReadExpect<'a, EventChannel<MouseEvent>>,
- }
-
- impl<'a> System<'a> for Init {
- type SystemData = InitData<'a>;
-
- fn run(&mut self, data: Self::SystemData) {
- let InitData {
- mut camera,
- mut uniform,
- mut control_events,
- global,
- config,
- geometry,
- input_state,
- mouse_events,
- } = data;
-
- /* screen size */
- if self.resolution != input_state.resolution {
- self.resolution = input_state.resolution;
-
- gl::viewport(0, 0, self.resolution.x as _, self.resolution.y as _);
-
- camera
- .resize(self.resolution.x, self.resolution.y)
- .error("Error while updating camera");
- }
-
- /* zoom */
- let events = mouse_events.read(&mut self.mouse_event_id);
- for event in events {
- match event {
- MouseEvent::ScrollY(delta) => {
- let s = config.input.camera_zoom_speed;
- let z = s / (s - delta);
- let m = Matrix4f::translate(input_state.mouse_pos)
- * Matrix4f::scale(z)
- * Matrix4f::translate(-input_state.mouse_pos);
-
- camera
- .update_with(move |v| m * v)
- .error("Error while zooming camera");
- }
- MouseEvent::Delta(x, y) if input_state.button_state(&[MouseButton::Right]) => {
- let m = Matrix4f::translate((*x, -*y, 0.0));
-
- camera
- .update_with(move |v| m * v)
- .error("Error while zooming camera");
- }
- MouseEvent::ButtonDown(b) if b == &config.input.camera_move_button => {
- control_events.single_write(ControlEvent::LockMouse);
- }
- MouseEvent::ButtonUp(b) if b == &config.input.camera_move_button => {
- control_events.single_write(ControlEvent::UnlockMouse);
- }
- _ => (),
- }
- }
-
- /* move camera */
- let up = input_state.key_state(&config.input.camera_move_key_up);
- let down = input_state.key_state(&config.input.camera_move_key_down);
- let left = input_state.key_state(&config.input.camera_move_key_left);
- let right = input_state.key_state(&config.input.camera_move_key_right);
-
- if up || down || left || right {
- let s = config.input.camera_move_speed * global.delta;
- let translate = Vector3f::new(
- if left { s } else { 0.0 } + if right { -s } else { 0.0 },
- if up { -s } else { 0.0 } + if down { s } else { 0.0 },
- 0.0,
- );
-
- let m = Matrix4f::translate(translate);
- camera
- .update_with(move |v| m * v)
- .error("Error while moving camera");
- }
-
- uniform
- .update()
- .error("Error while updating global uniform data");
-
- /* render background */
- self.program.bind();
- geometry.render_quad();
- self.program.unbind();
- }
- }
|