mirror of
https://github.com/guilhermewerner/wgpu-renderer
synced 2025-06-15 05:14:20 +00:00
115 lines
4.5 KiB
Rust
115 lines
4.5 KiB
Rust
use crate::Render::Renderer;
|
|
use crate::State;
|
|
use anyhow::Result;
|
|
use std::time::Instant;
|
|
use winit::dpi::LogicalSize;
|
|
use winit::event::*;
|
|
use winit::event_loop::{ControlFlow, EventLoop};
|
|
use winit::monitor::{MonitorHandle, VideoMode};
|
|
use winit::window::{Fullscreen, WindowBuilder};
|
|
|
|
/// Runtime state executor and event loop.
|
|
pub struct Runtime;
|
|
|
|
impl Runtime {
|
|
pub fn Execute<T: State>() -> Result<()> {
|
|
env_logger::init();
|
|
|
|
let event_loop = EventLoop::new();
|
|
|
|
//let monitor = event_loop.available_monitors().nth(0);
|
|
|
|
let window = WindowBuilder::new()
|
|
.with_title("Graphics")
|
|
//.with_fullscreen(Some(Fullscreen::Borderless(monitor)))
|
|
.with_inner_size(LogicalSize::new(1280, 720))
|
|
.build(&event_loop)?;
|
|
|
|
let mut renderer = pollster::block_on(Renderer::New(window))?;
|
|
|
|
let mut app = T::Init(&renderer)?;
|
|
|
|
let mut last_update = Instant::now();
|
|
|
|
let mut is_resumed = true;
|
|
let mut is_focused = true;
|
|
let mut is_redraw_requested = true;
|
|
|
|
event_loop.run(move |event, _, control_flow| {
|
|
*control_flow = if is_resumed && is_focused {
|
|
ControlFlow::Poll
|
|
} else {
|
|
ControlFlow::Wait
|
|
};
|
|
|
|
match event {
|
|
Event::Resumed => is_resumed = true,
|
|
Event::Suspended => is_resumed = false,
|
|
Event::RedrawRequested(window_id) => {
|
|
if window_id == renderer.window.id() {
|
|
let now = Instant::now();
|
|
let delta = now - last_update;
|
|
last_update = now;
|
|
|
|
app.Update(&renderer, delta);
|
|
|
|
match app.Draw(&mut renderer) {
|
|
Ok(_) => {}
|
|
// Reconfigure the surface if lost
|
|
Err(wgpu::SurfaceError::Lost) => {
|
|
let size = renderer.window.inner_size();
|
|
renderer.Resize(size.width, size.height);
|
|
app.Resize(&renderer);
|
|
}
|
|
// The system is out of memory, we should probably quit
|
|
Err(wgpu::SurfaceError::OutOfMemory) => {
|
|
*control_flow = ControlFlow::Exit
|
|
}
|
|
// All other errors (Outdated, Timeout) should be resolved by the next frame
|
|
Err(e) => eprintln!("{:?}", e),
|
|
}
|
|
|
|
is_redraw_requested = false;
|
|
}
|
|
}
|
|
Event::MainEventsCleared => {
|
|
if is_focused && is_resumed && !is_redraw_requested {
|
|
renderer.window.request_redraw();
|
|
is_redraw_requested = true;
|
|
} else {
|
|
// Freeze time while the app is not in the foreground
|
|
last_update = Instant::now();
|
|
}
|
|
}
|
|
Event::WindowEvent { event, window_id } if window_id == renderer.window.id() => {
|
|
if !app.Input(&renderer, &event) {
|
|
match event {
|
|
WindowEvent::CloseRequested
|
|
| WindowEvent::KeyboardInput {
|
|
input:
|
|
KeyboardInput {
|
|
state: ElementState::Pressed,
|
|
virtual_keycode: Some(VirtualKeyCode::Escape),
|
|
..
|
|
},
|
|
..
|
|
} => *control_flow = ControlFlow::Exit,
|
|
WindowEvent::Focused(focused) => is_focused = focused,
|
|
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
|
|
renderer.Resize(new_inner_size.width, new_inner_size.height);
|
|
app.Resize(&renderer);
|
|
}
|
|
WindowEvent::Resized(physical_size) => {
|
|
renderer.Resize(physical_size.width, physical_size.height);
|
|
app.Resize(&renderer);
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
})
|
|
}
|
|
}
|