Compare commits

...

3 Commits

Author SHA1 Message Date
Benjamin Hansen ce957226d3 cargo fmt 3 weeks ago
Benjamin Hansen 09c1024a8f fixed non-srgb on hdr tutorial 3 weeks ago
Benjamin Hansen 3d27fca202 demos working 3 weeks ago

3
Cargo.lock generated

@ -1671,6 +1671,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
"js-sys",
"wasm-bindgen",
"web-sys",
]
[[package]]

@ -28,9 +28,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});

@ -29,9 +29,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});

@ -26,9 +26,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});

@ -28,9 +28,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});

@ -89,9 +89,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});

@ -85,9 +85,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});

@ -91,9 +91,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});

@ -91,9 +91,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});

@ -241,9 +241,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});

@ -241,9 +241,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});

@ -295,9 +295,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});

@ -302,9 +302,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});

@ -494,9 +494,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});

@ -312,9 +312,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});

@ -10,11 +10,13 @@ pub struct Texture {
impl Texture {
pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
#[allow(unused)]
pub fn create_depth_texture(
device: &wgpu::Device,
config: &wgpu::SurfaceConfiguration,
label: &str,
) -> Self {let size = wgpu::Extent3d {
) -> Self {
let size = wgpu::Extent3d {
width: config.width.max(1),
height: config.height.max(1),
depth_or_array_layers: 1,
@ -57,7 +59,7 @@ impl Texture {
config: &wgpu::SurfaceConfiguration,
label: &str,
) -> Self {
let size = wgpu::Extent3d {
let size = wgpu::Extent3d {
width: config.width.max(1),
height: config.height.max(1),
depth_or_array_layers: 1,

@ -253,9 +253,9 @@ impl<'a> State<'a> {
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
log::warn!("WGPU setup");
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});
@ -312,7 +312,6 @@ impl<'a> State<'a> {
desired_maximum_frame_latency: 2,
};
let texture_bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[

@ -347,9 +347,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});
@ -403,7 +403,6 @@ impl<'a> State<'a> {
desired_maximum_frame_latency: 2,
};
let texture_bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[

@ -15,7 +15,7 @@ impl Texture {
config: &wgpu::SurfaceConfiguration,
label: &str,
) -> Self {
let size = wgpu::Extent3d {
let size = wgpu::Extent3d {
width: config.width.max(1),
height: config.height.max(1),
depth_or_array_layers: 1,

@ -347,9 +347,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});
@ -403,7 +403,6 @@ impl<'a> State<'a> {
desired_maximum_frame_latency: 2,
};
let texture_bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[

@ -15,7 +15,7 @@ impl Texture {
config: &wgpu::SurfaceConfiguration,
label: &str,
) -> Self {
let size = wgpu::Extent3d {
let size = wgpu::Extent3d {
width: config.width.max(1),
height: config.height.max(1),
depth_or_array_layers: 1,

@ -38,6 +38,7 @@ web-sys = { version = "0.3", features = [
"Element",
"Location",
]}
instant = { version = "0.1", features = [ "wasm-bindgen" ] }
[build-dependencies]
anyhow = "1.0"

@ -227,9 +227,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});
@ -283,7 +283,6 @@ impl<'a> State<'a> {
desired_maximum_frame_latency: 2,
};
let texture_bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[

@ -37,6 +37,7 @@ web-sys = { version = "0.3", features = [
"Element",
"Location",
]}
instant = { version = "0.1", features = [ "wasm-bindgen" ] }
[build-dependencies]
anyhow = "1.0"

@ -79,7 +79,7 @@ impl HdrPipeline {
let pipeline = create_render_pipeline(
device,
&pipeline_layout,
config.format,
config.format.add_srgb_suffix(),
None,
&[],
wgpu::PrimitiveTopology::TriangleList,

@ -247,7 +247,7 @@ impl<'a> State<'a> {
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
// UPDATED
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::BROWSER_WEBGPU,
@ -295,11 +295,11 @@ impl<'a> State<'a> {
height: size.height,
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
view_formats: vec![],
// NEW!
view_formats: vec![surface_format.add_srgb_suffix()],
desired_maximum_frame_latency: 2,
};
let texture_bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[
@ -712,9 +712,10 @@ impl<'a> State<'a> {
fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
let output = self.surface.get_current_texture()?;
let view = output
.texture
.create_view(&wgpu::TextureViewDescriptor::default());
let view = output.texture.create_view(&wgpu::TextureViewDescriptor {
format: Some(self.config.format.add_srgb_suffix()),
..Default::default()
});
let mut encoder = self
.device

@ -286,14 +286,28 @@ impl HdrLoader {
) -> anyhow::Result<texture::CubeTexture> {
let hdr_decoder = HdrDecoder::new(Cursor::new(data))?;
let meta = hdr_decoder.metadata();
let mut pixels = vec![[0.0, 0.0, 0.0, 0.0]; meta.width as usize * meta.height as usize];
hdr_decoder.read_image_transform(
|pix| {
#[cfg(not(target_arch = "wasm32"))]
let pixels = {
let mut pixels = vec![[0.0, 0.0, 0.0, 0.0]; meta.width as usize * meta.height as usize];
hdr_decoder.read_image_transform(
|pix| {
let rgb = pix.to_hdr();
[rgb.0[0], rgb.0[1], rgb.0[2], 1.0f32]
},
&mut pixels[..],
)?;
pixels
};
#[cfg(target_arch = "wasm32")]
let pixels = hdr_decoder
.read_image_native()?
.into_iter()
.map(|pix| {
let rgb = pix.to_hdr();
[rgb.0[0], rgb.0[1], rgb.0[2], 1.0f32]
},
&mut pixels[..],
)?;
})
.collect::<Vec<_>>();
let src = texture::Texture::create_2d_texture(
device,

@ -16,7 +16,7 @@ impl Texture {
config: &wgpu::SurfaceConfiguration,
label: &str,
) -> Self {
let size = wgpu::Extent3d {
let size = wgpu::Extent3d {
width: config.width.max(1),
height: config.height.max(1),
depth_or_array_layers: 1,

@ -228,9 +228,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});
@ -284,7 +284,6 @@ impl<'a> State<'a> {
desired_maximum_frame_latency: 2,
};
let texture_bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[

@ -16,7 +16,7 @@ impl Texture {
config: &wgpu::SurfaceConfiguration,
label: &str,
) -> Self {
let size = wgpu::Extent3d {
let size = wgpu::Extent3d {
width: config.width.max(1),
height: config.height.max(1),
depth_or_array_layers: 1,

@ -166,9 +166,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});
@ -222,7 +222,6 @@ impl<'a> State<'a> {
desired_maximum_frame_latency: 2,
};
let texture_bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[

@ -30,7 +30,7 @@ impl Texture {
config: &wgpu::SurfaceConfiguration,
label: &str,
) -> Self {
let size = wgpu::Extent3d {
let size = wgpu::Extent3d {
width: config.width.max(1),
height: config.height.max(1),
depth_or_array_layers: 1,

@ -36,9 +36,9 @@ 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 {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});

@ -232,9 +232,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});
@ -288,7 +288,6 @@ impl<'a> State<'a> {
desired_maximum_frame_latency: 2,
};
let texture_bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[

@ -15,7 +15,7 @@ impl Texture {
config: &wgpu::SurfaceConfiguration,
label: &str,
) -> Self {
let size = wgpu::Extent3d {
let size = wgpu::Extent3d {
width: config.width.max(1),
height: config.height.max(1),
depth_or_array_layers: 1,

@ -158,113 +158,115 @@ pub fn start() {
let window = &window;
let mut last_time = instant::Instant::now();
event_loop.run(move |event, control_flow| {
match event {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => {
state.game_state = state::GameState::Quiting;
}
Event::WindowEvent {
event:
WindowEvent::KeyboardInput {
event:
KeyEvent {
state: element_state,
physical_key: PhysicalKey::Code(key),
..
},
..
},
..
} => {
let input_handled = match state.game_state {
state::GameState::Quiting => true,
_ => input.update(key, element_state),
};
if !input_handled {
process_input(element_state, key, control_flow);
event_loop
.run(move |event, control_flow| {
match event {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => {
state.game_state = state::GameState::Quiting;
}
}
Event::WindowEvent {
event: WindowEvent::Resized(size),
..
} => {
render.resize(size);
events.push(state::Event::Resize(size.width as f32, size.height as f32));
}
Event::WindowEvent {
event: WindowEvent::RedrawRequested,
..
} => {
let dt = last_time.elapsed();
last_time = instant::Instant::now();
window.request_redraw();
for event in &events {
match event {
state::Event::FocusChanged | state::Event::ButtonPressed => {
sound_system.queue(sound_pack.bounce());
}
state::Event::BallBounce(_pos) => {
sound_system.queue(sound_pack.bounce());
}
state::Event::Score(_) => {
sound_system.queue(sound_pack.bounce());
}
state::Event::Resize(width, height) => {
// TODO: there should be a system that handles this
state.player1_score.position = (width * 0.25, 20.0).into();
state.player2_score.position = (width * 0.75, 20.0).into();
state.win_text.position = (width * 0.5, height * 0.5).into();
}
Event::WindowEvent {
event:
WindowEvent::KeyboardInput {
event:
KeyEvent {
state: element_state,
physical_key: PhysicalKey::Code(key),
..
},
..
},
..
} => {
let input_handled = match state.game_state {
state::GameState::Quiting => true,
_ => input.update(key, element_state),
};
if !input_handled {
process_input(element_state, key, control_flow);
}
}
events.clear();
visiblity_system.update_state(&input, dt, &mut state, &mut events);
match state.game_state {
state::GameState::MainMenu => {
menu_system.update_state(&input, dt, &mut state, &mut events);
if state.game_state == state::GameState::Serving {
serving_system.start(&mut state);
Event::WindowEvent {
event: WindowEvent::Resized(size),
..
} => {
render.resize(size);
events.push(state::Event::Resize(size.width as f32, size.height as f32));
}
Event::WindowEvent {
event: WindowEvent::RedrawRequested,
..
} => {
let dt = last_time.elapsed();
last_time = instant::Instant::now();
window.request_redraw();
for event in &events {
match event {
state::Event::FocusChanged | state::Event::ButtonPressed => {
sound_system.queue(sound_pack.bounce());
}
state::Event::BallBounce(_pos) => {
sound_system.queue(sound_pack.bounce());
}
state::Event::Score(_) => {
sound_system.queue(sound_pack.bounce());
}
state::Event::Resize(width, height) => {
// TODO: there should be a system that handles this
state.player1_score.position = (width * 0.25, 20.0).into();
state.player2_score.position = (width * 0.75, 20.0).into();
state.win_text.position = (width * 0.5, height * 0.5).into();
}
}
}
state::GameState::Serving => {
serving_system.update_state(&input, dt, &mut state, &mut events);
play_system.update_state(&input, dt, &mut state, &mut events);
if state.game_state == state::GameState::Playing {
play_system.start(&mut state);
events.clear();
visiblity_system.update_state(&input, dt, &mut state, &mut events);
match state.game_state {
state::GameState::MainMenu => {
menu_system.update_state(&input, dt, &mut state, &mut events);
if state.game_state == state::GameState::Serving {
serving_system.start(&mut state);
}
}
}
state::GameState::Playing => {
ball_system.update_state(&input, dt, &mut state, &mut events);
play_system.update_state(&input, dt, &mut state, &mut events);
if state.game_state == state::GameState::Serving {
serving_system.start(&mut state);
} else if state.game_state == state::GameState::GameOver {
game_over_system.start(&mut state);
state::GameState::Serving => {
serving_system.update_state(&input, dt, &mut state, &mut events);
play_system.update_state(&input, dt, &mut state, &mut events);
if state.game_state == state::GameState::Playing {
play_system.start(&mut state);
}
}
}
state::GameState::GameOver => {
game_over_system.update_state(&input, dt, &mut state, &mut events);
if state.game_state == state::GameState::MainMenu {
menu_system.start(&mut state);
state::GameState::Playing => {
ball_system.update_state(&input, dt, &mut state, &mut events);
play_system.update_state(&input, dt, &mut state, &mut events);
if state.game_state == state::GameState::Serving {
serving_system.start(&mut state);
} else if state.game_state == state::GameState::GameOver {
game_over_system.start(&mut state);
}
}
state::GameState::GameOver => {
game_over_system.update_state(&input, dt, &mut state, &mut events);
if state.game_state == state::GameState::MainMenu {
menu_system.start(&mut state);
}
}
state::GameState::Quiting => {
control_flow.exit();
}
}
state::GameState::Quiting => {
control_flow.exit();
}
}
render.render_state(&state);
if state.game_state != state::GameState::Quiting {
window.request_redraw();
render.render_state(&state);
if state.game_state != state::GameState::Quiting {
window.request_redraw();
}
}
_ => {}
}
_ => {}
}
}).unwrap();
})
.unwrap();
}
fn process_input(
@ -273,9 +275,7 @@ fn process_input(
control_flow: &EventLoopWindowTarget<()>,
) {
match (keycode, element_state) {
(KeyCode::Escape, ElementState::Pressed) => {
control_flow.exit()
}
(KeyCode::Escape, ElementState::Pressed) => control_flow.exit(),
_ => {}
}
}

@ -41,9 +41,9 @@ impl<'a> Render<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});
@ -63,7 +63,7 @@ impl<'a> Render<'a> {
&wgpu::DeviceDescriptor {
label: None,
required_features: wgpu::Features::empty(),
required_limits: wgpu::Limits::downlevel_webgl2_defaults(),
required_limits: wgpu::Limits::downlevel_webgl2_defaults(),
},
None, // Trace path
)

@ -144,7 +144,7 @@ impl System for BallSystem {
events: &mut Vec<state::Event>,
) {
let dt = dt.as_secs_f32();
// bounce the ball off the players
if state.player1.contains(&state.ball) {
events.push(state::Event::BallBounce(state.ball.position));

@ -226,9 +226,9 @@ impl<'a> State<'a> {
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
#[cfg(not(target_arch="wasm32"))]
#[cfg(not(target_arch = "wasm32"))]
backends: wgpu::Backends::PRIMARY,
#[cfg(target_arch="wasm32")]
#[cfg(target_arch = "wasm32")]
backends: wgpu::Backends::GL,
..Default::default()
});
@ -282,7 +282,6 @@ impl<'a> State<'a> {
view_formats: vec![],
};
let texture_bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[

@ -15,7 +15,7 @@ impl Texture {
config: &wgpu::SurfaceConfiguration,
label: &str,
) -> Self {
let size = wgpu::Extent3d {
let size = wgpu::Extent3d {
width: config.width.max(1),
height: config.height.max(1),
depth_or_array_layers: 1,

@ -1,4 +1,7 @@
use std::{path::PathBuf, process::{Command, ExitStatus}};
use std::{
path::PathBuf,
process::{Command, ExitStatus},
};
use anyhow::bail;
use rayon::prelude::{IntoParallelRefIterator, ParallelIterator};

@ -27,7 +27,12 @@ const SAFE_FRAC_PI_2: f32 = FRAC_PI_2 - 0.0001;
`std::time::Instant` panics on WASM, so we'll use the [instant crate](https://docs.rs/instant). You'll want to include it in your `Cargo.toml`:
```toml
[dependencies]
# ...
instant = "0.1"
[target.'cfg(target_arch = "wasm32")'.dependencies]
instant = { version = "0.1", features = [ "wasm-bindgen" ] }
```
</div>

@ -105,7 +105,7 @@ impl HdrPipeline {
let pipeline = create_render_pipeline(
device,
&pipeline_layout,
config.format,
config.format.add_srgb_suffix(),
None,
// We'll use some math to generate the vertex data in
// the shader, so we don't need any vertex buffers
@ -567,16 +567,27 @@ impl HdrLoader {
) -> anyhow::Result<texture::CubeTexture> {
let hdr_decoder = HdrDecoder::new(Cursor::new(data))?;
let meta = hdr_decoder.metadata();
let mut pixels = vec![[0.0, 0.0, 0.0, 0.0]; meta.width as usize * meta.height as usize];
hdr_decoder.read_image_transform(
|pix| {
// There's no Rgb32Float format, so we need
// an extra float
#[cfg(not(target_arch="wasm32"))]
let pixels = {
let mut pixels = vec![[0.0, 0.0, 0.0, 0.0]; meta.width as usize * meta.height as usize];
hdr_decoder.read_image_transform(
|pix| {
let rgb = pix.to_hdr();
[rgb.0[0], rgb.0[1], rgb.0[2], 1.0f32]
},
&mut pixels[..],
)?;
pixels
};
#[cfg(target_arch="wasm32")]
let pixels = hdr_decoder.read_image_native()?
.into_iter()
.map(|pix| {
let rgb = pix.to_hdr();
[rgb.0[0], rgb.0[1], rgb.0[2], 1.0f32]
},
&mut pixels[..],
)?;
})
.collect::<Vec<_>>();
let src = texture::Texture::create_2d_texture(
device,
@ -1201,6 +1212,48 @@ Here's the finished scene:
![with-reflections](./with-reflections.png)
## Output too dark on WebGPU?
WebGPU doesn't support using sRGB texture formats as the
output for a surface. We can get around this by making the
texture view used to render use the sRGB version of the
format. To do this we need to change the surface config
we use to allow view formats with sRGB.
```rust
let config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format: surface_format,
width: size.width,
height: size.height,
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
// NEW!
view_formats: vec![surface_format.add_srgb_suffix()],
desired_maximum_frame_latency: 2,
};
```
Then we need to create a view with sRGB enabled in
`State::render()`.
```rust
let view = output
.texture
.create_view(&wgpu::TextureViewDescriptor {
format: Some(self.config.format.add_srgb_suffix()),
..Default::default()
});
```
You may have noticed as well that in `HdrPipeline::new()`
we use `config.format.add_srgb_suffix()` when creating
the render pipeline. This is required as if we don't
the sRGB enabled `TextureView` won't work with the
render pipeline.
With that you should get the sRGB output as expected.
## Demo
<div class="warn">

Loading…
Cancel
Save