got pong working natively

master
Benjamin Hansen 2 months ago
parent 4daff65c34
commit 6325590051

696
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -16,5 +16,5 @@ members = [
]
exclude = [
"code/showcase/imgui-demo",
"code/showcase/pong",
#"code/showcase/pong",
]

@ -23,9 +23,9 @@ pollster = "0.3"
console_error_panic_hook = "0.1.6"
console_log = "1.0"
wgpu = { version = "0.19", features = ["webgl"]}
wasm-bindgen = "=0.2.90"
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4.30"
web-sys = { version = "0.3.53", features = [
web-sys = { version = "0.3.69", features = [
"Document",
"Window",
"Element",

@ -27,14 +27,14 @@ pub fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -12,7 +12,7 @@ cfg-if = "1"
winit = { version = "0.29", features = ["rwh_05"] }
env_logger = "0.10"
log = "0.4"
wgpu = "0.19"
wgpu = "0.19.3"
pollster = "0.3"
[target.'cfg(target_arch = "wasm32")'.dependencies]

@ -175,14 +175,14 @@ pub async fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
//window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -233,14 +233,14 @@ pub async fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -311,14 +311,14 @@ pub async fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -357,14 +357,14 @@ pub async fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -566,14 +566,14 @@ pub async fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -664,14 +664,14 @@ pub async fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -691,14 +691,14 @@ pub async fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -606,14 +606,14 @@ pub async fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -743,13 +743,13 @@ pub async fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
if let Some(dst) = doc.get_element_by_id("wasm-example") {
dst.append_child(&canvas).ok()?;
} else {

@ -794,14 +794,14 @@ pub async fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -697,14 +697,14 @@ pub async fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -827,14 +827,14 @@ pub async fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -747,14 +747,14 @@ pub async fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -743,14 +743,14 @@ pub async fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -16,7 +16,7 @@ bytemuck = { version = "1.12", features = [ "derive" ] }
cgmath = "0.18"
pollster = "0.3"
wgpu = { version = "0.19", features = ["spirv"]}
wgpu_glyph = { version = "0.21", git = "https://github.com/hecrj/wgpu_glyph.git" }
wgpu_glyph = { version = "0.22", git = "https://github.com/hecrj/wgpu_glyph.git" }
rand = "0.8"
rodio = { version = "0.16", default-features = false, features = ["wav"] }
log = "0.4"
@ -28,8 +28,8 @@ console_log = "1.0"
getrandom = { version = "0.2", features = ["js"] }
rodio = { version = "0.16", default-features = false, features = ["wasm-bindgen", "wav"] }
wasm-bindgen-futures = "0.4.20"
wasm-bindgen = "=0.2.90"
web-sys = { version = "0.3.53", features = [
wasm-bindgen = "0.2"
web-sys = { version = "0.3", features = [
"Document",
"Window",
"Element",

@ -1,4 +1,4 @@
use winit::event::{ElementState, VirtualKeyCode};
use winit::{event::ElementState, keyboard::KeyCode};
#[derive(Debug, Default)]
pub struct Input {
@ -14,26 +14,26 @@ impl Input {
Default::default()
}
pub fn update(&mut self, key: VirtualKeyCode, state: ElementState) -> bool {
pub fn update(&mut self, key: KeyCode, state: ElementState) -> bool {
let pressed = state == ElementState::Pressed;
match key {
VirtualKeyCode::Up => {
KeyCode::ArrowUp => {
self.p2_up_pressed = pressed;
true
}
VirtualKeyCode::Down => {
KeyCode::ArrowDown => {
self.p2_down_pressed = pressed;
true
}
VirtualKeyCode::W => {
KeyCode::KeyW => {
self.p1_up_pressed = pressed;
true
}
VirtualKeyCode::S => {
KeyCode::KeyS => {
self.p1_down_pressed = pressed;
true
}
VirtualKeyCode::Return => {
KeyCode::Enter => {
self.enter_pressed = pressed;
true
}

@ -13,7 +13,8 @@ use wasm_bindgen::prelude::*;
use winit::dpi::PhysicalSize;
use winit::event::*;
use winit::event_loop::{ControlFlow, EventLoop};
use winit::event_loop::{EventLoop, EventLoopWindowTarget};
use winit::keyboard::{KeyCode, PhysicalKey};
use winit::window::{Fullscreen, WindowBuilder};
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))]
@ -40,10 +41,6 @@ pub fn start() {
.build(&event_loop)
.unwrap();
if window.fullscreen().is_none() {
window.set_inner_size(PhysicalSize::new(512, 512));
}
window.set_cursor_visible(false);
#[cfg(target_arch = "wasm32")]
@ -53,7 +50,7 @@ pub fn start() {
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
// Request fullscreen, if denied, continue as normal
@ -159,13 +156,9 @@ pub fn start() {
log::info!("Event Loop...");
let window = &window;
let mut last_time = instant::Instant::now();
event_loop.run(move |event, control_flow| {
*control_flow = if state.game_state == state::GameState::Quiting {
ControlFlow::Exit
} else {
ControlFlow::Poll
};
match event {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
@ -176,10 +169,10 @@ pub fn start() {
Event::WindowEvent {
event:
WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state: element_state,
virtual_keycode: Some(key),
physical_key: PhysicalKey::Code(key),
..
},
..
@ -201,10 +194,13 @@ pub fn start() {
render.resize(size);
events.push(state::Event::Resize(size.width as f32, size.height as f32));
}
Event::RedrawEventsCleared => {
Event::WindowEvent {
event: WindowEvent::RedrawRequested,
..
} => {
let dt = last_time.elapsed();
last_time = instant::Instant::now();
window.request_redraw();
}
Event::RedrawRequested(window_id) if window_id == window.id() => {
for event in &events {
match event {
state::Event::FocusChanged | state::Event::ButtonPressed => {
@ -226,24 +222,24 @@ pub fn start() {
}
events.clear();
visiblity_system.update_state(&input, &mut state, &mut events);
visiblity_system.update_state(&input, dt, &mut state, &mut events);
match state.game_state {
state::GameState::MainMenu => {
menu_system.update_state(&input, &mut state, &mut events);
menu_system.update_state(&input, dt, &mut state, &mut events);
if state.game_state == state::GameState::Serving {
serving_system.start(&mut state);
}
}
state::GameState::Serving => {
serving_system.update_state(&input, &mut state, &mut events);
play_system.update_state(&input, &mut state, &mut events);
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::Playing => {
ball_system.update_state(&input, &mut state, &mut events);
play_system.update_state(&input, &mut state, &mut events);
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 {
@ -251,12 +247,14 @@ pub fn start() {
}
}
state::GameState::GameOver => {
game_over_system.update_state(&input, &mut state, &mut events);
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 => {}
state::GameState::Quiting => {
control_flow.exit();
}
}
render.render_state(&state);
@ -266,17 +264,17 @@ pub fn start() {
}
_ => {}
}
});
}).unwrap();
}
fn process_input(
element_state: ElementState,
keycode: VirtualKeyCode,
control_flow: &mut ControlFlow,
keycode: KeyCode,
control_flow: &EventLoopWindowTarget<()>,
) {
match (keycode, element_state) {
(VirtualKeyCode::Escape, ElementState::Pressed) => {
*control_flow = ControlFlow::Exit;
(KeyCode::Escape, ElementState::Pressed) => {
control_flow.exit()
}
_ => {}
}

@ -12,8 +12,8 @@ use crate::state;
const FONT_BYTES: &[u8] = include_bytes!("../../res/fonts/PressStart2P-Regular.ttf");
pub struct Render {
surface: wgpu::Surface,
pub struct Render<'a> {
surface: wgpu::Surface<'a>,
config: wgpu::SurfaceConfiguration,
#[allow(dead_code)]
adapter: wgpu::Adapter,
@ -26,7 +26,7 @@ pub struct Render {
staging_belt: wgpu::util::StagingBelt,
}
impl Render {
impl<'a> Render<'a> {
pub fn width(&self) -> f32 {
self.config.width as f32
}
@ -36,7 +36,7 @@ impl Render {
self.config.height as f32
}
pub async fn new(window: &Window, size: PhysicalSize<u32>) -> Self {
pub async fn new(window: &'a Window, size: PhysicalSize<u32>) -> Render<'a> {
log::warn!("size: {:?}", size);
// The instance is a handle to our GPU
// BackendBit::PRIMARY => Vulkan + Metal + DX12 + Browser WebGPU

@ -9,6 +9,7 @@ pub trait System {
fn update_state(
&self,
input: &input::Input,
dt: instant::Duration,
state: &mut state::State,
events: &mut Vec<state::Event>,
);
@ -19,6 +20,7 @@ impl System for VisibilitySystem {
fn update_state(
&self,
_input: &input::Input,
_dt: instant::Duration,
state: &mut state::State,
_events: &mut Vec<state::Event>,
) {
@ -60,6 +62,7 @@ impl System for MenuSystem {
fn update_state(
&self,
input: &input::Input,
_dt: instant::Duration,
state: &mut state::State,
events: &mut Vec<state::Event>,
) {
@ -92,21 +95,23 @@ impl System for PlaySystem {
fn update_state(
&self,
input: &input::Input,
dt: instant::Duration,
state: &mut state::State,
_events: &mut Vec<state::Event>,
) {
let dt = dt.as_secs_f32();
// move the players
if input.p1_up_pressed {
state.player1.position.y += util::PLAYER_SPEED;
state.player1.position.y += util::PLAYER_SPEED * dt;
}
if input.p1_down_pressed {
state.player1.position.y -= util::PLAYER_SPEED;
state.player1.position.y -= util::PLAYER_SPEED * dt;
}
if input.p2_up_pressed {
state.player2.position.y += util::PLAYER_SPEED;
state.player2.position.y += util::PLAYER_SPEED * dt;
}
if input.p2_down_pressed {
state.player2.position.y -= util::PLAYER_SPEED;
state.player2.position.y -= util::PLAYER_SPEED * dt;
}
// normalize players
@ -134,22 +139,25 @@ impl System for BallSystem {
fn update_state(
&self,
_input: &input::Input,
dt: instant::Duration,
state: &mut state::State,
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));
state.ball.position.x -= state.ball.velocity.x - state.player1.size.x;
state.ball.position.x -= state.ball.velocity.x * dt - state.player1.size.x;
state.ball.velocity = util::calc_ball_velocity(&state.ball, &state.player1);
} else if state.player2.contains(&state.ball) {
events.push(state::Event::BallBounce(state.ball.position));
state.ball.position.x -= state.ball.velocity.x + state.player2.size.x;
state.ball.position.x -= state.ball.velocity.x * dt + state.player2.size.x;
state.ball.velocity.x *= -state.player2.size.y;
state.ball.velocity = util::calc_ball_velocity(&state.ball, &state.player2);
}
state.ball.position += state.ball.velocity;
state.ball.position += state.ball.velocity * dt;
if state.ball.position.y > 1.0 {
events.push(state::Event::BallBounce(state.ball.position));
state.ball.position.y = 1.0;
@ -199,12 +207,11 @@ impl System for ServingSystem {
fn update_state(
&self,
_input: &input::Input,
_dt: instant::Duration,
state: &mut state::State,
_events: &mut Vec<state::Event>,
) {
let current_time = instant::Instant::now();
let delta_time = current_time - self.last_time;
if delta_time.as_secs_f32() > 2.0 {
if self.last_time.elapsed().as_secs_f32() > 2.0 {
log::info!("Serving...");
state.game_state = state::GameState::Playing;
}
@ -242,12 +249,11 @@ impl System for GameOverSystem {
fn update_state(
&self,
_input: &input::Input,
_dt: instant::Duration,
state: &mut state::State,
_events: &mut Vec<state::Event>,
) {
let current_time = instant::Instant::now();
let delta_time = current_time - self.last_time;
if delta_time.as_secs_f32() > 1.0 {
if self.last_time.elapsed().as_secs_f32() > 1.0 {
state.game_state = state::GameState::MainMenu;
}
}

@ -2,8 +2,8 @@
use crate::state;
pub const PLAYER_SPEED: f32 = 0.05;
pub const BALL_SPEED: f32 = 0.025;
pub const PLAYER_SPEED: f32 = 1.5;
pub const BALL_SPEED: f32 = 1.0;
const BOUNCE_ANGLE: f32 = std::f32::consts::FRAC_PI_2;

@ -704,14 +704,14 @@ pub async fn run() {
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -12,4 +12,4 @@ env_logger = "0.10"
rayon = "1"
serde = { version = "1", features = ["derive"]}
serde_json = "1"
wasm-bindgen-cli-support = "0.2.86"
wasm-bindgen-cli-support = "0.2.90"

@ -1,5 +1,6 @@
use std::{path::PathBuf, process::Command};
use std::{path::PathBuf, process::{Command, ExitStatus}};
use anyhow::bail;
use rayon::prelude::{IntoParallelRefIterator, ParallelIterator};
use wasm_bindgen_cli_support::Bindgen;
@ -37,7 +38,11 @@ fn main() -> anyhow::Result<()> {
for target in &targets {
command.arg("-p").arg(&target.package);
}
command.spawn()?.wait()?;
let status = command.spawn()?.wait()?;
if !status.success() {
bail!("Failed to compile WASM with code ({status})");
}
let errors = targets
.par_iter()

@ -1,9 +1,11 @@
# Dependencies and the window
## Boring, I know
Some of you reading this are very experienced with opening up windows in Rust and probably have your favorite windowing library, but this guide is designed for everybody, so it's something that we need to cover. Luckily, you don't need to read this if you know what you're doing. One thing that you do need to know is that whatever windowing solution you use needs to support the [raw-window-handle](https://github.com/rust-windowing/raw-window-handle) crate.
## What crates are we using?
For the beginner stuff, we're going to keep things very simple. We'll add things as we go, but I've listed the relevant `Cargo.toml` bits below.
```toml
@ -11,29 +13,34 @@ For the beginner stuff, we're going to keep things very simple. We'll add things
winit = { version = "0.29", features = ["rwh_05"] }
env_logger = "0.10"
log = "0.4"
wgpu = "0.19"
wgpu = "0.19.3"
```
## Using Rust's new resolver
As of version 0.10, wgpu requires Cargo's [newest feature resolver](https://doc.rust-lang.org/cargo/reference/resolver.html#feature-resolver-version-2), which is the default in the 2021 edition (any new project started with Rust version 1.56.0 or newer). However, if you are still using the 2018 edition, you must include `resolver = "2"` in either the `[package]` section of `Cargo.toml` if you are working on a single crate or the `[workspace]` section of the root `Cargo.toml` in a workspace.
## env_logger
It is very important to enable logging via `env_logger::init();`.
When wgpu hits any error, it panics with a generic message, while logging the real error via the log crate.
This means if you don't include `env_logger::init()`, wgpu will fail silently, leaving you very confused!
(This has been done in the code below)
## Create a new project
run ```cargo new project_name``` where project_name is the name of the project.
(In the example below, I have used 'tutorial1_window')
## The code
There's not much going on here yet, so I'm just going to post the code in full. Just paste this into your `lib.rs` or equivalent.
```rust
use winit::{
event::*,
event_loop::{ControlFlow, EventLoop},
event_loop::EventLoop,
keyboard::{KeyCode, PhysicalKey},
window::WindowBuilder,
};
@ -49,10 +56,10 @@ pub fn run() {
} if window_id == window.id() => match event {
WindowEvent::CloseRequested
| WindowEvent::KeyboardInput {
input:
KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape),
physical_key: PhysicalKey::Code(KeyCode::Escape),
..
},
..
@ -174,14 +181,14 @@ Next, after we create our event loop and window, we need to add a canvas to the
// Winit prevents sizing with CSS, so we have to set
// the size manually when on web.
use winit::dpi::PhysicalSize;
window.set_inner_size(PhysicalSize::new(450, 400));
window.request_inner_size(PhysicalSize::new(450, 400)).unwrap();
use winit::platform::web::WindowExtWebSys;
web_sys::window()
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
Some(())
})

@ -281,8 +281,8 @@ console_log = "1.0"
getrandom = { version = "0.2", features = ["js"] }
rodio = { version = "0.15", default-features = false, features = ["wasm-bindgen", "wav"] }
wasm-bindgen-futures = "0.4.20"
wasm-bindgen = "=0.2.90"
web-sys = { version = "0.3.53", features = [
wasm-bindgen = "0.2"
web-sys = { version = "0.3", features = [
"Document",
"Window",
"Element",
@ -366,7 +366,7 @@ We then have to do some web-specific stuff if we are on that platform.
.and_then(|win| win.document())
.and_then(|doc| {
let dst = doc.get_element_by_id("wasm-example")?;
let canvas = web_sys::Element::from(window.canvas());
let canvas = web_sys::Element::from(window.canvas()?);
dst.append_child(&canvas).ok()?;
// Request fullscreen, if denied, continue as normal

Loading…
Cancel
Save