code is working again

0.19
Benjamin Hansen 3 months ago
parent 3f0caa6904
commit 12f115dfa1

@ -1,7 +1,8 @@
use winit::{
event::*,
event_loop::EventLoop,
window::WindowBuilder, keyboard::{KeyCode, PhysicalKey},
keyboard::{KeyCode, PhysicalKey},
window::WindowBuilder,
};
#[cfg(target_arch = "wasm32")]
@ -40,23 +41,25 @@ pub fn run() {
.expect("Couldn't append canvas to document body.");
}
event_loop.run(move |event, control_flow| match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == window.id() => match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
event_loop
.run(move |event, control_flow| match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == window.id() => match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
_ => {}
},
_ => {}
},
_ => {}
}).unwrap();
})
.unwrap();
}

@ -84,6 +84,7 @@ impl<'a> State<'a> {
alpha_mode: surface_caps.alpha_modes[0],
desired_maximum_frame_latency: 2,
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -180,50 +181,54 @@ async fn run() {
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(&window).await;
event_loop.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
_ => {}
}
}
_ => {}
}
_ => {}
}
}).unwrap();
})
.unwrap();
}

@ -3,7 +3,8 @@ use std::iter;
use winit::{
event::*,
event_loop::EventLoop,
window::{Window, WindowBuilder}, keyboard::{PhysicalKey, KeyCode},
keyboard::{KeyCode, PhysicalKey},
window::{Window, WindowBuilder},
};
#[cfg(target_arch = "wasm32")]
@ -81,6 +82,7 @@ impl<'a> State<'a> {
alpha_mode: surface_caps.alpha_modes[0],
desired_maximum_frame_latency: 2,
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -191,53 +193,57 @@ pub async fn run() {
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(&window).await;
event_loop.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
// UPDATED!
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
// UPDATED!
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
_ => {}
}
}
_ => {}
}
_ => {}
}
}).unwrap();
})
.unwrap();
}

@ -3,11 +3,12 @@ use std::iter;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
keyboard::{KeyCode, PhysicalKey},
window::{Window, WindowBuilder},
};
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -15,11 +16,11 @@ struct State {
render_pipeline: wgpu::RenderPipeline,
challenge_render_pipeline: wgpu::RenderPipeline,
use_color: bool,
window: Window,
window: &'a Window,
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -29,11 +30,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -48,10 +45,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -80,6 +77,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -213,10 +211,10 @@ impl State {
fn input(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state,
virtual_keycode: Some(VirtualKeyCode::Space),
physical_key: PhysicalKey::Code(KeyCode::Space),
..
},
..
@ -284,61 +282,62 @@ fn main() {
async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new().build(&event_loop).unwrap();
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(window).await;
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
// new_inner_size is &mut so w have to dereference it twice
state.resize(**new_inner_size);
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
}
_ => {}
}
_ => {}
}
}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
Event::MainEventsCleared => {
// RedrawRequested will only trigger once, unless we manually
// request it.
state.window().request_redraw();
}
_ => {}
}
});
})
.unwrap();
}

@ -2,26 +2,27 @@ use std::iter;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
event_loop::EventLoop,
keyboard::{KeyCode, PhysicalKey},
window::{Window, WindowBuilder},
};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
size: winit::dpi::PhysicalSize<u32>,
// NEW!
render_pipeline: wgpu::RenderPipeline,
window: Window,
window: &'a Window,
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -31,11 +32,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -50,10 +47,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -82,6 +79,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -227,7 +225,7 @@ pub async fn run() {
}
}
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new().build(&event_loop).unwrap();
#[cfg(target_arch = "wasm32")]
@ -250,57 +248,58 @@ pub async fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(window).await;
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
// new_inner_size is &mut so w have to dereference it twice
state.resize(**new_inner_size);
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
}
_ => {}
}
_ => {}
}
}
_ => {}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
}
Event::MainEventsCleared => {
// RedrawRequested will only trigger once, unless we manually
// request it.
state.window().request_redraw();
}
_ => {}
}
});
})
.unwrap();
}

@ -4,6 +4,7 @@ use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
keyboard::{KeyCode, PhysicalKey},
window::{Window, WindowBuilder},
};
@ -60,8 +61,8 @@ const VERTICES: &[Vertex] = &[
const INDICES: &[u16] = &[0, 1, 4, 1, 2, 4, 2, 3, 4];
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -78,11 +79,11 @@ struct State {
use_complex: bool,
size: winit::dpi::PhysicalSize<u32>,
window: Window,
window: &'a Window,
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -96,7 +97,7 @@ impl State {
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -111,10 +112,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -143,6 +144,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -281,10 +283,10 @@ impl State {
fn input(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state,
virtual_keycode: Some(VirtualKeyCode::Space),
physical_key: PhysicalKey::Code(KeyCode::Space),
..
},
..
@ -361,61 +363,62 @@ fn main() {
async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new().build(&event_loop).unwrap();
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(window).await;
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
let mut state = State::new(&window).await;
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
}
_ => {}
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
// new_inner_size is &mut so w have to dereference it twice
state.resize(**new_inner_size);
}
_ => {}
}
}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
Event::MainEventsCleared => {
// RedrawRequested will only trigger once, unless we manually
// request it.
state.window().request_redraw();
}
_ => {}
}
});
})
.unwrap();
}

@ -3,7 +3,8 @@ use std::iter;
use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
event_loop::EventLoop,
keyboard::{KeyCode, PhysicalKey},
window::{Window, WindowBuilder},
};
@ -63,8 +64,8 @@ const VERTICES: &[Vertex] = &[
const INDICES: &[u16] = &[0, 1, 4, 1, 2, 4, 2, 3, 4, /* padding */ 0];
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -74,11 +75,11 @@ struct State {
vertex_buffer: wgpu::Buffer,
index_buffer: wgpu::Buffer,
num_indices: u32,
window: Window,
window: &'a Window,
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -92,7 +93,7 @@ impl State {
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -107,10 +108,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -139,6 +140,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -301,7 +303,7 @@ pub async fn run() {
}
}
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new().build(&event_loop).unwrap();
#[cfg(target_arch = "wasm32")]
@ -324,57 +326,58 @@ pub async fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(window).await;
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
let mut state = State::new(&window).await;
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
}
_ => {}
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
// new_inner_size is &mut so w have to dereference it twice
state.resize(**new_inner_size);
}
_ => {}
}
}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
Event::MainEventsCleared => {
// RedrawRequested will only trigger once, unless we manually
// request it.
state.window().request_redraw();
}
_ => {}
}
});
})
.unwrap();
}

@ -4,6 +4,7 @@ use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
keyboard::{KeyCode, PhysicalKey},
window::{Window, WindowBuilder},
};
@ -63,8 +64,8 @@ const VERTICES: &[Vertex] = &[
const INDICES: &[u16] = &[0, 1, 4, 1, 2, 4, 2, 3, 4];
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -80,11 +81,11 @@ struct State {
cartoon_texture: texture::Texture,
cartoon_bind_group: wgpu::BindGroup,
is_space_pressed: bool,
window: Window,
window: &'a Window,
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -98,7 +99,7 @@ impl State {
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -112,10 +113,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -144,6 +145,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -312,10 +314,10 @@ impl State {
fn input(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state,
virtual_keycode: Some(VirtualKeyCode::Space),
physical_key: PhysicalKey::Code(KeyCode::Space),
..
},
..
@ -388,61 +390,61 @@ fn main() {
async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new().build(&event_loop).unwrap();
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(window).await;
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
let mut state = State::new(&window).await;
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
}
_ => {}
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
// new_inner_size is &mut so we have to dereference it twice
state.resize(**new_inner_size);
}
_ => {}
}
}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
Event::MainEventsCleared => {
// RedrawRequested will only trigger once, unless we manually
// request it.
state.window().request_redraw();
}
_ => {}
}
});
})
.unwrap();
}

