improved fullscreening

This commit is contained in:
aiden 2023-05-14 07:49:41 +01:00
parent e938fed68e
commit 8bc0ea9880
Signed by: aiden
GPG Key ID: EFA9C74AEBF806E0
2 changed files with 82 additions and 62 deletions

@ -5,8 +5,8 @@ use crate::Input;
#[derive(Debug)]
pub struct Camera {
pub position: Point3<f32>,
pub yaw: Rad<f32>,
pub pitch: Rad<f32>,
pub rot_x: Rad<f32>,
pub rot_y: Rad<f32>,
aspect: f32,
fovy: Rad<f32>,
@ -23,13 +23,13 @@ impl Camera {
dimensions: winit::dpi::PhysicalSize<u32>,
position: V,
yaw: Y,
pitch: P
rot_x: Y,
rot_y: P
) -> Self {
Self {
position: position.into(),
yaw: yaw.into(),
pitch: pitch.into(),
rot_x: rot_x.into(),
rot_y: rot_y.into(),
aspect: dimensions.width as f32 / dimensions.height as f32,
fovy: Deg(45.0).into(),
@ -48,7 +48,7 @@ impl Camera {
let dt = dt.as_secs_f32();
// Move forward/backward and left/right
let (yaw_sin, yaw_cos) = self.yaw.0.sin_cos();
let (yaw_sin, yaw_cos) = self.rot_x.0.sin_cos();
let forward = Vector3::new(yaw_cos, 0.0, yaw_sin).normalize();
let right = Vector3::new(-yaw_sin, 0.0, yaw_cos).normalize();
self.position += forward * (input.amount_forward - input.amount_backward) * input.speed * dt;
@ -59,13 +59,12 @@ impl Camera {
self.position.y += (input.amount_up - input.amount_down) * input.speed * dt;
// Rotate
self.yaw += Rad(input.rotate_horizontal) * input.sensitivity * dt;
println!("{:?}", Deg::from(self.yaw));
self.rot_x += Rad(input.rotate_horizontal) * input.sensitivity * dt;
let pitch = (self.pitch + Rad(-input.rotate_vertical) * input.sensitivity * dt).0;
let pitch = (self.rot_y + Rad(-input.rotate_vertical) * input.sensitivity * dt).0;
let frac = std::f32::consts::FRAC_PI_2 - 0.0001;
self.pitch = Rad(pitch.clamp(-Rad(frac).0, Rad(frac).0));
self.rot_y = Rad(pitch.clamp(-Rad(frac).0, Rad(frac).0));
}
}
@ -94,8 +93,8 @@ impl<'a> CameraUniform {
}
}
pub fn set_view_projection_matrix(&self, queue: &wgpu::Queue, camera: &Camera) {
let (sin_pitch, cos_pitch) = camera.pitch.0.sin_cos();
let (sin_yaw, cos_yaw) = camera.yaw.0.sin_cos();
let (sin_yaw, cos_yaw) = camera.rot_x.0.sin_cos();
let (sin_pitch, cos_pitch) = camera.rot_y.0.sin_cos();
let target = Vector3::new(
cos_pitch * cos_yaw,

@ -7,7 +7,7 @@ use state::State;
mod camera;
use camera::Camera;
use winit::event::{VirtualKeyCode, ElementState, KeyboardInput, WindowEvent};
use winit::{event::{VirtualKeyCode, ElementState, KeyboardInput, WindowEvent, MouseButton}, window::Window};
#[derive(Debug)]
pub struct Input {
@ -39,35 +39,29 @@ impl Input {
}
}
pub fn process_keyboard(&mut self, key: VirtualKeyCode, state: ElementState) -> bool{
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;
true
}
VirtualKeyCode::J | VirtualKeyCode::Left => {
self.amount_left = amount;
true
}
VirtualKeyCode::K | VirtualKeyCode::Down => {
self.amount_backward = amount;
true
}
VirtualKeyCode::L | VirtualKeyCode::Right => {
self.amount_right = amount;
true
}
VirtualKeyCode::Space => {
self.amount_up = amount;
true
}
VirtualKeyCode::Semicolon => {
self.amount_down = amount;
true
}
_ => false,
}
_ => ()
};
}
pub fn process_mouse(&mut self, (dx, dy): (f64, f64)) {
@ -76,32 +70,46 @@ impl Input {
}
}
fn set_fullscreen(to: bool, window: &Window) -> bool {
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()))
);
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");
}
return to;
}
fn real_main() -> Result<(), &'static str> {
let event_loop = EventLoop::new();
let window = WindowBuilder::new()
.with_title("game")
.build(&(event_loop))
.map_err(|_| "failed to create window")?;
fn area(size: winit::dpi::PhysicalSize<u32>) -> u32 {
size.width * size.height
}
let video_modes = window.current_monitor().unwrap().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;
}
}).unwrap();
window.set_fullscreen(
Some(winit::window::Fullscreen::Exclusive(video_mode))
);
window.set_cursor_visible(false);
let mut fullscreen = set_fullscreen(false, &(window));
let mut state = State::new(window)?;
let mut input = Input::new(1.0, 0.088 * 31.4);
@ -113,15 +121,24 @@ fn real_main() -> Result<(), &'static str> {
event_loop.run(move |event, _, flow| {
*flow = ControlFlow::Poll;
let window = state.window();
window.set_cursor_grab(winit::window::CursorGrabMode::Confined).expect("failed to lock cursor");
match event {
Event::Event::DeviceEvent {
event: Event::DeviceEvent::MouseMotion { delta, },
..
} => {
input.process_mouse(delta);
}
Event::Event::WindowEvent { window_id, event } if window_id == window.id() => match event {
WindowEvent::MouseInput { state, button, .. } => {
if button == MouseButton::Left && state == ElementState::Pressed && !fullscreen {
fullscreen = set_fullscreen(true, &(window));
}
}
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 {
@ -130,18 +147,21 @@ fn real_main() -> Result<(), &'static str> {
..
},
..
} => { input.process_keyboard(key, state); }
WindowEvent::CloseRequested => {
*flow = ControlFlow::Exit;
},
WindowEvent::Resized(physical_size) => {
state.reconfigure(Some(physical_size));
} if fullscreen => match key {
VirtualKeyCode::Escape if state == ElementState::Pressed => {
fullscreen = set_fullscreen(false, &(window));
}
_ => input.process_keyboard(key, state),
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
state.reconfigure(Some(*new_inner_size));
}
_ => (),
_ => ()
}
Event::Event::DeviceEvent {
event: Event::DeviceEvent::MouseMotion { delta, }, ..
} if fullscreen => {
input.process_mouse(delta);
}
Event::Event::MainEventsCleared => {
let now = std::time::Instant::now();
let dt = now - last_render_time;
@ -160,9 +180,10 @@ fn real_main() -> Result<(), &'static str> {
frames += 1;
let now = std::time::Instant::now();
if now.duration_since(timer).as_millis() > 1000 {
let time = now.duration_since(timer).as_millis();
if time > 1000 {
timer = now;
println!("{:?}", frames);
println!("frames in the past {time}ms: {:?}", frames);
frames = 0;
}
}