improved fullscreening
This commit is contained in:
parent
e938fed68e
commit
8bc0ea9880
@ -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,
|
||||
|
119
src/main.rs
119
src/main.rs
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user