@ -3,7 +3,8 @@ use std::iter;
use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
event_loop::EventLoop,
keyboard::{KeyCode, PhysicalKey},
window::{Window, WindowBuilder},
};
@ -66,8 +67,8 @@ const VERTICES: &[Vertex] = &[
const INDICES: &[u16] = &[0, 1, 4, 1, 2, 4, 2, 3, 4, /* padding */ 0];
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -80,11 +81,11 @@ struct State {
#[allow(dead_code)]
diffuse_texture: texture::Texture,
diffuse_bind_group: wgpu::BindGroup,
window: Window,
window: &'a Window,
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -94,11 +95,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -112,10 +109,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -144,6 +141,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -351,7 +349,7 @@ pub async fn run() {
}
}
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new().build(&event_loop).unwrap();
#[cfg(target_arch = "wasm32")]
@ -374,57 +372,58 @@ pub async fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(window).await;
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
let mut state = State::new(&window).await;
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
}
_ => {}
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
// new_inner_size is &mut so w have to dereference it twice
state.resize(**new_inner_size);
}
_ => {}
}
}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
Event::MainEventsCleared => {
// RedrawRequested will only trigger once, unless we manually
// request it.
state.window().request_redraw();
}
_ => {}
}
});
})
.unwrap();
}

@ -3,7 +3,8 @@ use std::iter;
use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
event_loop::EventLoop,
keyboard::{KeyCode, PhysicalKey},
window::{Window, WindowBuilder},
};
@ -146,29 +147,29 @@ impl CameraController {
fn process_events(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state,
virtual_keycode: Some(keycode),
physical_key: PhysicalKey::Code(keycode),
..
},
..
} => {
let is_pressed = *state == ElementState::Pressed;
match keycode {
VirtualKeyCode::W | VirtualKeyCode::Up => {
KeyCode::KeyW | KeyCode::ArrowUp => {
self.is_forward_pressed = is_pressed;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.is_left_pressed = is_pressed;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.is_backward_pressed = is_pressed;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.is_right_pressed = is_pressed;
true
}
@ -212,8 +213,8 @@ impl CameraController {
}
}
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -230,11 +231,11 @@ struct State {
camera_buffer: wgpu::Buffer,
camera_bind_group: wgpu::BindGroup,
size: winit::dpi::PhysicalSize<u32>,
window: Window,
window: &'a Window,
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -244,11 +245,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -262,10 +259,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -294,6 +291,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -559,61 +557,62 @@ fn main() {
async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new().build(&event_loop).unwrap();
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(window).await;
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
let mut state = State::new(&window).await;
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
}
_ => {}
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
// new_inner_size is &mut so w have to dereference it twice
state.resize(**new_inner_size);
}
_ => {}
}
}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
Event::MainEventsCleared => {
// RedrawRequested will only trigger once, unless we manually
// request it.
state.window().request_redraw();
}
_ => {}
}
});
})
.unwrap();
}

@ -3,7 +3,8 @@ use std::iter;
use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
event_loop::EventLoop,
keyboard::{KeyCode, PhysicalKey},
window::{Window, WindowBuilder},
};
@ -137,37 +138,37 @@ impl CameraController {
fn process_events(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state,
virtual_keycode: Some(keycode),
physical_key: PhysicalKey::Code(keycode),
..
},
..
} => {
let is_pressed = *state == ElementState::Pressed;
match keycode {
VirtualKeyCode::Space => {
KeyCode::Space => {
self.is_up_pressed = is_pressed;
true
}
VirtualKeyCode::LShift => {
KeyCode::ShiftLeft => {
self.is_down_pressed = is_pressed;
true
}
VirtualKeyCode::W | VirtualKeyCode::Up => {
KeyCode::KeyW | KeyCode::ArrowUp => {
self.is_forward_pressed = is_pressed;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.is_left_pressed = is_pressed;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.is_backward_pressed = is_pressed;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.is_right_pressed = is_pressed;
true
}
@ -211,8 +212,8 @@ impl CameraController {
}
}
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -230,11 +231,11 @@ struct State {
camera_uniform: CameraUniform,
camera_buffer: wgpu::Buffer,
camera_bind_group: wgpu::BindGroup,
window: Window,
window: &'a Window,
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -244,11 +245,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -262,10 +259,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -294,6 +291,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -560,7 +558,7 @@ pub async fn run() {
}
}
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new().build(&event_loop).unwrap();
#[cfg(target_arch = "wasm32")]
@ -583,57 +581,58 @@ pub async fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(window).await;
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
let mut state = State::new(&window).await;
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
}
_ => {}
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
// new_inner_size is &mut so w have to dereference it twice
state.resize(**new_inner_size);
}
_ => {}
}
}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
Event::MainEventsCleared => {
// RedrawRequested will only trigger once, unless we manually
// request it.
state.window().request_redraw();
}
_ => {}
}
});
})
.unwrap();
}

@ -4,7 +4,8 @@ use cgmath::prelude::*;
use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
event_loop::EventLoop,
keyboard::{KeyCode, PhysicalKey},
window::{Window, WindowBuilder},
};
@ -137,29 +138,29 @@ impl CameraController {
fn process_events(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state,
virtual_keycode: Some(keycode),
physical_key: PhysicalKey::Code(keycode),
..
},
..
} => {
let is_pressed = *state == ElementState::Pressed;
match keycode {
VirtualKeyCode::W | VirtualKeyCode::Up => {
KeyCode::KeyW | KeyCode::ArrowUp => {
self.is_forward_pressed = is_pressed;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.is_left_pressed = is_pressed;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.is_backward_pressed = is_pressed;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.is_right_pressed = is_pressed;
true
}
@ -264,8 +265,8 @@ impl InstanceRaw {
}
}
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -284,11 +285,11 @@ struct State {
size: winit::dpi::PhysicalSize<u32>,
instances: Vec<Instance>,
instance_buffer: wgpu::Buffer,
window: Window,
window: &'a Window,
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -298,11 +299,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -316,10 +313,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -348,6 +345,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -660,61 +658,62 @@ fn main() {
async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new().build(&event_loop).unwrap();
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(window).await;
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
let mut state = State::new(&window).await;
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
}
_ => {}
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
// new_inner_size is &mut so w have to dereference it twice
state.resize(**new_inner_size);
}
_ => {}
}
}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
Event::MainEventsCleared => {
// RedrawRequested will only trigger once, unless we manually
// request it.
state.window().request_redraw();
}
_ => {}
}
});
})
.unwrap();
}

@ -5,6 +5,7 @@ use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
keyboard::{KeyCode, PhysicalKey},
window::{Window, WindowBuilder},
};
@ -144,37 +145,37 @@ impl CameraController {
fn process_events(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state,
virtual_keycode: Some(keycode),
physical_key: PhysicalKey::Code(keycode),
..
},
..
} => {
let is_pressed = *state == ElementState::Pressed;
match keycode {
VirtualKeyCode::Space => {
KeyCode::Space => {
self.is_up_pressed = is_pressed;
true
}
VirtualKeyCode::LShift => {
KeyCode::ShiftLeft => {
self.is_down_pressed = is_pressed;
true
}
VirtualKeyCode::W | VirtualKeyCode::Up => {
KeyCode::KeyW | KeyCode::ArrowUp => {
self.is_forward_pressed = is_pressed;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.is_left_pressed = is_pressed;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.is_backward_pressed = is_pressed;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.is_right_pressed = is_pressed;
true
}
@ -269,8 +270,8 @@ impl InstanceRaw {
}
}
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -291,11 +292,11 @@ struct State {
instances: Vec<Instance>,
#[allow(dead_code)]
instance_buffer: wgpu::Buffer,
window: Window,
window: &'a Window,
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -305,11 +306,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -323,10 +320,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -355,6 +352,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -658,7 +656,7 @@ pub async fn run() {
}
}
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new().build(&event_loop).unwrap();
#[cfg(target_arch = "wasm32")]
@ -681,57 +679,58 @@ pub async fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(window).await;
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
let mut state = State::new(&window).await;
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
}
_ => {}
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
// new_inner_size is &mut so w have to dereference it twice
state.resize(**new_inner_size);
}
_ => {}
}
}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
Event::MainEventsCleared => {
// RedrawRequested will only trigger once, unless we manually
// request it.
state.window().request_redraw();
}
_ => {}
}
});
})
.unwrap();
}

