cleaned up some stuff

This commit is contained in:
aiden 2023-05-16 10:58:36 +01:00
parent c2c645ee39
commit 62e5bd3c0d
Signed by: aiden
GPG Key ID: EFA9C74AEBF806E0
4 changed files with 227 additions and 166 deletions

@ -1,6 +1,6 @@
use cgmath::{Vector3, Point3, InnerSpace, Deg, Rad};
use crate::Input;
use crate::input::Input;
#[derive(Debug)]
pub struct Camera {
@ -53,7 +53,7 @@ impl Camera {
}
pub fn update_rot(&mut self, input: &Input, sf: f32) {
// doesn't need dt because the input is not continuous.
// doesn't need dt because the input is not continuous.
let (dx, dy) = input.mouse_moved;
self.rot_x += Deg((dx / input.dots_per_deg) * sf);

59
src/input.rs Normal file

@ -0,0 +1,59 @@
use winit::event::{VirtualKeyCode, ElementState};
#[derive(Debug)]
pub struct Input {
pub amount_left: f32,
pub amount_right: f32,
pub amount_forward: f32,
pub amount_backward: f32,
pub amount_up: f32,
pub amount_down: f32,
pub mouse_moved: (f32, f32),
pub speed: f32,
pub dots_per_deg: f32,
}
impl Input {
pub fn new(speed: f32, dots_per_360deg: f32) -> Self {
Self {
amount_left: 0.0,
amount_right: 0.0,
amount_forward: 0.0,
amount_backward: 0.0,
amount_up: 0.0,
amount_down: 0.0,
mouse_moved: (0.0, 0.0),
speed,
dots_per_deg: dots_per_360deg / 360.0,
}
}
pub fn process_key(&mut self, key: VirtualKeyCode, state: ElementState) {
let amount = if state == ElementState::Pressed { 1.0 } else { 0.0 };
match key {
VirtualKeyCode::I | VirtualKeyCode::Up => {
self.amount_forward = amount;
}
VirtualKeyCode::J | VirtualKeyCode::Left => {
self.amount_left = amount;
}
VirtualKeyCode::K | VirtualKeyCode::Down => {
self.amount_backward = amount;
}
VirtualKeyCode::L | VirtualKeyCode::Right => {
self.amount_right = amount;
}
VirtualKeyCode::Space => {
self.amount_up = amount;
}
VirtualKeyCode::Semicolon => {
self.amount_down = amount;
}
_ => ()
};
}
pub fn process_mouse_motion(&mut self, (dx, dy): (f64, f64)) {
self.mouse_moved = (dx as f32, dy as f32);
}
}

@ -41,116 +41,81 @@ var inches_per_1dg = inches_per_360dg / 360;
var dots_per_1dg = inches_per_1dg * dpi;
*/
use {winit::{event as Event, event_loop::{ControlFlow, EventLoop}, window::WindowBuilder}, std::{cmp::Ordering, process::ExitCode}};
use {
std::{process::ExitCode, time::Instant},
winit::{
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
event::{VirtualKeyCode, ElementState, WindowEvent}
},
};
mod state;
use std::time::Instant;
mod camera;
mod input;
use input::Input;
use state::State;
mod camera;
use camera::Camera;
use winit::{event::{VirtualKeyCode, ElementState, KeyboardInput, WindowEvent, MouseButton}, window::Window};
fn handle_window_event(state: &mut State, event: WindowEvent) -> ControlFlow {
use WindowEvent::{*, KeyboardInput as KeyboardInputEvent};
use winit::event::{KeyboardInput, MouseButton};
#[derive(Debug)]
pub struct Input {
amount_left: f32,
amount_right: f32,
amount_forward: f32,
amount_backward: f32,
amount_up: f32,
amount_down: f32,
mouse_moved: (f32, f32),
speed: f32,
dots_per_deg: f32,
}
impl Input {
pub fn new(speed: f32, dots_per_360deg: f32) -> Self {
Self {
amount_left: 0.0,
amount_right: 0.0,
amount_forward: 0.0,
amount_backward: 0.0,
amount_up: 0.0,
amount_down: 0.0,
mouse_moved: (0.0, 0.0),
speed,
dots_per_deg: dots_per_360deg / 360.0,
match event {
MouseInput { state: elem_state, button, .. } => {
if button == MouseButton::Left && elem_state == ElementState::Pressed {
if !state.is_fullscreen() {
state.set_fullscreen(true);
} else if !state.is_focused() {
// is fullscreen but not focused
state.set_focus(true);
}
}
}
}
pub fn process_keyboard(&mut self, key: VirtualKeyCode, state: ElementState) {
let amount = if state == ElementState::Pressed { 1.0 } else { 0.0 };
match key {
VirtualKeyCode::I | VirtualKeyCode::Up => {
self.amount_forward = amount;
}
VirtualKeyCode::J | VirtualKeyCode::Left => {
self.amount_left = amount;
}
VirtualKeyCode::K | VirtualKeyCode::Down => {
self.amount_backward = amount;
}
VirtualKeyCode::L | VirtualKeyCode::Right => {
self.amount_right = amount;
}
VirtualKeyCode::Space => {
self.amount_up = amount;
}
VirtualKeyCode::Semicolon => {
self.amount_down = amount;
}
_ => ()
};
}
}
fn set_fullscreen(to: bool, window: &Window, cursor_locked: &mut bool) -> bool {
if to {
fn area(size: winit::dpi::PhysicalSize<u32>) -> u32 {
size.width * size.height
CursorLeft { .. } if state.is_focused() => {
state.set_focus(false);
}
let video_modes = window.current_monitor().expect("no monitor detected").video_modes();
let video_mode = video_modes.max_by(|x, y| {
if area(x.size()) > area(y.size()) {
return Ordering::Greater;
} else if area(x.size()) < area(y.size()) {
return Ordering::Less;
CloseRequested => {
return ControlFlow::Exit;
}
Resized(physical_size) => {
state.reconfigure(Some(physical_size));
}
ScaleFactorChanged { new_inner_size, .. } => {
state.reconfigure(Some(*new_inner_size));
}
KeyboardInputEvent {
input:
KeyboardInput {
virtual_keycode: Some(key),
state: elem_state,
..
},
..
} => match key {
VirtualKeyCode::Escape if elem_state == ElementState::Pressed => {
// toggle fullscreen
state.set_fullscreen(!state.is_fullscreen());
}
if x.refresh_rate_millihertz() > y.refresh_rate_millihertz() {
return Ordering::Greater;
} else {
return Ordering::Less;
}
}).expect("no video modes");
window.set_fullscreen(
Some(winit::window::Fullscreen::Exclusive(video_mode.clone()))
);
window.set_cursor_visible(false);
window.set_cursor_grab(winit::window::CursorGrabMode::Confined).expect("failed to lock cursor");
} else {
window.set_fullscreen(None);
window.set_cursor_visible(true);
window.set_cursor_grab(winit::window::CursorGrabMode::None).expect("failed to unlock cursor");
_ => state.process_key(key, elem_state),
}
_ => ()
}
*cursor_locked = to;
return to;
return ControlFlow::Poll;
}
fn real_main() -> Result<(), &'static str> {
let event_loop = EventLoop::new();
let window = WindowBuilder::new()
.with_title("game")
.with_fullscreen(None)
.build(&(event_loop))
.map_err(|_| "failed to create window")?;
let mut cursor_locked = false;
let mut fullscreen = set_fullscreen(false, &(window), &mut(cursor_locked));
let mut state = State::new(window)?;
let mut input = Input::new(1.0, 7368.0);
let mut state = State::new(window, Input::new(1.0, 7368.0))?;
let mut total_elapsed = 0.0;
let mut frames = 0;
@ -158,85 +123,44 @@ fn real_main() -> Result<(), &'static str> {
let mut prev_render = Instant::now();
event_loop.run(move |event, _, flow| {
use winit::event::{Event::*, DeviceEvent::MouseMotion};
let window = state.window();
*flow = ControlFlow::Poll;
match event {
Event::Event::WindowEvent { window_id, event } if window_id == window.id() => match event {
WindowEvent::MouseInput { state, button, .. } => {
if button == MouseButton::Left && state == ElementState::Pressed {
if !fullscreen {
fullscreen = set_fullscreen(true, &(window), &mut(cursor_locked));
} else if !cursor_locked {
window.set_cursor_grab(winit::window::CursorGrabMode::Confined).expect("failed to lock cursor");
window.set_cursor_visible(false);
cursor_locked = true;
}
}
}
WindowEvent::CursorLeft { .. } if fullscreen => {
window.set_cursor_grab(winit::window::CursorGrabMode::None).expect("failed to unlock cursor");
window.set_cursor_visible(true);
cursor_locked = false;
}
WindowEvent::CloseRequested => {
*flow = ControlFlow::Exit;
}
WindowEvent::Resized(physical_size) => {
state.reconfigure(Some(physical_size));
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
state.reconfigure(Some(*new_inner_size));
}
WindowEvent::KeyboardInput {
input:
KeyboardInput {
virtual_keycode: Some(key),
state,
..
},
..
} => match key {
VirtualKeyCode::Escape if state == ElementState::Pressed => {
fullscreen = set_fullscreen(!fullscreen, &(window), &mut(cursor_locked));
}
_ => input.process_keyboard(key, state),
}
_ => ()
}
Event::Event::DeviceEvent {
event: Event::DeviceEvent::MouseMotion { delta, }, ..
} if cursor_locked => {
input.mouse_moved.0 = delta.0 as f32;
input.mouse_moved.1 = delta.1 as f32;
WindowEvent { window_id, event: window_event } if window_id == window.id() => {
*flow = handle_window_event(&mut(state), window_event);
}
Event::Event::MainEventsCleared => {
DeviceEvent {
event: MouseMotion { delta, }, ..
} if state.is_focused() => {
state.process_mouse_motion(delta);
}
MainEventsCleared => {
let mut elapsed = prev_render.elapsed().as_secs_f32();
total_elapsed += elapsed;
prev_render = Instant::now();
prev_render = Instant::now();
const TIMESTEP: f32 = 1.0 / 60.0;
const TIMESTEP: f32 = 1.0 / 60.0;
let mut interpolate = 1.0;
let sf = interpolate / (elapsed / TIMESTEP);
let mut interpolate = 1.0;
let sf = interpolate / (elapsed / TIMESTEP);
while elapsed >= TIMESTEP {
state.camera.update_pos(&(input), TIMESTEP);
state.camera.update_rot(&(input), sf);
elapsed -= TIMESTEP;
interpolate -= sf;
}
state.camera.update_pos(&(input), elapsed);
state.camera.update_rot(&(input), interpolate);
input.mouse_moved = (0.0, 0.0);
while elapsed >= TIMESTEP {
state.update_camera(TIMESTEP, sf);
state.window().request_redraw();
elapsed -= TIMESTEP;
interpolate -= sf;
}
state.update_camera(elapsed, interpolate);
state.process_mouse_motion((0.0, 0.0));
state.window().request_redraw();
}
Event::Event::RedrawRequested(_) => {
state.update();
RedrawRequested(_) => {
match state.render() {
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => state.reconfigure(None),
Err(wgpu::SurfaceError::OutOfMemory) => *flow = ControlFlow::ExitWithCode(1),
@ -251,8 +175,8 @@ fn real_main() -> Result<(), &'static str> {
frames = 0;
total_elapsed = 0.0;
}
}
_ => (),
}
_ => (),
};
return;

@ -2,11 +2,15 @@ use cgmath::Deg;
use winit::window::Window;
use wgpu::{util::DeviceExt};
use crate::{Camera, camera::CameraUniform};
use crate::{camera::*, Input};
pub struct State {
input: Input,
window: Window,
size: winit::dpi::PhysicalSize<u32>,
fullscreen: bool,
focused: bool,
surface: wgpu::Surface,
device: wgpu::Device,
@ -16,7 +20,7 @@ pub struct State {
vertex_buffer: wgpu::Buffer,
pub camera: Camera,
camera: Camera,
camera_uniform: CameraUniform,
camera_bind_group: wgpu::BindGroup,
}
@ -29,7 +33,7 @@ struct Vertex {
}
impl State {
pub fn new(window: Window) -> Result<Self, &'static str> {
pub fn new(window: Window, input: Input) -> Result<Self, &'static str> {
let size = window.inner_size();
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
@ -176,6 +180,10 @@ impl State {
}));
return Ok(Self {
input,
fullscreen: false,
focused: false,
window,
size,
@ -197,6 +205,63 @@ impl State {
return &(self.window);
}
pub fn set_focus(&mut self, to: bool) {
assert!((!self.fullscreen && !to) || self.fullscreen);
assert!(to != self.focused);
let window = self.window();
if to {
window.set_cursor_visible(false);
window.set_cursor_grab(winit::window::CursorGrabMode::Confined).expect("failed to lock cursor");
} else {
window.set_cursor_visible(true);
window.set_cursor_grab(winit::window::CursorGrabMode::None).expect("failed to unlock cursor");
}
self.focused = to;
return;
}
pub fn is_focused(&self) -> bool {
return self.focused;
}
pub fn set_fullscreen(&mut self, to: bool) {
assert!(to != self.fullscreen);
use std::cmp::Ordering;
let window = self.window();
if to {
fn area(size: winit::dpi::PhysicalSize<u32>) -> u32 {
size.width * size.height
}
let video_modes = window.current_monitor().expect("no monitor detected").video_modes();
let video_mode = video_modes.max_by(|x, y| {
if area(x.size()) > area(y.size()) {
return Ordering::Greater;
} else if area(x.size()) < area(y.size()) {
return Ordering::Less;
}
if x.refresh_rate_millihertz() > y.refresh_rate_millihertz() {
return Ordering::Greater;
} else {
return Ordering::Less;
}
}).expect("no video modes");
window.set_fullscreen(
Some(winit::window::Fullscreen::Exclusive(video_mode.clone()))
);
} else {
window.set_fullscreen(None);
}
self.fullscreen = to;
self.set_focus(to);
return;
}
pub fn is_fullscreen(&self) -> bool {
return self.fullscreen;
}
pub fn reconfigure(&mut self, new_size: Option<winit::dpi::PhysicalSize<u32>>) {
let new_size = new_size.unwrap_or(self.size);
assert!(new_size.width > 0 && new_size.height > 0);
@ -205,13 +270,12 @@ impl State {
self.config.height = new_size.height;
self.surface.configure(&(self.device), &(self.config));
self.camera.reconfigure(new_size);
}
pub fn update(&mut self) {
self.camera_uniform.set_view_projection_matrix(&(self.queue), &(self.camera));
return;
}
pub fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
self.camera_uniform.set_view_projection_matrix(&(self.queue), &(self.camera));
let output = self.surface.get_current_texture()?;
let view = output.texture.create_view(&(wgpu::TextureViewDescriptor::default()));
let mut encoder = self.device.create_command_encoder(&(wgpu::CommandEncoderDescriptor {
@ -243,4 +307,18 @@ impl State {
return Ok(());
}
pub fn update_camera(&mut self, dt: f32, sf: f32) {
self.camera.update_pos(&(self.input), dt);
self.camera.update_rot(&(self.input), sf);
return;
}
pub fn process_key(&mut self, key: winit::event::VirtualKeyCode, state: winit::event::ElementState) {
self.input.process_key(key, state);
return;
}
pub fn process_mouse_motion(&mut self, delta: (f64, f64)) {
self.input.process_mouse_motion(delta);
return;
}
}