From b5d68435c91369822af7bed0f3fe0ca670b4e6b5 Mon Sep 17 00:00:00 2001 From: Alex Butler Date: Sun, 23 Jun 2024 10:11:49 +0100 Subject: [PATCH] Require ActiveEventLoop for window building (#10) --- CHANGELOG.md | 4 + Cargo.toml | 2 +- README.md | 1 - examples/triangle.rs | 225 ++++++++++++++++++++++++++++--------------- src/lib.rs | 14 +-- 5 files changed, 158 insertions(+), 88 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1aa7145..bd4f7be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v0.34.0 +* Require `winit::event_loop::ActiveEventLoop` for window building supporting `winit::application::ApplicationHandler`. + Use previous version for building using `EventLoop`. + # v0.33.0 * Update _winit_ to `0.30`, _glutin-winit_ to `0.5`, _glutin_ to `0.32`, _raw-window-handle_ to `0.6`. diff --git a/Cargo.toml b/Cargo.toml index 565bb73..e598630 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "old_school_gfx_glutin_ext" -version = "0.33.0" +version = "0.34.0" authors = ["Alex Butler "] edition = "2021" description = "Extensions for glutin to initialize & update old school gfx" diff --git a/README.md b/README.md index 182bdcb..326466d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ Initialise & update old school [gfx](https://crates.io/crates/gfx) with [glutin] type ColorFormat = gfx::format::Srgba8; type DepthFormat = gfx::format::DepthStencil; -let event_loop = winit::event_loop::EventLoop::new()?; let window_attrs = winit::window::Window::default_attributes(); // Initialise winit window, glutin context & gfx views diff --git a/examples/triangle.rs b/examples/triangle.rs index 48ff562..6a471a9 100644 --- a/examples/triangle.rs +++ b/examples/triangle.rs @@ -7,11 +7,15 @@ extern crate gfx; use gfx::{traits::FactoryExt, Device}; -use glutin::surface::GlSurface; +use glutin::{ + context::PossiblyCurrentContext, + surface::{GlSurface, Surface, WindowSurface}, +}; use std::{error::Error, num::NonZeroU32}; use winit::{ - event::{Event, KeyEvent, WindowEvent}, - event_loop::{ControlFlow, EventLoop}, + dpi::PhysicalSize, + event::{KeyEvent, WindowEvent}, + event_loop::{ActiveEventLoop, ControlFlow, EventLoop}, keyboard::{Key, NamedKey}, window::Window, }; @@ -50,85 +54,148 @@ const TRIANGLE: [Vertex; 3] = [ const CLEAR_COLOR: [f32; 4] = [0.1, 0.11, 0.12, 1.0]; pub fn main() -> Result<(), Box> { - let events = EventLoop::new()?; - events.set_control_flow(ControlFlow::Poll); - - // Initialise winit window, glutin context & gfx views - let old_school_gfx_glutin_ext::Init { - window, - gl_surface, - gl_context, - mut device, - mut factory, - color_view, - mut depth_view, - .. - } = old_school_gfx_glutin_ext::window_builder( - &events, - Window::default_attributes() - .with_title("Triangle") - .with_inner_size(winit::dpi::PhysicalSize::new(1024, 768)), - ) - .build::()?; - - let mut encoder = gfx::Encoder::from(factory.create_command_buffer()); - - let pso = factory.create_pipeline_simple( - include_bytes!("triangle.vs.glsl"), - include_bytes!("triangle.fs.glsl"), - pipe::new(), - )?; - - let (vertex_buffer, slice) = factory.create_vertex_buffer_with_slice(&TRIANGLE, ()); - let mut data = pipe::Data { - vbuf: vertex_buffer, - out: color_view, - }; - let mut dimensions = window.inner_size(); - - events.run(move |event, elwt| { + Ok(EventLoop::new()?.run_app(&mut WinitApp::None)?) +} + +enum WinitApp { + None, + Resumed(App), +} + +impl winit::application::ApplicationHandler for WinitApp { + fn resumed(&mut self, events: &ActiveEventLoop) { + events.set_control_flow(ControlFlow::Poll); + *self = Self::Resumed(App::new(events).unwrap()); + } + + fn window_event( + &mut self, + events: &ActiveEventLoop, + _: winit::window::WindowId, + event: WindowEvent, + ) { + if let Self::Resumed(app) = self { + app.window_event(events, event); + } + } + + fn about_to_wait(&mut self, _events: &ActiveEventLoop) { + if let Self::Resumed(App { window, .. }) = self { + window.request_redraw(); + }; + } +} + +struct App { + window: Window, + gl_surface: Surface, + gl_context: PossiblyCurrentContext, + device: gfx_device_gl::Device, + encoder: gfx::Encoder, + dimensions: PhysicalSize, + data: pipe::Data, + slice: gfx::Slice, + pso: gfx::PipelineState, + depth_view: gfx::handle::DepthStencilView, +} + +impl App { + fn new(events: &ActiveEventLoop) -> Result> { + let old_school_gfx_glutin_ext::Init { + window, + gl_surface, + gl_context, + device, + mut factory, + color_view, + depth_view, + .. + } = old_school_gfx_glutin_ext::window_builder( + events, + Window::default_attributes() + .with_title("Triangle") + .with_inner_size(winit::dpi::PhysicalSize::new(1024, 768)), + ) + .build::()?; + + let encoder = gfx::Encoder::from(factory.create_command_buffer()); + + let pso = factory.create_pipeline_simple( + include_bytes!("triangle.vs.glsl"), + include_bytes!("triangle.fs.glsl"), + pipe::new(), + )?; + + let (vertex_buffer, slice) = factory.create_vertex_buffer_with_slice(&TRIANGLE, ()); + let data = pipe::Data { + vbuf: vertex_buffer, + out: color_view, + }; + let dimensions = window.inner_size(); + Ok(Self { + window, + gl_surface, + gl_context, + device, + encoder, + dimensions, + data, + slice, + pso, + depth_view, + }) + } + + fn window_event(&mut self, elwt: &ActiveEventLoop, event: WindowEvent) { + let Self { + window, + gl_surface, + gl_context, + device, + encoder, + dimensions, + data, + slice, + pso, + depth_view, + } = self; + match event { - Event::AboutToWait => window.request_redraw(), - Event::WindowEvent { event, .. } => match event { - WindowEvent::CloseRequested - | WindowEvent::KeyboardInput { - event: - KeyEvent { - logical_key: Key::Named(NamedKey::Escape), - .. - }, - .. - } => elwt.exit(), - WindowEvent::RedrawRequested => { - // handle resizes - let window_size = window.inner_size(); - if dimensions != window_size { - if let (Some(w), Some(h)) = ( - NonZeroU32::new(window_size.width), - NonZeroU32::new(window_size.height), - ) { - gl_surface.resize(&gl_context, w, h); - old_school_gfx_glutin_ext::resize_views( - window_size, - &mut data.out, - &mut depth_view, - ); - } - dimensions = window_size; + WindowEvent::CloseRequested + | WindowEvent::KeyboardInput { + event: + KeyEvent { + logical_key: Key::Named(NamedKey::Escape), + .. + }, + .. + } => elwt.exit(), + WindowEvent::RedrawRequested => { + // handle resizes + let window_size = window.inner_size(); + if *dimensions != window_size { + if let (Some(w), Some(h)) = ( + NonZeroU32::new(window_size.width), + NonZeroU32::new(window_size.height), + ) { + gl_surface.resize(gl_context, w, h); + old_school_gfx_glutin_ext::resize_views( + window_size, + &mut data.out, + depth_view, + ); } - - // draw a frame - encoder.clear(&data.out, CLEAR_COLOR); - encoder.draw(&slice, &pso, &data); - encoder.flush(&mut device); - gl_surface.swap_buffers(&gl_context).unwrap(); - device.cleanup(); + *dimensions = window_size; } - _ => (), - }, + + // draw a frame + encoder.clear(&data.out, CLEAR_COLOR); + encoder.draw(slice, pso, data); + encoder.flush(device); + gl_surface.swap_buffers(gl_context).unwrap(); + device.cleanup(); + } _ => (), } - })?; - - Ok(()) + } } diff --git a/src/lib.rs b/src/lib.rs index 29c6c2d..335ff6f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,7 @@ //! type DepthFormat = gfx::format::DepthStencil; //! //! # fn main() -> Result<(), Box> { -//! let event_loop = winit::event_loop::EventLoop::new()?; +//! # let event_loop: winit::event_loop::ActiveEventLoop = unimplemented!(); //! let window_attrs = winit::window::Window::default_attributes(); //! //! // Initialise winit window, glutin context & gfx views @@ -51,10 +51,10 @@ use raw_window_handle::HasWindowHandle; use std::{error::Error, ffi::CString}; /// Returns a builder for initialising a winit window, glutin context & gfx views. -pub fn window_builder( - event_loop: &winit::event_loop::EventLoop, +pub fn window_builder( + event_loop: &winit::event_loop::ActiveEventLoop, winit: winit::window::WindowAttributes, -) -> Builder<'_, T> { +) -> Builder<'_> { Builder { event_loop, winit, @@ -67,8 +67,8 @@ pub fn window_builder( /// Builder for initialising a winit window, glutin context & gfx views. #[derive(Debug, Clone)] -pub struct Builder<'a, T: 'static> { - event_loop: &'a winit::event_loop::EventLoop, +pub struct Builder<'a> { + event_loop: &'a winit::event_loop::ActiveEventLoop, winit: winit::window::WindowAttributes, surface_attrs: Option>, ctx_attrs: ContextAttributesBuilder, @@ -76,7 +76,7 @@ pub struct Builder<'a, T: 'static> { sample_number_pref: NumberOfSamples, } -impl Builder<'_, T> { +impl Builder<'_> { /// Configure surface attributes. /// /// If not called glutin default settings are used.