mod profile_with_puffin;
use {
clap::Parser,
log::error,
screen_13::{
Display, DisplayError, DisplayInfo,
driver::{
device::{Device, DeviceInfoBuilder},
surface::Surface,
swapchain::{Swapchain, SwapchainInfo},
},
graph::RenderGraph,
pool::hash::HashPool,
},
std::sync::Arc,
winit::{
application::ApplicationHandler,
error::EventLoopError,
event::WindowEvent,
event_loop::{ActiveEventLoop, EventLoop},
window::{Window, WindowId},
},
};
fn main() -> Result<(), EventLoopError> {
pretty_env_logger::init();
profile_with_puffin::init();
EventLoop::new()?.run_app(&mut Application::default())
}
#[derive(Default)]
struct Application(Option<Context>);
impl ApplicationHandler for Application {
fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) {
self.0.as_ref().unwrap().window.request_redraw();
}
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
let window_attributes = Window::default_attributes().with_title("Screen 13");
let window = event_loop.create_window(window_attributes).unwrap();
let args = Args::parse();
let device_info = DeviceInfoBuilder::default().debug(args.debug);
let device = Arc::new(Device::create_display(device_info, &window).unwrap());
let surface = Surface::create(&device, &window).unwrap();
let surface_formats = Surface::formats(&surface).unwrap();
let surface_format = Surface::linear_or_default(&surface_formats);
let window_size = window.inner_size();
let swapchain = Swapchain::new(
&device,
surface,
SwapchainInfo::new(window_size.width, window_size.height, surface_format),
)
.unwrap();
let display_pool = HashPool::new(&device);
let display = Display::new(&device, swapchain, DisplayInfo::default()).unwrap();
self.0 = Some(Context {
display,
display_pool,
window,
});
}
fn window_event(
&mut self,
event_loop: &ActiveEventLoop,
_window_id: WindowId,
event: WindowEvent,
) {
let context = self.0.as_mut().unwrap();
match event {
WindowEvent::CloseRequested => event_loop.exit(),
WindowEvent::Resized(size) => {
let mut swapchain_info = context.display.swapchain_info();
swapchain_info.width = size.width;
swapchain_info.height = size.height;
context.display.set_swapchain_info(swapchain_info);
}
WindowEvent::RedrawRequested => {
if let Err(err) = context.draw() {
error!("unable to draw window: {err}");
event_loop.exit();
};
profiling::finish_frame!();
}
_ => (),
}
}
}
#[derive(Parser)]
struct Args {
#[arg(long)]
debug: bool,
}
struct Context {
display: Display,
display_pool: HashPool,
window: Window,
}
impl Context {
fn draw(&mut self) -> Result<(), DisplayError> {
if let Some(swapchain_image) = self.display.acquire_next_image()? {
let mut render_graph = RenderGraph::new();
let swapchain_image = render_graph.bind_node(swapchain_image);
render_graph.clear_color_image_value(swapchain_image, [1.0, 0.0, 1.0]);
self.window.pre_present_notify();
self.display
.present_image(&mut self.display_pool, render_graph, swapchain_image, 0)?;
}
Ok(())
}
}