@ -6,6 +6,7 @@ use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
keyboard::{KeyCode, PhysicalKey},
window::{Window, WindowBuilder},
};
@ -159,29 +160,29 @@ impl CameraController {
fn process_events(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state,
virtual_keycode: Some(keycode),
physical_key: PhysicalKey::Code(keycode),
..
},
..
} => {
let is_pressed = *state == ElementState::Pressed;
match keycode {
VirtualKeyCode::W | VirtualKeyCode::Up => {
KeyCode::KeyW | KeyCode::ArrowUp => {
self.is_forward_pressed = is_pressed;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.is_left_pressed = is_pressed;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.is_backward_pressed = is_pressed;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.is_right_pressed = is_pressed;
true
}
@ -461,8 +462,8 @@ impl DepthPass {
}
}
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -483,11 +484,11 @@ struct State {
#[allow(dead_code)]
instance_buffer: wgpu::Buffer,
depth_pass: DepthPass,
window: Window,
window: &'a Window,
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -497,11 +498,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -515,10 +512,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -547,6 +544,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -867,61 +865,62 @@ fn main() {
async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new().build(&event_loop).unwrap();
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(window).await;
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
let mut state = State::new(&window).await;
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
}
_ => {}
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
// new_inner_size is &mut so w have to dereference it twice
state.resize(**new_inner_size);
}
_ => {}
}
}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
Event::MainEventsCleared => {
// RedrawRequested will only trigger once, unless we manually
// request it.
state.window().request_redraw();
}
_ => {}
}
});
})
.unwrap();
}

@ -5,6 +5,7 @@ use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
keyboard::{KeyCode, PhysicalKey},
window::{Window, WindowBuilder},
};
@ -144,37 +145,37 @@ impl CameraController {
fn process_events(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state,
virtual_keycode: Some(keycode),
physical_key: PhysicalKey::Code(keycode),
..
},
..
} => {
let is_pressed = *state == ElementState::Pressed;
match keycode {
VirtualKeyCode::Space => {
KeyCode::Space => {
self.is_up_pressed = is_pressed;
true
}
VirtualKeyCode::LShift => {
KeyCode::ShiftLeft => {
self.is_down_pressed = is_pressed;
true
}
VirtualKeyCode::W | VirtualKeyCode::Up => {
KeyCode::KeyW | KeyCode::ArrowUp => {
self.is_forward_pressed = is_pressed;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.is_left_pressed = is_pressed;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.is_backward_pressed = is_pressed;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.is_right_pressed = is_pressed;
true
}
@ -278,8 +279,8 @@ impl InstanceRaw {
}
}
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -301,11 +302,11 @@ struct State {
instance_buffer: wgpu::Buffer,
// NEW!
depth_texture: texture::Texture,
window: Window,
window: &'a Window,
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -315,11 +316,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -333,10 +330,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -365,6 +362,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -685,7 +683,7 @@ pub async fn run() {
}
}
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new().build(&event_loop).unwrap();
#[cfg(target_arch = "wasm32")]
@ -708,57 +706,58 @@ pub async fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(window).await;
event_loop.run(move |event, _, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
let mut state = State::new(&window).await;
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
}
_ => {}
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
// new_inner_size is &mut so w have to dereference it twice
state.resize(**new_inner_size);
}
_ => {}
}
}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
Event::MainEventsCleared => {
// RedrawRequested will only trigger once, unless we manually
// request it.
state.window().request_redraw();
}
_ => {}
}
});
})
.unwrap();
}

@ -5,6 +5,7 @@ use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
keyboard::{KeyCode, PhysicalKey},
window::Window,
};
@ -89,37 +90,37 @@ impl CameraController {
fn process_events(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state,
virtual_keycode: Some(keycode),
physical_key: PhysicalKey::Code(keycode),
..
},
..
} => {
let is_pressed = *state == ElementState::Pressed;
match keycode {
VirtualKeyCode::Space => {
KeyCode::Space => {
self.is_up_pressed = is_pressed;
true
}
VirtualKeyCode::LShift => {
KeyCode::ShiftLeft => {
self.is_down_pressed = is_pressed;
true
}
VirtualKeyCode::W | VirtualKeyCode::Up => {
KeyCode::KeyW | KeyCode::ArrowUp => {
self.is_forward_pressed = is_pressed;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.is_left_pressed = is_pressed;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.is_backward_pressed = is_pressed;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.is_right_pressed = is_pressed;
true
}
@ -223,8 +224,8 @@ impl InstanceRaw {
}
}
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -240,11 +241,11 @@ struct State {
#[allow(dead_code)]
instance_buffer: wgpu::Buffer,
depth_texture: texture::Texture,
window: Window,
window: &'a Window,
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -255,11 +256,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -274,10 +271,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -308,6 +305,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -596,7 +594,7 @@ pub async fn run() {
}
}
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let title = env!("CARGO_PKG_NAME");
let window = winit::window::WindowBuilder::new()
.with_title(title)
@ -623,53 +621,58 @@ pub async fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(window).await;
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
match event {
Event::MainEventsCleared => state.window().request_redraw(),
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
let mut state = State::new(&window).await;
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
}
_ => {}
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
state.resize(**new_inner_size);
}
_ => {}
}
}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
_ => {}
}
});
})
.unwrap();
}

@ -5,6 +5,7 @@ use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
keyboard::{KeyCode, PhysicalKey},
window::Window,
};
@ -93,37 +94,37 @@ impl CameraController {
fn process_events(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state,
virtual_keycode: Some(keycode),
physical_key: PhysicalKey::Code(keycode),
..
},
..
} => {
let is_pressed = *state == ElementState::Pressed;
match keycode {
VirtualKeyCode::Space => {
KeyCode::Space => {
self.is_up_pressed = is_pressed;
true
}
VirtualKeyCode::LShift => {
KeyCode::ShiftLeft => {
self.is_down_pressed = is_pressed;
true
}
VirtualKeyCode::W | VirtualKeyCode::Up => {
KeyCode::KeyW | KeyCode::ArrowUp => {
self.is_forward_pressed = is_pressed;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.is_left_pressed = is_pressed;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.is_backward_pressed = is_pressed;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.is_right_pressed = is_pressed;
true
}
@ -255,9 +256,9 @@ struct LightUniform {
_padding2: u32,
}
struct State {
window: Window,
surface: wgpu::Surface,
struct State<'a> {
window: &'a Window,
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -339,8 +340,8 @@ fn create_render_pipeline(
})
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -350,11 +351,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -368,10 +365,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -400,6 +397,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -733,7 +731,7 @@ pub async fn run() {
}
}
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let title = env!("CARGO_PKG_NAME");
let window = winit::window::WindowBuilder::new()
.with_title(title)
@ -763,53 +761,58 @@ pub async fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(window).await;
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
match event {
Event::MainEventsCleared => state.window().request_redraw(),
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
let mut state = State::new(&window).await;
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
}
_ => {}
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
state.resize(**new_inner_size);
}
_ => {}
}
}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
_ => {}
}
});
})
.unwrap();
}

@ -5,6 +5,7 @@ use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
keyboard::{KeyCode, PhysicalKey},
window::Window,
};
@ -92,37 +93,37 @@ impl CameraController {
fn process_events(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state,
virtual_keycode: Some(keycode),
physical_key: PhysicalKey::Code(keycode),
..
},
..
} => {
let is_pressed = *state == ElementState::Pressed;
match keycode {
VirtualKeyCode::Space => {
KeyCode::Space => {
self.is_up_pressed = is_pressed;
true
}
VirtualKeyCode::LShift => {
KeyCode::ShiftLeft => {
self.is_down_pressed = is_pressed;
true
}
VirtualKeyCode::W | VirtualKeyCode::Up => {
KeyCode::KeyW | KeyCode::ArrowUp => {
self.is_forward_pressed = is_pressed;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.is_left_pressed = is_pressed;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.is_backward_pressed = is_pressed;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.is_right_pressed = is_pressed;
true
}
@ -253,9 +254,9 @@ struct LightUniform {
_padding2: u32,
}
struct State {
window: Window,
surface: wgpu::Surface,
struct State<'a> {
window: &'a Window,
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -339,8 +340,8 @@ fn create_render_pipeline(
})
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -350,11 +351,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -368,10 +365,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -400,6 +397,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -784,7 +782,7 @@ pub async fn run() {
}
}
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let title = env!("CARGO_PKG_NAME");
let window = winit::window::WindowBuilder::new()
.with_title(title)
@ -811,53 +809,58 @@ pub async fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state = State::new(window).await;
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
match event {
Event::MainEventsCleared => state.window().request_redraw(),
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
let mut state = State::new(&window).await;
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,
window_id,
} if window_id == state.window().id() => {
if !state.input(event) {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::RedrawRequested => {
// This tells winit that we want another frame after this one
state.window().request_redraw();
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(
wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated,
) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => {
log::error!("OutOfMemory");
control_flow.exit();
}
// This happens when the a frame takes too long to present
Err(wgpu::SurfaceError::Timeout) => {
log::warn!("Surface timeout")
}
}
}
_ => {}
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
state.resize(**new_inner_size);
}
_ => {}
}
}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
state.update();
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {
state.resize(state.size)
}
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
_ => {}
}
_ => {}
}
});
})
.unwrap();
}

