Skip to content

Commit

Permalink
Require ActiveEventLoop for window building (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexheretic authored Jun 23, 2024
1 parent 8ac26c0 commit b5d6843
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 88 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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`.

Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "old_school_gfx_glutin_ext"
version = "0.33.0"
version = "0.34.0"
authors = ["Alex Butler <[email protected]>"]
edition = "2021"
description = "Extensions for glutin to initialize & update old school gfx"
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
225 changes: 146 additions & 79 deletions examples/triangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down Expand Up @@ -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<dyn Error>> {
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::<ColorFormat, DepthFormat>()?;

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<WindowSurface>,
gl_context: PossiblyCurrentContext,
device: gfx_device_gl::Device,
encoder: gfx::Encoder<gfx_device_gl::Resources, gfx_device_gl::CommandBuffer>,
dimensions: PhysicalSize<u32>,
data: pipe::Data<gfx_device_gl::Resources>,
slice: gfx::Slice<gfx_device_gl::Resources>,
pso: gfx::PipelineState<gfx_device_gl::Resources, pipe::Meta>,
depth_view: gfx::handle::DepthStencilView<gfx_device_gl::Resources, DepthFormat>,
}

impl App {
fn new(events: &ActiveEventLoop) -> Result<Self, Box<dyn Error>> {
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::<ColorFormat, DepthFormat>()?;

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(())
}
}
14 changes: 7 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//! type DepthFormat = gfx::format::DepthStencil;
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! 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
Expand Down Expand Up @@ -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<T: 'static>(
event_loop: &winit::event_loop::EventLoop<T>,
pub fn window_builder(
event_loop: &winit::event_loop::ActiveEventLoop,
winit: winit::window::WindowAttributes,
) -> Builder<'_, T> {
) -> Builder<'_> {
Builder {
event_loop,
winit,
Expand All @@ -67,16 +67,16 @@ pub fn window_builder<T: 'static>(

/// 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<T>,
pub struct Builder<'a> {
event_loop: &'a winit::event_loop::ActiveEventLoop,
winit: winit::window::WindowAttributes,
surface_attrs: Option<SurfaceAttributesBuilder<WindowSurface>>,
ctx_attrs: ContextAttributesBuilder,
config_attrs: ConfigTemplateBuilder,
sample_number_pref: NumberOfSamples,
}

impl<T> Builder<'_, T> {
impl Builder<'_> {
/// Configure surface attributes.
///
/// If not called glutin default settings are used.
Expand Down

0 comments on commit b5d6843

Please sign in to comment.