diff --git a/src/camera.rs b/src/camera.rs index 34d0747..4481ec4 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -3,6 +3,7 @@ use winit::event::{MouseScrollDelta, VirtualKeyCode, ElementState}; use winit::dpi::{PhysicalPosition, LogicalPosition}; use std::time::{Duration, Instant}; use std::f32::consts::FRAC_PI_2; +use crate::render::OPENGL_TO_WGPU_MATRIX; #[derive(Clone, Copy, Debug, PartialEq)] pub struct Camera { @@ -28,8 +29,8 @@ impl Camera { } } - pub fn calc_matrix(&self) -> Matrix4 { - Matrix4::look_at_dir( + pub fn calc_matrix(&self, projection: cgmath::Matrix4) -> Matrix4 { + let mx_view = Matrix4::look_at_dir( self.position, Vector3::new( self.yaw.0.cos(), @@ -37,7 +38,9 @@ impl Camera { self.yaw.0.sin(), ).normalize(), Vector3::unit_y(), - ) + ); + let mx_correction = OPENGL_TO_WGPU_MATRIX; + mx_correction * projection * mx_view } } @@ -123,10 +126,7 @@ impl CameraController { }; } - pub fn update_camera(&mut self, camera: &mut Camera, dt: Duration) { - - - let dt = dt.as_secs_f32(); + pub fn update_camera(&mut self, camera: &mut Camera, dt: f32) { // Move forward/backward and left/right let (yaw_sin, yaw_cos) = camera.yaw.0.sin_cos(); diff --git a/src/components.rs b/src/components.rs index 89b5b9b..f1d2101 100644 --- a/src/components.rs +++ b/src/components.rs @@ -3,8 +3,17 @@ use std::sync::Arc; use rapier3d::dynamics::{RigidBody, RigidBodyHandle}; use rapier3d::geometry::ColliderHandle; use rapier3d::geometry::Collider as r3dCollider; +use std::time::{Duration, Instant}; // a component is any type that is 'static, sized, send and sync + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct LoopState { + pub delta_time: Duration, + pub start_time: Instant, + pub step_size: f32, +} + #[derive(Clone, Copy, Debug, PartialEq)] pub struct Position { pub x: f32, diff --git a/src/main.rs b/src/main.rs index dab36ec..56093a4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,10 +30,10 @@ use winit::{ use gilrs::Event as GilEvent; use crate::camera::{CameraController, Camera}; -use crate::components::{Collider, Color, Physics, Position}; +use crate::components::{Collider, Color, Physics, Position, LoopState}; use crate::physics::PhysicsState; use crate::render::Renderer; -use crate::owned_event::TrEventExtension; +use crate::owned_event::{OwnedEventExtension, OwnedEvent}; use gilrs::{Gamepad, Gilrs}; use rapier3d::counters::Timer; @@ -85,12 +85,10 @@ fn main() { (local_pool, spawner) }; - // Schedule for the render systen let mut render_schedule = Schedule::builder() .add_system(render::render_test_system()) .build(); - // TODO schedule for the update system and others let mut update_schedule = Schedule::builder() .add_system(physics::update_camera_system()) .add_system(physics::run_physics_system()) @@ -98,7 +96,11 @@ fn main() { // next system here, gamelogic update system? .build(); - let event_loop = EventLoop::::with_user_event(); + let mut event_schedule = Schedule::builder() + .add_system(owned_event::event_dispatch_system()) + .build(); + + let event_loop = EventLoop::::with_user_event(); let mut builder = winit::window::WindowBuilder::new(); builder = builder.with_title("MVGE"); @@ -126,10 +128,15 @@ fn main() { resources.insert(physics_state); resources.insert(physics_pipeline); - resources.insert(CameraController::new(1.0, 1.0)); - resources.insert(Instant::now()); + resources.insert(LoopState { + delta_time: Default::default(), + start_time: Instant::now(), + step_size: 0.005, + }); + resources.insert(Vec::>::new()); + let event_loop_proxy = event_loop.create_proxy(); std::thread::spawn(move || { @@ -148,7 +155,7 @@ fn main() { while let Some(GilEvent { id, event, time }) = gilrs.next_event() { println!("{:?} New event from {}: {:?}", time, id, event); active_gamepad = Some(id); - event_loop_proxy.send_event(TrEventExtension::GamepadEvent { + event_loop_proxy.send_event(OwnedEventExtension::GamepadEvent { gil_event: GilEvent { id, event, time } }).ok(); } @@ -164,19 +171,15 @@ fn main() { } }); - - - let step_size: f32 = 0.005; let mut elapsed_time: f32 = { // deltatime since last frame - let last_frame = resources.get::().unwrap(); - last_frame.elapsed() + let loop_state = resources.get::().unwrap(); + loop_state.start_time.elapsed() }.as_secs_f32(); let mut delta_time: f32 = 0.0; let mut accumulator_time: f32 = 0.0; let mut current_time: f32 = elapsed_time; - event_loop.run(move |event, _, control_flow| { // Artificially slows the loop rate to 10 millis // This is called after redraw events cleared @@ -184,12 +187,17 @@ fn main() { *control_flow = ControlFlow::Poll; match event { + event::Event::NewEvents(cause) => { + event_schedule.execute(&mut world, &mut resources); + resources.get_mut::>>() + .unwrap().clear(); + } event::Event::MainEventsCleared => { - elapsed_time = { // deltatime since last frame - let last_frame = resources.get::().unwrap(); - last_frame.elapsed() - }.as_secs_f32(); + let (step_size, elapsed_time) = { // deltatime since last frame + let loop_state = resources.get::().unwrap(); + (loop_state.step_size, loop_state.start_time.elapsed().as_secs_f32()) + }; delta_time = elapsed_time - current_time; current_time = elapsed_time; if delta_time > 0.02 { @@ -197,35 +205,15 @@ fn main() { } accumulator_time += delta_time; - - let dt = { // deltatime since last frame - let last_frame = resources.get::().unwrap(); - last_frame.elapsed() - }; - - update_schedule.execute(&mut world, &mut resources); - - // ask for a redraw every 20 millis - if dt > Duration::from_millis(20) { - + while ((accumulator_time - step_size) >= step_size) { + accumulator_time -= step_size; + // ==== DELTA TIME LOCKED ==== + update_schedule.execute(&mut world, &mut resources); } - // update the world time here for next update - resources.insert(Instant::now()); - + // ==== FPS LOCKED ==== render_schedule.execute(&mut world, &mut resources); } - event::Event::DeviceEvent { - event: MouseMotion { delta }, - .. - } => { - resources - .get_mut::() - .unwrap() - .cam_look_delta((delta.0, delta.1)); - - //swap_chain = device.create_swap_chain(&surface, &sc_desc); - } // Resizing will queue a request_redraw event::Event::WindowEvent { event: WindowEvent::Resized(size), @@ -239,51 +227,37 @@ fn main() { .get_mut::() .unwrap() .resize(width, height); - - //swap_chain = device.create_swap_chain(&surface, &sc_desc); } - event::Event::WindowEvent { event, .. } => match event { - WindowEvent::KeyboardInput { - input: - event::KeyboardInput { - virtual_keycode: Some(event::VirtualKeyCode::Escape), - state: event::ElementState::Pressed, - .. - }, - .. - } - | WindowEvent::CloseRequested => { - *control_flow = ControlFlow::Exit; - } - _ => { - //renderer.update(event); - } - }, + event::Event::WindowEvent { event: WindowEvent::CloseRequested, .. } => { + *control_flow = ControlFlow::Exit + } event::Event::RedrawRequested(_) => { // Call the render system render_schedule.execute(&mut world, &mut resources); } _ => {} } + + resources.get_mut::>>() + .unwrap().push(event.into()); }); } pub fn entity_loading(world: &mut World, renderer: &mut Renderer) { let monkey_mesh = renderer.load_mesh_to_buffer("./resources/monkey.obj"); - - - // let camera_ent: Entity = world.push(( - // Camera { - // position: Point3 { - // x: 5.0, - // y: 5.0, - // z: 5.0 - // }, - // yaw: Rad(45.0), - // pitch: Rad(45.0) - // } - // )); + let camera_ent: Entity = world.push(( + Camera { + position: Point3 { + x: 5.0, + y: 5.0, + z: 5.0 + }, + yaw: Rad(0.0), + pitch: Rad(-75.0) + }, + CameraController::new(1.0, 1.0), + )); let light_entity: Entity = world.push(( cgmath::Point3 { diff --git a/src/owned_event.rs b/src/owned_event.rs index b0ad4ad..639176c 100644 --- a/src/owned_event.rs +++ b/src/owned_event.rs @@ -1,17 +1,25 @@ -use winit::window::{WindowId, Theme}; -use winit::event::{WindowEvent, DeviceId, DeviceEvent, KeyboardInput, ModifiersState, MouseScrollDelta, TouchPhase, ElementState, MouseButton, AxisId, Touch, StartCause, Event}; -use winit::dpi::{PhysicalPosition, PhysicalSize}; -use gilrs::Event as GilEvent; use std::path::PathBuf; +use gilrs::Event as GilEvent; +use legion::world::SubWorld; +use legion::*; +use winit::dpi::{PhysicalPosition, PhysicalSize}; +use winit::event::DeviceEvent::MouseMotion; +use winit::event::{ + AxisId, DeviceEvent, DeviceId, ElementState, Event, KeyboardInput, ModifiersState, MouseButton, + MouseScrollDelta, StartCause, Touch, TouchPhase, WindowEvent, +}; +use winit::window::{Theme, WindowId}; + +use crate::camera::{Camera, CameraController}; + #[derive(Clone)] -pub enum TrUIEvent { - UIEvent(T) +pub enum OwnedUIEvent { + UIEvent(T), } #[derive(Clone)] -pub enum TrEventExtension { - +pub enum OwnedEventExtension { /// Custom events here MouseHeldEvent {}, KeyHeldEvent {}, @@ -21,8 +29,7 @@ pub enum TrEventExtension { } #[derive(Clone, Debug)] -pub enum TrEvent { - +pub enum OwnedEvent { /// Custom events here MouseHeldEvent {}, KeyHeldEvent {}, @@ -34,7 +41,7 @@ pub enum TrEvent { NewEvents(StartCause), WindowEvent { window_id: WindowId, - event: TrWindowEvent, + event: OwnedWindowEvent, }, DeviceEvent { device_id: DeviceId, @@ -49,114 +56,127 @@ pub enum TrEvent { LoopDestroyed, } - -impl From> for TrEvent { +impl From> for OwnedEvent { fn from(event: Event) -> Self { match event { - Event::NewEvents(cause) => { - TrEvent::NewEvents(cause) - }, - Event::WindowEvent { window_id: window_id, event: event } => { - TrEvent::WindowEvent { - window_id: window_id, - event: match event { - WindowEvent::AxisMotion { device_id, axis, value } => { - TrWindowEvent::AxisMotion { device_id, axis, value } - }, - WindowEvent::Resized(physical_size) => { - TrWindowEvent::Resized(physical_size) - } - WindowEvent::Moved(physical_position) => { - TrWindowEvent::Moved(physical_position) - } - WindowEvent::CloseRequested => { - TrWindowEvent::CloseRequested - } - WindowEvent::Destroyed => { - TrWindowEvent::Destroyed - } - WindowEvent::DroppedFile(path_buf) => { - TrWindowEvent::DroppedFile(path_buf) - } - WindowEvent::HoveredFile(path_buf) => { - TrWindowEvent::HoveredFile(path_buf) - } - WindowEvent::HoveredFileCancelled => { - TrWindowEvent::HoveredFileCancelled - } - WindowEvent::ReceivedCharacter(char) => { - TrWindowEvent::ReceivedCharacter(char) - } - WindowEvent::Focused(bool) => { - TrWindowEvent::Focused(bool) - } - WindowEvent::KeyboardInput { device_id: device_id, input: input, is_synthetic: is_synthetic } => { - TrWindowEvent::KeyboardInput { device_id, input, is_synthetic } - } - WindowEvent::ModifiersChanged(modifiers_state) => { - TrWindowEvent::ModifiersChanged(modifiers_state) - } - WindowEvent::CursorMoved { device_id: device_id, position: position, modifiers: modifiers } => { - TrWindowEvent::CursorMoved { device_id, position, modifiers } - } - WindowEvent::CursorEntered { device_id: device_id } => { - TrWindowEvent::CursorEntered { device_id } - } - WindowEvent::CursorLeft { device_id: device_id } => { - TrWindowEvent::CursorLeft { device_id } - } - WindowEvent::MouseWheel { device_id: device_id, delta: delta, phase: phase, modifiers: modifiers } => { - TrWindowEvent::MouseWheel { device_id, delta, phase, modifiers } - } - WindowEvent::MouseInput { device_id: device_id, state: state, button: button, modifiers: modifiers } => { - TrWindowEvent::MouseInput { device_id, state, button, modifiers } - } - WindowEvent::TouchpadPressure { device_id: device_id, pressure: pressure, stage: stage } => { - TrWindowEvent::TouchpadPressure { device_id, pressure, stage } - } - WindowEvent::Touch(touch) => { - TrWindowEvent::Touch(touch) - } - WindowEvent::ScaleFactorChanged { scale_factor: scale_factor, new_inner_size: new_inner_size } => { - TrWindowEvent::ScaleFactorChanged { scale_factor, new_inner_size: PhysicalSize { width: new_inner_size.width, height: new_inner_size.height } } - } - WindowEvent::ThemeChanged(theme) => { - TrWindowEvent::ThemeChanged(theme) - } + Event::NewEvents(cause) => OwnedEvent::NewEvents(cause), + Event::WindowEvent { + window_id: window_id, + event: event, + } => OwnedEvent::WindowEvent { + window_id: window_id, + event: match event { + WindowEvent::AxisMotion { + device_id, + axis, + value, + } => OwnedWindowEvent::AxisMotion { + device_id, + axis, + value, + }, + WindowEvent::Resized(physical_size) => OwnedWindowEvent::Resized(physical_size), + WindowEvent::Moved(physical_position) => { + OwnedWindowEvent::Moved(physical_position) } - } - } - Event::DeviceEvent { device_id: device_id, event: event } => { - TrEvent::DeviceEvent { device_id, event } - } - Event::UserEvent(user_event) => { - TrEvent::UserEvent(user_event) - } - Event::Suspended => { - TrEvent::Suspended - } - Event::Resumed => { - TrEvent::Resumed - } - Event::MainEventsCleared => { - TrEvent::MainEventsCleared - } - Event::RedrawRequested(window_id) => { - TrEvent::RedrawRequested(window_id) - } - Event::RedrawEventsCleared => { - TrEvent::RedrawEventsCleared - } - Event::LoopDestroyed => { - TrEvent::LoopDestroyed - } + WindowEvent::CloseRequested => OwnedWindowEvent::CloseRequested, + WindowEvent::Destroyed => OwnedWindowEvent::Destroyed, + WindowEvent::DroppedFile(path_buf) => OwnedWindowEvent::DroppedFile(path_buf), + WindowEvent::HoveredFile(path_buf) => OwnedWindowEvent::HoveredFile(path_buf), + WindowEvent::HoveredFileCancelled => OwnedWindowEvent::HoveredFileCancelled, + WindowEvent::ReceivedCharacter(char) => { + OwnedWindowEvent::ReceivedCharacter(char) + } + WindowEvent::Focused(bool) => OwnedWindowEvent::Focused(bool), + WindowEvent::KeyboardInput { + device_id: device_id, + input: input, + is_synthetic: is_synthetic, + } => OwnedWindowEvent::KeyboardInput { + device_id, + input, + is_synthetic, + }, + WindowEvent::ModifiersChanged(modifiers_state) => { + OwnedWindowEvent::ModifiersChanged(modifiers_state) + } + WindowEvent::CursorMoved { + device_id: device_id, + position: position, + modifiers: modifiers, + } => OwnedWindowEvent::CursorMoved { + device_id, + position, + modifiers, + }, + WindowEvent::CursorEntered { + device_id: device_id, + } => OwnedWindowEvent::CursorEntered { device_id }, + WindowEvent::CursorLeft { + device_id: device_id, + } => OwnedWindowEvent::CursorLeft { device_id }, + WindowEvent::MouseWheel { + device_id: device_id, + delta: delta, + phase: phase, + modifiers: modifiers, + } => OwnedWindowEvent::MouseWheel { + device_id, + delta, + phase, + modifiers, + }, + WindowEvent::MouseInput { + device_id: device_id, + state: state, + button: button, + modifiers: modifiers, + } => OwnedWindowEvent::MouseInput { + device_id, + state, + button, + modifiers, + }, + WindowEvent::TouchpadPressure { + device_id: device_id, + pressure: pressure, + stage: stage, + } => OwnedWindowEvent::TouchpadPressure { + device_id, + pressure, + stage, + }, + WindowEvent::Touch(touch) => OwnedWindowEvent::Touch(touch), + WindowEvent::ScaleFactorChanged { + scale_factor: scale_factor, + new_inner_size: new_inner_size, + } => OwnedWindowEvent::ScaleFactorChanged { + scale_factor, + new_inner_size: PhysicalSize { + width: new_inner_size.width, + height: new_inner_size.height, + }, + }, + WindowEvent::ThemeChanged(theme) => OwnedWindowEvent::ThemeChanged(theme), + }, + }, + Event::DeviceEvent { + device_id: device_id, + event: event, + } => OwnedEvent::DeviceEvent { device_id, event }, + Event::UserEvent(user_event) => OwnedEvent::UserEvent(user_event), + Event::Suspended => OwnedEvent::Suspended, + Event::Resumed => OwnedEvent::Resumed, + Event::MainEventsCleared => OwnedEvent::MainEventsCleared, + Event::RedrawRequested(window_id) => OwnedEvent::RedrawRequested(window_id), + Event::RedrawEventsCleared => OwnedEvent::RedrawEventsCleared, + Event::LoopDestroyed => OwnedEvent::LoopDestroyed, } } } #[derive(Debug, PartialEq, Clone)] -pub enum TrWindowEvent { - +pub enum OwnedWindowEvent { Resized(PhysicalSize), Moved(PhysicalPosition), CloseRequested, @@ -178,8 +198,12 @@ pub enum TrWindowEvent { #[deprecated = "Deprecated in favor of WindowEvent::ModifiersChanged"] modifiers: ModifiersState, }, - CursorEntered { device_id: DeviceId }, - CursorLeft { device_id: DeviceId }, + CursorEntered { + device_id: DeviceId, + }, + CursorLeft { + device_id: DeviceId, + }, MouseWheel { device_id: DeviceId, delta: MouseScrollDelta, @@ -210,4 +234,61 @@ pub enum TrWindowEvent { new_inner_size: PhysicalSize, }, ThemeChanged(Theme), -} \ No newline at end of file +} + +/// Because I am a glutton for punishment I am going to just do a mono-event-dispatch-magoooo +#[system] +#[write_component(Camera)] +#[write_component(CameraController)] +pub fn event_dispatch( + world: &mut SubWorld, + #[resource] event_stack: &mut Vec>, +) { + use winit::event::Event::DeviceEvent; + + for event in event_stack { + match event { + OwnedEvent::DeviceEvent { + event: MouseMotion { delta }, + .. + } => { + let mut query = <(&mut CameraController)>::query(); + for (camera_controller) in query.iter_mut(world) { + camera_controller.process_mouse(delta.0, delta.1); + } + } + + OwnedEvent::DeviceEvent { device_id, event } => { + match event { + winit::event::DeviceEvent::Key(keyboard_input) => { + let mut query = <(&mut CameraController)>::query(); + for (camera_controller) in query.iter_mut(world) { + camera_controller.process_keyboard( + keyboard_input.virtual_keycode.unwrap(), + keyboard_input.state, + ); + } + + // match keyboard_input.virtual_keycode.unwrap() { + // VirtualKeyCode::A => { + // if keyboard_input.state == ElementState::Pressed {} + // } + // VirtualKeyCode::S => { + // if keyboard_input.state == ElementState::Pressed {} + // } + // VirtualKeyCode::P => { + // if keyboard_input.state == ElementState::Pressed { + // let data = world.write_resource::().read_compute_buffer(compute_buffer.clone()); + // image::save_buffer(&Path::new("image.png"), data.as_slice(), (image_data.1).0, (image_data.1).1, image::RGBA(8)); + // } + // } + // _ => () + // } + } + _ => {} + } + } + _ => {} + } + } +} diff --git a/src/physics.rs b/src/physics.rs index ec6e48b..b8873b4 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -7,7 +7,7 @@ use legion::*; use crate::render::{EntityUniforms, Renderer}; use cgmath::Quaternion; -use crate::components::{Collider, Physics, Mesh, Position}; +use crate::components::{Collider, Physics, Mesh, Position, LoopState}; use crate::camera::{CameraController, Camera}; use std::time::Instant; @@ -83,16 +83,15 @@ pub fn run_physics( #[system] #[write_component(Camera)] +#[write_component(CameraController)] pub fn update_camera( world: &mut SubWorld, - #[resource] camera_controller: &mut CameraController, - #[resource] last_frame: &mut Instant, + #[resource] loop_state: &mut LoopState, ) { - let mut query = <(&mut Camera)>::query(); - for (camera) in query.iter_mut(world) { - //camera.update_camera() + let mut query = <(&mut Camera, &mut CameraController)>::query(); + for (mut camera, controller) in query.iter_mut(world) { + controller.update_camera(&mut camera, loop_state.step_size) } - } #[system] diff --git a/src/render.rs b/src/render.rs index 91c6918..190addb 100644 --- a/src/render.rs +++ b/src/render.rs @@ -3,14 +3,17 @@ use std::{iter, num::NonZeroU32, ops::Range, rc::Rc}; use bytemuck::__core::mem; use bytemuck::{Pod, Zeroable}; -use cgmath::{vec3, Decomposed, Deg, Euler, InnerSpace, Matrix4, Point3, Quaternion, Rotation3, Transform, Vector3, Rad}; +use cgmath::{ + vec3, Decomposed, Deg, Euler, InnerSpace, Matrix4, Point3, Quaternion, Rad, Rotation3, + Transform, Vector3, +}; use futures::executor::LocalPool; use legion::world::SubWorld; use legion::*; use rapier3d::parry::motion::RigidMotionComposition; use wgpu::util::DeviceExt; use wgpu::{ - BindGroup, BindGroupLayout, Buffer, Device, Instance, Queue, Surface, SwapChain, + BackendBit, BindGroup, BindGroupLayout, Buffer, Device, Instance, Queue, Surface, SwapChain, SwapChainDescriptor, SwapChainFrame, TextureView, }; use winit::dpi::PhysicalSize; @@ -69,43 +72,14 @@ pub struct Pass { uniform_buf: wgpu::Buffer, } -pub struct Renderer { - swapchain: SwapChain, - swapchain_description: SwapChainDescriptor, - instance: Arc, - device: Arc, - queue: Arc, - - size: PhysicalSize, - surface: Arc, - - lights_are_dirty: bool, - shadow_pass: Pass, - shadow_target_views: Vec>, - views_given: u32, - - forward_pass: Pass, - forward_depth: wgpu::TextureView, - - entity_bind_group_layout: BindGroupLayout, - - light_uniform_buf: wgpu::Buffer, - - camera_projection: Matrix4, -} - #[system] +#[write_component(Camera)] #[write_component(Position)] #[write_component(Point3)] #[write_component(Mesh)] #[write_component(Color)] #[write_component(DirectionalLight)] -pub fn render_test( - world: &mut SubWorld, - #[resource] renderer: &mut Renderer, - #[resource] camera_controller: &mut CameraController, -) { - +pub fn render_test(world: &mut SubWorld, #[resource] renderer: &mut Renderer) { let mut encoder = renderer .device .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); @@ -113,6 +87,17 @@ pub fn render_test( let frame = renderer.get_current_frame(); + let mut query = <(&mut Camera)>::query(); + for (camera) in query.iter_mut(world) { + let matrix = camera.calc_matrix(renderer.camera_projection); + let mx_ref: &[f32; 16] = matrix.as_ref(); + renderer.queue.write_buffer( + &renderer.forward_pass.uniform_buf, + 0, + bytemuck::cast_slice(mx_ref), + ); + } + let mut query = <(&mut Position, &mut Mesh, &mut Color)>::query(); let mut mesh_stack = Vec::new(); @@ -240,6 +225,31 @@ pub fn render_test( renderer.queue.submit(iter::once(encoder.finish())); } +pub struct Renderer { + swapchain: SwapChain, + swapchain_description: SwapChainDescriptor, + instance: Arc, + device: Arc, + queue: Arc, + + size: PhysicalSize, + surface: Arc, + + lights_are_dirty: bool, + shadow_pass: Pass, + shadow_target_views: Vec>, + views_given: u32, + + forward_pass: Pass, + forward_depth: wgpu::TextureView, + + entity_bind_group_layout: BindGroupLayout, + + light_uniform_buf: wgpu::Buffer, + + camera_projection: Matrix4, +} + impl Renderer { const MAX_LIGHTS: usize = 10; const SHADOW_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float; @@ -250,71 +260,21 @@ impl Renderer { }; const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float; - pub fn generate_matrix(aspect_ratio: f32) -> cgmath::Matrix4 { + /// Generate a projection matrix with no look-at yet + pub fn generate_matrix(&self) -> cgmath::Matrix4 { // Specifies the aspect ratio that determines the field of view in the x direction. // The aspect ratio is the ratio of x (width) to y (height). - let mx_projection = cgmath::perspective(cgmath::Deg(75f32), aspect_ratio, 1.0, 20.0); - let mx_view = cgmath::Matrix4::look_at( - cgmath::Point3::new(1.0f32, 1.0, 4.0), - cgmath::Point3::new(0.0f32, 0.0, 0.0), - cgmath::Vector3::unit_z(), - ); - - let mx_correction = OPENGL_TO_WGPU_MATRIX; - mx_correction * mx_projection * mx_view - } - - pub fn cam_look_delta(&mut self, delta: (f64, f64)) { - - // let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 20.0); - // let mx_view = cgmath::Matrix4::look_at( - // cgmath::Point3::new(3.0f32, -9.0, 6.0), - // cgmath::Point3::new(0f32, 0.0, 0.0), - // cgmath::Vector3::unit_z(), - // ); - // let mx_correction = OPENGL_TO_WGPU_MATRIX; - // let mx_total = mx_correction * mx_projection * mx_view; - // - // let rotation = Quaternion::from(Euler { - // x: Deg(90.0), - // y: Deg(45.0), - // z: Deg(15.0), - // }); - // - // Euler { - // x: (), - // y: (), - // z: () - // }; - // - // let offset = cgmath::vec3(1.0, 1.0, 4.0); - // let transform = Decomposed { - // disp: offset.clone(), - // rot: Quaternion::from_axis_angle(offset.normalize(), Deg(50.0)), - // scale: 1.0, - // }; - // - // let mut q = Quaternion::from(self.camera_direction); - // q.v.z += delta.0 as f32; - // q.v.y += delta.1 as f32; - // //let q2 = Quaternion::from_angle_x(Deg(delta.0 as f32)); - // //let q3 = Quaternion::from_angle_y(Deg(delta.1 as f32)); - // let w = Matrix4::from(q); - // //mx_total = mx_total + w; - // - // self.camera_projection = transform.into(); - // let mut mx_total = self.camera_projection.clone(); - // - // let mx_ref: &[f32; 16] = mx_total.as_ref(); - // self.queue.write_buffer( - // &self.forward_pass.uniform_buf, - // 0, - // bytemuck::cast_slice(mx_ref), - // ); + cgmath::perspective( + cgmath::Deg(75f32), + self.size.width as f32 / self.size.height as f32, + 1.0, + 20.0, + ) } + /// Get the next frame from the swapchain + /// (recreates if something funky goes on) pub fn get_current_frame(&mut self) -> SwapChainFrame { - // Update the renderers swapchain state match self.swapchain.get_current_frame() { Ok(frame) => frame, Err(_) => { @@ -328,6 +288,8 @@ impl Renderer { } } + /// Create a bare vertex & indices buffer + /// TODO I really should remove this / consolidate it pub fn create_buffer( device: &wgpu::Device, indices: Vec, @@ -352,6 +314,9 @@ impl Renderer { (vertex_buf, index_buf) } + /// When creating a light we have to give it a target view to render to + /// This is major danger scary since we have a 10 light limit, and only + /// 2 views created at this moment, need to smarten this up pub fn create_light(&mut self) -> DirectionalLight { let target = self .shadow_target_views @@ -375,6 +340,7 @@ impl Renderer { } } + /// I don't know why the hell this is still in here pub fn create_plane(&self, size: f32) -> Mesh { let vertices = [ vertex([size, -size, 0.0], [0.0, 0.0, 1.0]), @@ -701,7 +667,12 @@ impl Renderer { }) .collect::>(); - let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); + let mx_projection = cgmath::perspective( + cgmath::Deg(75f32), // FOV, might wanna hook this up somewhere + sc_desc.width as f32 / sc_desc.height as f32, + 1.0, + 20.0, + ); let forward_pass = { // Create pipeline layout @@ -758,7 +729,7 @@ impl Renderer { // I need to know the number of lights... let forward_uniforms = ForwardUniforms { - proj: *mx_total.as_ref(), + proj: *mx_projection.as_ref(), //num_lights: [lights.len() as u32, 0, 0, 0], num_lights: [2 as u32, 0, 0, 0], }; @@ -883,7 +854,7 @@ impl Renderer { surface, instance: Arc::new(instance), views_given: 0, - camera_projection: mx_total, + camera_projection: mx_projection, } } @@ -903,7 +874,7 @@ impl Renderer { .create_swap_chain(&self.surface, &self.swapchain_description.clone()); // update view-projection matrix - let mx_total = Self::generate_matrix(width as f32 / height as f32); + let mx_total = self.generate_matrix(); let mx_ref: &[f32; 16] = mx_total.as_ref(); self.queue.write_buffer( &self.forward_pass.uniform_buf,