@ -3,6 +3,7 @@ use std::f32::consts::FRAC_PI_2;
use std::time::Duration;
use winit::dpi::PhysicalPosition;
use winit::event::*;
use winit::keyboard::KeyCode;
#[rustfmt::skip]
pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
@ -104,34 +105,34 @@ impl CameraController {
}
}
pub fn process_keyboard(&mut self, key: VirtualKeyCode, state: ElementState) -> bool {
pub fn process_keyboard(&mut self, key: KeyCode, state: ElementState) -> bool {
let amount = if state == ElementState::Pressed {
1.0
} else {
0.0
};
match key {
VirtualKeyCode::W | VirtualKeyCode::Up => {
KeyCode::KeyW | KeyCode::ArrowUp => {
self.amount_forward = amount;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.amount_backward = amount;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.amount_left = amount;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.amount_right = amount;
true
}
VirtualKeyCode::Space => {
KeyCode::Space => {
self.amount_up = amount;
true
}
VirtualKeyCode::LShift => {
KeyCode::ShiftLeft => {
self.amount_down = amount;
true
}

@ -1,10 +1,11 @@
use std::iter;
use std::{f32::consts::PI, iter};
use cgmath::prelude::*;
use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
keyboard::{KeyCode, PhysicalKey},
window::Window,
};
@ -130,9 +131,9 @@ struct LightUniform {
_padding2: u32,
}
struct State {
window: Window,
surface: wgpu::Surface,
struct State<'a> {
window: &'a Window,
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -219,8 +220,8 @@ fn create_render_pipeline(
})
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -230,11 +231,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -248,10 +245,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -280,6 +277,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -564,9 +562,9 @@ impl State {
fn input(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
virtual_keycode: Some(key),
event:
KeyEvent {
physical_key: PhysicalKey::Code(key),
state,
..
},
@ -601,10 +599,11 @@ impl State {
// Update the light
let old_position: cgmath::Vector3<_> = self.light_uniform.position.into();
self.light_uniform.position =
(cgmath::Quaternion::from_axis_angle((0.0, 1.0, 0.0).into(), cgmath::Deg(1.0))
* old_position)
.into();
self.light_uniform.position = (cgmath::Quaternion::from_axis_angle(
(0.0, 1.0, 0.0).into(),
cgmath::Deg(PI * dt.as_secs_f32()),
) * old_position)
.into();
self.queue.write_buffer(
&self.light_buffer,
0,
@ -686,7 +685,7 @@ pub async fn run() {
}
}
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let title = env!("CARGO_PKG_NAME");
let window = winit::window::WindowBuilder::new()
.with_title(title)
@ -712,12 +711,10 @@ pub async fn run() {
.expect("Couldn't append canvas to document body.");
}
let mut state = State::new(window).await; // NEW!
let mut state = State::new(&window).await; // NEW!
let mut last_render_time = instant::Instant::now();
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
event_loop.run(move |event, control_flow| {
match event {
Event::MainEventsCleared => state.window().request_redraw(),
// NEW!
Event::DeviceEvent {
event: DeviceEvent::MouseMotion{ delta, },
@ -734,40 +731,38 @@ pub async fn run() {
#[cfg(not(target_arch="wasm32"))]
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
state.resize(**new_inner_size);
// UPDATED!
WindowEvent::RedrawRequested => {
state.window().request_redraw();
let now = instant::Instant::now();
let dt = now - last_render_time;
last_render_time = now;
state.update(dt);
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => control_flow.exit(),
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
}
_ => {}
}
}
// UPDATED!
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
let now = instant::Instant::now();
let dt = now - last_render_time;
last_render_time = now;
state.update(dt);
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
}
_ => {}
}
});
}).unwrap();
}

@ -3,6 +3,7 @@ use std::f32::consts::FRAC_PI_2;
use std::time::Duration;
use winit::dpi::PhysicalPosition;
use winit::event::*;
use winit::keyboard::KeyCode;
const SAFE_FRAC_PI_2: f32 = FRAC_PI_2 - 0.0001;
@ -97,34 +98,34 @@ impl CameraController {
}
}
pub fn process_keyboard(&mut self, key: VirtualKeyCode, state: ElementState) -> bool {
pub fn process_keyboard(&mut self, key: KeyCode, state: ElementState) -> bool {
let amount = if state == ElementState::Pressed {
1.0
} else {
0.0
};
match key {
VirtualKeyCode::W | VirtualKeyCode::Up => {
KeyCode::KeyW | KeyCode::ArrowUp => {
self.amount_forward = amount;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.amount_backward = amount;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.amount_left = amount;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.amount_right = amount;
true
}
VirtualKeyCode::Space => {
KeyCode::Space => {
self.amount_up = amount;
true
}
VirtualKeyCode::LShift => {
KeyCode::ShiftLeft => {
self.amount_down = amount;
true
}

@ -1,10 +1,11 @@
use std::iter;
use std::{f32::consts::PI, iter};
use cgmath::prelude::*;
use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
event_loop::EventLoop,
keyboard::{KeyCode, PhysicalKey},
window::Window,
};
@ -146,9 +147,9 @@ struct LightUniform {
_padding2: u32,
}
struct State {
window: Window,
surface: wgpu::Surface,
struct State<'a> {
window: &'a Window,
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -238,26 +239,22 @@ fn create_render_pipeline(
})
}
impl State {
async fn new(window: Window) -> anyhow::Result<Self> {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> anyhow::Result<State<'a>> {
let size = window.inner_size();
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
// UPDATED
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::BROWSER_WEBGPU,
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::all(),
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -272,9 +269,9 @@ impl State {
&wgpu::DeviceDescriptor {
label: None,
// UPDATED!
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// UPDATED!
limits: wgpu::Limits::downlevel_defaults(),
required_limits: wgpu::Limits::downlevel_defaults(),
},
None, // Trace path
)
@ -299,6 +296,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -665,9 +663,9 @@ impl State {
fn input(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
virtual_keycode: Some(key),
event:
KeyEvent {
physical_key: PhysicalKey::Code(key),
state,
..
},
@ -701,10 +699,11 @@ impl State {
// Update the light
let old_position: cgmath::Vector3<_> = self.light_uniform.position.into();
self.light_uniform.position =
(cgmath::Quaternion::from_axis_angle((0.0, 1.0, 0.0).into(), cgmath::Deg(1.0))
* old_position)
.into();
self.light_uniform.position = (cgmath::Quaternion::from_axis_angle(
(0.0, 1.0, 0.0).into(),
cgmath::Deg(PI * dt.as_secs_f32()),
) * old_position)
.into();
self.queue.write_buffer(
&self.light_buffer,
0,
@ -816,7 +815,7 @@ pub async fn run() {
}
}
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let title = env!("CARGO_PKG_NAME");
let window = winit::window::WindowBuilder::new()
.with_title(title)
@ -842,12 +841,10 @@ pub async fn run() {
.expect("Couldn't append canvas to document body.");
}
let mut state = State::new(window).await.unwrap(); // NEW!
let mut state = State::new(&window).await.unwrap();
let mut last_render_time = instant::Instant::now();
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
event_loop.run(move |event, control_flow| {
match event {
Event::MainEventsCleared => state.window().request_redraw(),
Event::DeviceEvent {
event: DeviceEvent::MouseMotion{ delta, },
.. // We're not using device_id currently
@ -863,40 +860,38 @@ pub async fn run() {
#[cfg(not(target_arch="wasm32"))]
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
state.resize(**new_inner_size);
// UPDATED!
WindowEvent::RedrawRequested => {
state.window().request_redraw();
let now = instant::Instant::now();
let dt = now - last_render_time;
last_render_time = now;
state.update(dt);
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => control_flow.exit(),
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
}
_ => {}
}
}
// UPDATED!
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
let now = instant::Instant::now();
let dt = now - last_render_time;
last_render_time = now;
state.update(dt);
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
}
_ => {}
}
});
}).unwrap();
}

@ -327,8 +327,7 @@ impl HdrLoader {
dst_size,
self.texture_format,
1,
wgpu::TextureUsages::STORAGE_BINDING
| wgpu::TextureUsages::TEXTURE_BINDING,
wgpu::TextureUsages::STORAGE_BINDING | wgpu::TextureUsages::TEXTURE_BINDING,
wgpu::FilterMode::Nearest,
label,
);
@ -356,7 +355,10 @@ impl HdrLoader {
});
let mut encoder = device.create_command_encoder(&Default::default());
let mut pass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label, timestamp_writes: None });
let mut pass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor {
label,
timestamp_writes: None,
});
let num_workgroups = (dst_size + 15) / 16;
pass.set_pipeline(&self.equirect_to_cubemap);

@ -239,10 +239,15 @@ impl CubeTexture {
}
}
pub fn texture(&self) -> &wgpu::Texture { &self.texture }
pub fn view(&self) -> &wgpu::TextureView { &self.view }
pub fn texture(&self) -> &wgpu::Texture {
&self.texture
}
pub fn sampler(&self) -> &wgpu::Sampler { &self.sampler }
pub fn view(&self) -> &wgpu::TextureView {
&self.view
}
pub fn sampler(&self) -> &wgpu::Sampler {
&self.sampler
}
}

@ -2,7 +2,7 @@ use std::marker::PhantomData;
pub struct Binder<B> {
layout: wgpu::BindGroupLayout,
_marker: PhantomData<B>
_marker: PhantomData<B>,
}
// pub trait Uniform
// pub trait Uniform

@ -3,6 +3,7 @@ use std::f32::consts::FRAC_PI_2;
use std::time::Duration;
use winit::dpi::PhysicalPosition;
use winit::event::*;
use winit::keyboard::KeyCode;
#[rustfmt::skip]
pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
@ -104,34 +105,34 @@ impl CameraController {
}
}
pub fn process_keyboard(&mut self, key: VirtualKeyCode, state: ElementState) -> bool {
pub fn process_keyboard(&mut self, key: KeyCode, state: ElementState) -> bool {
let amount = if state == ElementState::Pressed {
1.0
} else {
0.0
};
match key {
VirtualKeyCode::W | VirtualKeyCode::Up => {
KeyCode::KeyW | KeyCode::ArrowUp => {
self.amount_forward = amount;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.amount_backward = amount;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.amount_left = amount;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.amount_right = amount;
true
}
VirtualKeyCode::Space => {
KeyCode::Space => {
self.amount_up = amount;
true
}
VirtualKeyCode::LShift => {
KeyCode::ShiftLeft => {
self.amount_down = amount;
true
}

@ -5,18 +5,19 @@ use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
keyboard::{KeyCode, PhysicalKey},
window::Window,
};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
mod bindgroups;
mod camera;
mod model;
mod resources;
mod terrain;
mod texture;
mod bindgroups; // NEW!
mod texture; // NEW!
use model::{DrawLight, DrawModel, Vertex};
@ -132,9 +133,9 @@ struct LightUniform {
_padding2: u32,
}
struct State {
window: Window,
surface: wgpu::Surface,
struct State<'a> {
window: &'a Window,
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -220,8 +221,8 @@ fn create_render_pipeline(
})
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -231,11 +232,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -249,10 +246,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -281,6 +278,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -606,9 +604,9 @@ impl State {
fn input(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
virtual_keycode: Some(key),
event:
KeyEvent {
physical_key: PhysicalKey::Code(key),
state,
..
},
@ -736,7 +734,7 @@ pub async fn run() {
}
}
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let title = env!("CARGO_PKG_NAME");
let window = winit::window::WindowBuilder::new()
.with_title(title)
@ -763,13 +761,11 @@ pub async fn run() {
.expect("Couldn't append canvas to document body.");
}
let mut state = State::new(window).await; // NEW!
let mut state = State::new(&window).await; // NEW!
state.window().set_visible(true);
let mut last_render_time = instant::Instant::now();
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
event_loop.run(move |event, control_flow| {
match event {
Event::MainEventsCleared => state.window().request_redraw(),
// NEW!
Event::DeviceEvent {
event: DeviceEvent::MouseMotion{ delta, },
@ -786,40 +782,37 @@ pub async fn run() {
#[cfg(not(target_arch="wasm32"))]
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
state.resize(**new_inner_size);
// UPDATED!
WindowEvent::RedrawRequested => {
let now = instant::Instant::now();
let dt = now - last_render_time;
last_render_time = now;
state.update(dt);
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => control_flow.exit(),
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
}
_ => {}
}
}
// UPDATED!
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
let now = instant::Instant::now();
let dt = now - last_render_time;
last_render_time = now;
state.update(dt);
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
}
_ => {}
}
});
}).unwrap();
}

@ -241,8 +241,7 @@ impl GenerateChunk for TerrainPipeline {
let gen_buffer = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("TerrainPipeline: ChunkData"),
size: size_of_val(&data) as _,
usage: wgpu::BufferUsages::UNIFORM
| wgpu::BufferUsages::COPY_DST,
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false,
});
queue.write_buffer(&gen_buffer, 0, bytemuck::bytes_of(&data));

@ -63,7 +63,14 @@ impl Texture {
address_mode: AddressMode, // NEW!
) -> Result<Self> {
let img = image::load_from_memory(bytes)?;
Self::from_image(device, queue, &img, Some(label), is_normal_map, address_mode) // UPDATED!
Self::from_image(
device,
queue,
&img,
Some(label),
is_normal_map,
address_mode,
) // UPDATED!
}
pub fn from_image(
@ -117,7 +124,7 @@ impl Texture {
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
// UPDATED!
address_mode_u: address_mode,
address_mode_u: address_mode,
address_mode_v: address_mode,
address_mode_w: address_mode,
mag_filter: wgpu::FilterMode::Linear,

@ -3,6 +3,7 @@ use std::f32::consts::FRAC_PI_2;
use std::time::Duration;
use winit::dpi::PhysicalPosition;
use winit::event::*;
use winit::keyboard::KeyCode;
#[rustfmt::skip]
pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
@ -104,34 +105,34 @@ impl CameraController {
}
}
pub fn process_keyboard(&mut self, key: VirtualKeyCode, state: ElementState) -> bool {
pub fn process_keyboard(&mut self, key: KeyCode, state: ElementState) -> bool {
let amount = if state == ElementState::Pressed {
1.0
} else {
0.0
};
match key {
VirtualKeyCode::W | VirtualKeyCode::Up => {
KeyCode::KeyW | KeyCode::ArrowUp => {
self.amount_forward = amount;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.amount_backward = amount;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.amount_left = amount;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.amount_right = amount;
true
}
VirtualKeyCode::Space => {
KeyCode::Space => {
self.amount_up = amount;
true
}
VirtualKeyCode::LShift => {
KeyCode::ShiftLeft => {
self.amount_down = amount;
true
}

@ -6,6 +6,7 @@ use winit::{
dpi::PhysicalPosition,
event::*,
event_loop::{ControlFlow, EventLoop},
keyboard::{KeyCode, PhysicalKey},
window::Window,
};
@ -129,8 +130,8 @@ struct LightUniform {
_padding2: u32,
}
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -155,11 +156,11 @@ struct State {
debug_material: model::Material,
last_mouse_pos: PhysicalPosition<f64>,
mouse_pressed: bool,
window: Window,
window: &'a Window,
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -169,11 +170,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -187,10 +184,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -219,6 +216,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -506,9 +504,9 @@ impl State {
fn input(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
virtual_keycode: Some(key),
event:
KeyEvent {
physical_key: PhysicalKey::Code(key),
state,
..
},
@ -636,18 +634,16 @@ fn main() {
async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let title = env!("CARGO_PKG_NAME");
let window = winit::window::WindowBuilder::new()
.with_title(title)
.build(&event_loop)
.unwrap();
let mut state = State::new(window).await; // NEW!
let mut state = State::new(&window).await; // NEW!
let mut last_render_time = std::time::Instant::now();
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
match event {
Event::MainEventsCleared => state.window().request_redraw(),
event_loop
.run(move |event, control_flow| match event {
Event::WindowEvent {
ref event,
window_id,
@ -656,32 +652,30 @@ async fn run() {
match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
state.resize(**new_inner_size);
WindowEvent::RedrawRequested => {
state.window.request_redraw();
let now = std::time::Instant::now();
let dt = now - last_render_time;
last_render_time = now;
state.update(dt);
state.render();
}
_ => {}
}
}
}
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
let now = std::time::Instant::now();
let dt = now - last_render_time;
last_render_time = now;
state.update(dt);
state.render();
}
_ => {}
}
});
})
.unwrap();
}

@ -298,7 +298,10 @@ impl ModelLoader {
m.mesh.positions[i * 3 + 2],
],
// tex_coords: [m.mesh.texcoords[i * 2], m.mesh.texcoords[i * 2 + 1], 0.0]
tex_coords: [m.mesh.texcoords[i * 2], 1.0 - m.mesh.texcoords[i * 2 + 1]],
tex_coords: [
m.mesh.texcoords[i * 2],
1.0 - m.mesh.texcoords[i * 2 + 1],
],
normal: [
m.mesh.normals[i * 3],
m.mesh.normals[i * 3 + 1],

@ -3,6 +3,7 @@ use std::f32::consts::FRAC_PI_2;
use std::time::Duration;
use winit::dpi::PhysicalPosition;
use winit::event::*;
use winit::keyboard::KeyCode;
#[rustfmt::skip]
pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
@ -104,34 +105,34 @@ impl CameraController {
}
}
pub fn process_keyboard(&mut self, key: VirtualKeyCode, state: ElementState) -> bool {
pub fn process_keyboard(&mut self, key: KeyCode, state: ElementState) -> bool {
let amount = if state == ElementState::Pressed {
1.0
} else {
0.0
};
match key {
VirtualKeyCode::W | VirtualKeyCode::Up => {
KeyCode::KeyW | KeyCode::ArrowUp => {
self.amount_forward = amount;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.amount_backward = amount;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.amount_left = amount;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.amount_right = amount;
true
}
VirtualKeyCode::Space => {
KeyCode::Space => {
self.amount_up = amount;
true
}
VirtualKeyCode::LShift => {
KeyCode::ShiftLeft => {
self.amount_down = amount;
true
}

@ -21,24 +21,25 @@ use std::time::{Duration, Instant};
use wgpu::util::{BufferInitDescriptor, DeviceExt};
use winit::event::*;
use winit::event_loop::{ControlFlow, EventLoop};
use winit::keyboard::{KeyCode, PhysicalKey};
use winit::window::{Window, WindowBuilder};
pub struct Display {
surface: wgpu::Surface,
pub window: Window,
pub struct Display<'a> {
surface: wgpu::Surface<'a>,
pub window: &'a Window,
pub config: wgpu::SurfaceConfiguration,
pub device: wgpu::Device,
pub queue: wgpu::Queue,
}
impl Display {
pub async fn new(window: Window) -> Result<Self, Error> {
impl<'a> Display<'a> {
pub async fn new(window: &'a Window) -> Result<Display<'a>, Error> {
let size = window.inner_size();
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends: wgpu::Backends::all(),
..Default::default()
});
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::default(),
@ -51,10 +52,10 @@ impl Display {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -82,6 +83,7 @@ impl Display {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -214,7 +216,7 @@ impl UniformBinding {
pub trait Demo: 'static + Sized {
fn init(display: &Display) -> Result<Self, Error>;
fn process_mouse(&mut self, dx: f64, dy: f64);
fn process_keyboard(&mut self, key: VirtualKeyCode, pressed: bool);
fn process_keyboard(&mut self, key: KeyCode, pressed: bool);
fn resize(&mut self, display: &Display);
fn update(&mut self, display: &Display, dt: Duration);
fn render(&mut self, display: &mut Display);
@ -223,74 +225,71 @@ pub trait Demo: 'static + Sized {
pub async fn run<D: Demo>() -> Result<(), Error> {
wgpu_subscriber::initialize_default_subscriber(None);
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new()
.with_title(env!("CARGO_PKG_NAME"))
.build(&event_loop)?;
let mut display = Display::new(window).await?;
let mut display = Display::new(&window).await?;
let mut demo = D::init(&display)?;
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
event_loop.run(move |event, control_flow| {
if is_resumed && is_focused {
control_flow.set_control_flow(ControlFlow::Poll)
} else {
ControlFlow::Wait
control_flow.set_control_flow(ControlFlow::Wait)
};
match event {
Event::Resumed => is_resumed = true,
Event::Suspended => is_resumed = false,
Event::RedrawRequested(wid) => {
if wid == display.window().id() {
let now = Instant::now();
let dt = now - last_update;
last_update = now;
demo.update(&display, dt);
demo.render(&mut display);
is_redraw_requested = false;
}
}
Event::MainEventsCleared => {
if is_focused && is_resumed && !is_redraw_requested {
display.window().request_redraw();
is_redraw_requested = true;
} else {
// Freeze time while the demo is not in the foreground
last_update = Instant::now();
}
}
Event::WindowEvent {
event, window_id, ..
} => {
if window_id == display.window().id() {
match event {
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
WindowEvent::CloseRequested => control_flow.exit(),
WindowEvent::Focused(f) => is_focused = f,
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
display.resize(new_inner_size.width, new_inner_size.height);
demo.resize(&display);
}
WindowEvent::Resized(new_inner_size) => {
display.resize(new_inner_size.width, new_inner_size.height);
demo.resize(&display);
}
WindowEvent::KeyboardInput { input: KeyboardInput {
virtual_keycode: Some(key),
state,
WindowEvent::KeyboardInput {
event:
KeyEvent {
physical_key: PhysicalKey::Code(key),
state,
..
},
..
}, .. } => {
} => {
demo.process_keyboard(key, state == ElementState::Pressed);
}
WindowEvent::RedrawRequested => {
let now = Instant::now();
let dt = now - last_update;
last_update = now;
demo.update(&display, dt);
demo.render(&mut display);
if is_focused && is_resumed {
display.window().request_redraw();
} else {
// Freeze time while the demo is not in the foreground
last_update = Instant::now();
}
}
_ => {}
}
}
}
_ => {}
}
});
})?;
Ok(())
}

@ -1,7 +1,7 @@
use anyhow::*;
use image::GenericImageView;
use std::path::Path;
use std::mem;
use std::path::Path;
use crate::buffer;

@ -16,10 +16,10 @@ async fn run() {
.request_device(
&wgpu::DeviceDescriptor {
label: Some("Device"),
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()

@ -7,7 +7,7 @@ use winit::{
};
async fn run() -> anyhow::Result<()> {
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let mut window = Some(
WindowBuilder::new()
.with_visible(false)
@ -31,7 +31,7 @@ async fn run() -> anyhow::Result<()> {
&wgpu::DeviceDescriptor {
label: None,
features: Default::default(),
limits: Default::default(),
required_limits: Default::default(),
},
None,
)

@ -3,6 +3,7 @@ use std::f32::consts::FRAC_PI_2;
use std::time::Duration;
use winit::dpi::PhysicalPosition;
use winit::event::*;
use winit::keyboard::KeyCode;
#[rustfmt::skip]
pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
@ -104,34 +105,34 @@ impl CameraController {
}
}
pub fn process_keyboard(&mut self, key: VirtualKeyCode, state: ElementState) -> bool {
pub fn process_keyboard(&mut self, key: KeyCode, state: ElementState) -> bool {
let amount = if state == ElementState::Pressed {
1.0
} else {
0.0
};
match key {
VirtualKeyCode::W | VirtualKeyCode::Up => {
KeyCode::KeyW | KeyCode::ArrowUp => {
self.amount_forward = amount;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.amount_backward = amount;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.amount_left = amount;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.amount_right = amount;
true
}
VirtualKeyCode::Space => {
KeyCode::Space => {
self.amount_up = amount;
true
}
VirtualKeyCode::LShift => {
KeyCode::ShiftLeft => {
self.amount_down = amount;
true
}

@ -6,6 +6,7 @@ use wgpu::util::DeviceExt;
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
keyboard::{KeyCode, PhysicalKey},
window::Window,
};
@ -131,9 +132,9 @@ struct LightUniform {
_padding2: u32,
}
struct State {
window: Window,
surface: wgpu::Surface,
struct State<'a> {
window: &'a Window,
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -224,8 +225,8 @@ fn create_render_pipeline(
})
}
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -235,11 +236,7 @@ impl State {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -253,10 +250,10 @@ impl State {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -285,6 +282,7 @@ impl State {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
@ -577,9 +575,9 @@ impl State {
fn input(&mut self, event: &WindowEvent) -> bool {
match event {
WindowEvent::KeyboardInput {
input:
KeyboardInput {
virtual_keycode: Some(key),
event:
KeyEvent {
physical_key: PhysicalKey::Code(key),
state,
..
},
@ -733,7 +731,7 @@ pub async fn run() {
}
}
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let title = env!("CARGO_PKG_NAME");
let window = winit::window::WindowBuilder::new()
.with_title(title)
@ -759,12 +757,10 @@ pub async fn run() {
.expect("Couldn't append canvas to document body.");
}
let mut state = State::new(window).await; // NEW!
let mut state = State::new(&window).await; // NEW!
let mut last_render_time = instant::Instant::now();
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
event_loop.run(move |event, control_flow| {
match event {
Event::MainEventsCleared => state.window().request_redraw(),
// NEW!
Event::DeviceEvent {
event: DeviceEvent::MouseMotion{ delta, },
@ -781,40 +777,38 @@ pub async fn run() {
#[cfg(not(target_arch="wasm32"))]
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
state.resize(**new_inner_size);
// UPDATED!
WindowEvent::RedrawRequested => {
state.window.request_redraw();
let now = instant::Instant::now();
let dt = now - last_render_time;
last_render_time = now;
state.update(dt);
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => control_flow.exit(),
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
}
_ => {}
}
}
// UPDATED!
Event::RedrawRequested(window_id) if window_id == state.window().id() => {
let now = instant::Instant::now();
let dt = now - last_render_time;
last_render_time = now;
state.update(dt);
match state.render() {
Ok(_) => {}
// Reconfigure the surface if it's lost or outdated
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => state.resize(state.size),
// The system is out of memory, we should probably quit
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
// We're ignoring timeouts
Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
}
}
_ => {}
}
});
}).unwrap();
}

@ -27,7 +27,7 @@ pub fn start() {
}
}
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let monitor = event_loop.primary_monitor().unwrap();
let video_mode = monitor.video_modes().next();
let size = video_mode
@ -159,7 +159,7 @@ pub fn start() {
log::info!("Event Loop...");
event_loop.run(move |event, _, control_flow| {
event_loop.run(move |event, control_flow| {
*control_flow = if state.game_state == state::GameState::Quiting {
ControlFlow::Exit
} else {

@ -45,11 +45,7 @@ impl Render {
..Default::default()
});
// # Safety
//
// The surface needs to live as long as the window that created it.
// State owns the window so this should be safe.
let surface = unsafe { instance.create_surface(&window) }.unwrap();
let surface = instance.create_surface(window).unwrap();
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -63,8 +59,8 @@ impl Render {
.request_device(
&wgpu::DeviceDescriptor {
label: None,
features: wgpu::Features::empty(),
limits: wgpu::Limits::downlevel_webgl2_defaults(),
required_features: wgpu::Features::empty(),
required_limits: wgpu::Limits::downlevel_webgl2_defaults(),
},
None, // Trace path
)
@ -89,6 +85,7 @@ impl Render {
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);

@ -1,6 +1,9 @@
use std::{time::Duration, f32::consts::FRAC_PI_2};
use std::{f32::consts::FRAC_PI_2, time::Duration};
use winit::{event::{VirtualKeyCode, MouseScrollDelta}, dpi::PhysicalPosition};
use winit::{
dpi::PhysicalPosition,
event::{MouseScrollDelta, VirtualKeyCode},
};
const SAFE_FRAC_PI_2: f32 = FRAC_PI_2 - 0.0001;
@ -12,11 +15,7 @@ pub struct Camera {
}
impl Camera {
pub fn new<V: Into<glam::Vec3>>(
position: V,
yaw: f32,
pitch: f32,
) -> Self {
pub fn new<V: Into<glam::Vec3>>(position: V, yaw: f32, pitch: f32) -> Self {
Self {
position: position.into(),
yaw,
@ -95,11 +94,7 @@ impl CameraController {
}
pub fn process_keyboard(&mut self, key: VirtualKeyCode, pressed: bool) -> bool {
let amount = if pressed {
1.0
} else {
0.0
};
let amount = if pressed { 1.0 } else { 0.0 };
match key {
VirtualKeyCode::W | VirtualKeyCode::Up => {
self.amount_forward = amount;
@ -183,4 +178,4 @@ impl CameraController {
camera.pitch = SAFE_FRAC_PI_2;
}
}
}
}

@ -2,7 +2,7 @@ mod camera;
use std::f32::consts::PI;
use camera::{Camera, Projection, CameraController};
use camera::{Camera, CameraController, Projection};
use wgpu::util::{BufferInitDescriptor, DeviceExt};
const MAX_PARTICLES: u32 = 1000;
@ -181,21 +181,25 @@ impl framework::Demo for Snow {
entries: &[wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::VERTEX,
ty: wgpu::BindingType::Buffer { ty: wgpu::BufferBindingType::Uniform, has_dynamic_offset: false, min_binding_size: None },
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
}],
});
let uniforms_bind_group = display.device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("uniforms_bind_group"),
layout: &uniforms_bind_group_layout,
entries: &[
wgpu::BindGroupEntry {
let uniforms_bind_group = display
.device
.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("uniforms_bind_group"),
layout: &uniforms_bind_group_layout,
entries: &[wgpu::BindGroupEntry {
binding: 0,
resource: uniform_buffer.as_entire_binding(),
}
],
});
}],
});
let draw_particles_layout =
display
@ -260,14 +264,15 @@ impl framework::Demo for Snow {
self.camera_controller.process_mouse(dx, dy);
self.uniforms_dirty = true;
}
fn process_keyboard(&mut self, key: winit::event::VirtualKeyCode, pressed: bool) {
self.camera_controller.process_keyboard(key, pressed);
self.uniforms_dirty = true;
}
fn resize(&mut self, display: &framework::Display) {
self.projection.resize(display.config.width, display.config.height);
self.projection
.resize(display.config.width, display.config.height);
self.uniforms_dirty = true;
self.uniforms_dirty = true;
}
@ -278,7 +283,9 @@ impl framework::Demo for Snow {
self.uniforms_dirty = false;
self.camera_controller.update_camera(&mut self.camera, dt);
self.uniforms.view_proj = self.projection.calc_matrix() * self.camera.calc_matrix();
display.queue.write_buffer(&self.uniform_buffer, 0, bytemuck::bytes_of(&self.uniforms));
display
.queue
.write_buffer(&self.uniform_buffer, 0, bytemuck::bytes_of(&self.uniforms));
}
let dt = dt.as_secs_f32();

@ -1,9 +1,9 @@
use cgmath::*;
use winit::keyboard::KeyCode;
use std::f32::consts::FRAC_PI_2;
use std::time::Duration;
use winit::dpi::PhysicalPosition;
use winit::event::*;
use winit::keyboard::KeyCode;
#[rustfmt::skip]
pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(

@ -39,7 +39,7 @@ use winit::{
pub fn run() {
env_logger::init();
let event_loop = EventLoop::new();
let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new().build(&event_loop).unwrap();
event_loop.run(move |event, _, control_flow| match event {

@ -7,8 +7,8 @@ For convenience, we're going to pack all the fields into a struct and create som
// lib.rs
use winit::window::Window;
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -16,12 +16,12 @@ struct State {
// The window must be declared after the surface so
// it gets dropped after it as the surface contains
// unsafe references to the window's resources.
window: Window,
window: &'a Window,
}
impl State {
impl<'a> State<'a> {
// Creating some of the wgpu types requires async code
async fn new(window: Window) -> Self {
async fn new(window: &'a Window) -> State<'a> {
todo!()
}
@ -53,9 +53,9 @@ I'm glossing over `State`s fields, but they'll make more sense as I explain the
The code for this is pretty straightforward, but let's break it down a bit.
```rust
impl State {
impl<'a> State<'a> {
// ...
async fn new(window: Window) -> Self {
async fn new(window: &'a Window) -> State<'a> {
let size = window.inner_size();
// The instance is a handle to our GPU
@ -127,10 +127,10 @@ Let's use the `adapter` to create the device and queue.
```rust
let (device, queue) = adapter.request_device(
&wgpu::DeviceDescriptor {
features: wgpu::Features::empty(),
required_features: wgpu::Features::empty(),
// WebGL doesn't support all of wgpu's features, so if
// we're building for the web, we'll have to disable some.
limits: if cfg!(target_arch = "wasm32") {
required_limits: if cfg!(target_arch = "wasm32") {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
@ -145,7 +145,7 @@ The `features` field on `DeviceDescriptor` allows us to specify what extra featu
<div class="note">
The graphics card you have limits the features you can use. If you want to use certain features, you may need to limit what devices you support or provide workarounds.
The graphics card you haverequired_limits the features you can use. If you want to use certain features, you may need to limit what devices you support or provide workarounds.
You can get a list of features supported by your device using `adapter.features()` or `device.features()`.
@ -153,7 +153,7 @@ You can view a full list of features [here](https://docs.rs/wgpu/latest/wgpu/str
</div>
The `limits` field describes the limit of certain types of resources that we can create. We'll use the defaults for this tutorial so we can support most devices. You can view a list of limits [here](https://docs.rs/wgpu/latest/wgpu/struct.Limits.html).
The `limits` field describes the limit of certain types of resources that we can create. We'll use the defaults for this tutorial so we can support most devices. You can view a list ofrequired_limits [here](https://docs.rs/wgpu/latest/wgpu/struct.Limits.html).
```rust
let surface_caps = surface.get_capabilities(&adapter);
@ -173,6 +173,7 @@ The `limits` field describes the limit of certain types of resources that we can
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
desired_maximum_frame_latency: 2,
};
surface.configure(&device, &config);
```
@ -210,7 +211,7 @@ Regardless, `PresentMode::Fifo` will always be supported, and `PresentMode::Auto
Now that we've configured our surface properly, we can add these new fields at the end of the method.
```rust
async fn new(window: Window) -> Self {
async fn new(window: &'a Window) -> State<'a> {
// ...
Self {
@ -233,9 +234,9 @@ Our `window` has beened moved to the State instance, we will need to update our
pub async fn run() {
// Window setup...
let mut state = State::new(window).await;
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
event_loop.run(move |event, control_flow| {
match event {
Event::WindowEvent {
ref event,

@ -156,8 +156,8 @@ This is the part where we finally make the thing in the title: the pipeline. Fir
```rust
// lib.rs
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,

@ -247,7 +247,7 @@ struct State {
num_vertices: u32,
}
impl State {
impl<'a> State<'a> {
// ...
fn new(...) -> Self {
// ...
@ -380,8 +380,8 @@ let num_indices = INDICES.len() as u32;
We don't need to implement `Pod` and `Zeroable` for our indices because `bytemuck` has already implemented them for basic types such as `u16`. That means we can just add `index_buffer` and `num_indices` to the `State` struct.
```rust
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,

@ -242,8 +242,8 @@ Looking at this, you might get a bit of déjà vu! That's because a `BindGroup`
Now that we have our `diffuse_bind_group`, let's add it to our `State` struct:
```rust
struct State {
surface: wgpu::Surface,
struct State<'a> {
surface: wgpu::Surface<'a>,
device: wgpu::Device,
queue: wgpu::Queue,
config: wgpu::SurfaceConfiguration,
@ -259,7 +259,7 @@ struct State {
Make sure we return these fields in the `new` method:
```rust
impl State {
impl<'a> State<'a> {
async fn new() -> Self {
// ...
Self {
@ -593,7 +593,7 @@ struct State {
```
```rust
impl State {
impl<'a> State<'a> {
async fn new() -> Self {
// ...
Self {

@ -310,20 +310,19 @@ impl CameraController {
..
} => {
let is_pressed = *state == ElementState::Pressed;
match keycode {
VirtualKeyCode::W | VirtualKeyCode::Up => {
match keycode {KeyCode::KeyW | KeyCode::ArrowUp => {
self.is_forward_pressed = is_pressed;
true
}
VirtualKeyCode::A | VirtualKeyCode::Left => {
KeyCode::KeyA | KeyCode::ArrowLeft => {
self.is_left_pressed = is_pressed;
true
}
VirtualKeyCode::S | VirtualKeyCode::Down => {
KeyCode::KeyS | KeyCode::ArrowDown => {
self.is_backward_pressed = is_pressed;
true
}
VirtualKeyCode::D | VirtualKeyCode::Right => {
KeyCode::KeyD | KeyCode::ArrowRight => {
self.is_right_pressed = is_pressed;
true
}
@ -381,8 +380,8 @@ struct State {
// ...
}
// ...
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
// ...
let camera_controller = CameraController::new(0.2);
// ...

@ -97,8 +97,8 @@ const INSTANCE_DISPLACEMENT: cgmath::Vector3<f32> = cgmath::Vector3::new(NUM_INS
Now, we can create the actual instances.
```rust
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
// ...
let instances = (0..NUM_INSTANCES_PER_ROW).flat_map(|z| {
(0..NUM_INSTANCES_PER_ROW).map(move |x| {

@ -453,7 +453,7 @@ where
Finally, we want to add Light rendering to our render passes.
```rust
impl State {
impl<'a> State<'a> {
// ...
fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
// ...

@ -568,7 +568,7 @@ I found a cobblestone texture with a matching normal map and created a `debug_ma
```rust
// lib.rs
impl State {
impl<'a> State<'a> {
async fn new(window: &Window) -> Result<Self> {
// ...
let debug_material = {

@ -293,8 +293,8 @@ You'll need to import `winit::dpi::PhysicalPosition` if you haven't already.
We need to update `new()` as well.
```rust
impl State {
async fn new(window: Window) -> Self {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> State<'a> {
// ...
// UPDATED!
@ -369,8 +369,7 @@ Here are the changes to `run()`:
```rust
fn main() {
// ...
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
event_loop.run(move |event, control_flow| {
match event {
// ...
// NEW!
@ -389,14 +388,14 @@ fn main() {
#[cfg(not(target_arch="wasm32"))]
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
} => *control_flow = ControlFlow::Exit,
} => control_flow.exit(),
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
@ -437,10 +436,9 @@ We still need to calculate `dt`. Let's do that in the `main` function.
```rust
fn main() {
// ...
let mut state = State::new(window).await;
let mut state = State::new(&window).await;
let mut last_render_time = instant::Instant::now(); // NEW!
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
event_loop.run(move |event, control_flow| {
match event {
// ...
// UPDATED!

@ -1,6 +1,6 @@
# High Dynamic Range Rendering
Up to this point, we've been using the sRGB colorspace to render our scene. While this is fine, it limits what we can do with our lighting. We are using `TextureFormat::Bgra8UnormSrgb` (on most systems) for our surface texture. This means we have 8 bits for each red, green, blue and alpha channel. While the channels are stored as integers between 0 and 255 inclusively, they get converted to and from floating point values between 0.0 and 1.0. The TL:DR of this is that using 8-bit textures, we only get 256 possible values in each channel.
Up to this point, we've been using the sRGB colorspace to render our scene. While this is fine, itrequired_limits what we can do with our lighting. We are using `TextureFormat::Bgra8UnormSrgb` (on most systems) for our surface texture. This means we have 8 bits for each red, green, blue and alpha channel. While the channels are stored as integers between 0 and 255 inclusively, they get converted to and from floating point values between 0.0 and 1.0. The TL:DR of this is that using 8-bit textures, we only get 256 possible values in each channel.
The kicker with this is most of the precision gets used to represent darker values of the scene. This means that bright objects like light bulbs have the same value as exceedingly bright objects like the sun. This inaccuracy makes realistic lighting difficult to do right. Because of this, we are going to switch our rendering system to use high dynamic range in order to give our scene more flexibility and enable us to leverage more advanced techniques such as Physically Based Rendering.
@ -290,7 +290,7 @@ struct State {
hdr: hdr::HdrPipeline,
}
impl State {
impl<'a> State<'a> {
pub fn new(window: Window) -> anyhow::Result<Self> {
// ...
// NEW!
@ -477,7 +477,7 @@ let (device, queue) = adapter
// UPDATED!
features: wgpu::Features::all_webgpu_mask(),
// UPDATED!
limits: wgpu::Limits::downlevel_defaults(),
required_limits: wgpu::Limits::downlevel_defaults(),
},
None, // Trace path
)
@ -910,8 +910,8 @@ struct State {
}
// ...
impl State {
async fn new(window: Window) -> anyhow::Result<Self> {
impl<'a> State<'a> {
async fn new(window: &'a Window) -> anyhow::Result<State<'a>> {
// ...
Ok(Self {
// ...

Loading…
Cancel
Save