tutorials 1-9 now work with wasm

web2
Ben Hansen 2 years ago
parent 82d50cba6c
commit 6324e485f1

24
Cargo.lock generated

@ -2843,11 +2843,9 @@ name = "tutorial1-window"
version = "0.1.0"
dependencies = [
"cfg-if 1.0.0",
"cgmath",
"console_error_panic_hook",
"console_log",
"env_logger",
"image 0.23.14",
"log",
"pollster",
"wasm-bindgen",
@ -2934,14 +2932,13 @@ name = "tutorial2-surface"
version = "0.1.0"
dependencies = [
"cfg-if 1.0.0",
"cgmath",
"console_error_panic_hook",
"console_log",
"env_logger",
"image 0.23.14",
"log",
"pollster",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"wgpu",
"winit",
@ -2953,16 +2950,15 @@ version = "0.1.0"
dependencies = [
"anyhow",
"cfg-if 1.0.0",
"cgmath",
"console_error_panic_hook",
"console_log",
"env_logger",
"fs_extra",
"glob",
"image 0.23.14",
"log",
"pollster",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"wgpu",
"winit",
@ -2975,16 +2971,15 @@ dependencies = [
"anyhow",
"bytemuck",
"cfg-if 1.0.0",
"cgmath",
"console_error_panic_hook",
"console_log",
"env_logger",
"fs_extra",
"glob",
"image 0.23.14",
"log",
"pollster",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"wgpu",
"winit",
@ -2997,16 +2992,16 @@ dependencies = [
"anyhow",
"bytemuck",
"cfg-if 1.0.0",
"cgmath",
"console_error_panic_hook",
"console_log",
"env_logger",
"fs_extra",
"glob",
"image 0.23.14",
"image 0.24.0",
"log",
"pollster",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"wgpu",
"winit",
@ -3025,10 +3020,11 @@ dependencies = [
"env_logger",
"fs_extra",
"glob",
"image 0.23.14",
"image 0.24.0",
"log",
"pollster",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"wgpu",
"winit",
@ -3047,10 +3043,11 @@ dependencies = [
"env_logger",
"fs_extra",
"glob",
"image 0.23.14",
"image 0.24.0",
"log",
"pollster",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"wgpu",
"winit",
@ -3069,10 +3066,11 @@ dependencies = [
"env_logger",
"fs_extra",
"glob",
"image 0.23.14",
"image 0.24.0",
"log",
"pollster",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"wgpu",
"winit",

@ -1,10 +1,12 @@
# wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/pong code/showcase/pong
# wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial1_window code/beginner/tutorial1-window
# wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial2_surface code/beginner/tutorial2-surface
# wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial3_pipeline code/beginner/tutorial3-pipeline
# wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial4_buffer code/beginner/tutorial4-buffer
# wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial5_textures code/beginner/tutorial5-textures
# wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial6_uniforms code/beginner/tutorial6-uniforms
# wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial7_instancing code/beginner/tutorial7-instancing
# wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial8_depth code/beginner/tutorial8-depth
(trap 'kill 0' SIGINT;
wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/pong code/showcase/pong &
wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial1_window code/beginner/tutorial1-window &
wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial2_surface code/beginner/tutorial2-surface &
wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial3_pipeline code/beginner/tutorial3-pipeline &
wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial4_buffer code/beginner/tutorial4-buffer &
wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial5_textures code/beginner/tutorial5-textures &
wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial6_uniforms code/beginner/tutorial6-uniforms &
wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial7_instancing code/beginner/tutorial7-instancing &
wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial8_depth code/beginner/tutorial8-depth &
wasm-pack build --out-dir ../../../docs/.vuepress/components/wasm/tutorial9_models code/beginner/tutorial9-models
)

@ -13,9 +13,7 @@ path = "src/main.rs"
[dependencies]
cfg-if = "1"
image = "0.23"
winit = "0.26"
cgmath = "0.18"
env_logger = "0.9"
log = "0.4"
wgpu = "0.12"

@ -8,7 +8,7 @@ use winit::{
use wasm_bindgen::prelude::*;
#[cfg_attr(target_arch="wasm32", wasm_bindgen(start))]
pub fn run() {
pub async fn run() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
std::panic::set_hook(Box::new(console_error_panic_hook::hook));

@ -9,9 +9,7 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
cfg-if = "1"
image = "0.23"
winit = "0.26"
cgmath = "0.18"
env_logger = "0.9"
log = "0.4"
wgpu = "0.12"
@ -21,8 +19,9 @@ pollster = "0.2"
console_error_panic_hook = "0.1.6"
console_log = "0.2.0"
wgpu = { version = "0.12", features = ["webgl"]}
wasm-bindgen = "0.2.76"
web-sys = { version = "0.3.53", features = [
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"
web-sys = { version = "0.3", features = [
"Document",
"Window",
"Element",

@ -138,12 +138,16 @@ impl State {
}
fn main() {
pollster::block_on(run());
}
async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
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 = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {

@ -127,7 +127,7 @@ impl State {
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))]
pub fn run() {
pub async fn run() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
@ -160,7 +160,7 @@ pub fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state: State = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {

@ -1,5 +1,5 @@
use tutorial2_surface::run;
fn main() {
run()
pollster::block_on(run());
}

@ -9,9 +9,7 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
cfg-if = "1"
image = "0.23"
winit = "0.26"
cgmath = "0.18"
env_logger = "0.9"
log = "0.4"
wgpu = "0.12"
@ -21,8 +19,9 @@ pollster = "0.2"
console_error_panic_hook = "0.1.6"
console_log = "0.2.0"
wgpu = { version = "0.12", features = ["webgl"]}
wasm-bindgen = "0.2.76"
web-sys = { version = "0.3.53", features = [
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"
web-sys = { version = "0.3", features = [
"Document",
"Window",
"Element",

@ -249,12 +249,16 @@ impl State {
}
fn main() {
pollster::block_on(run());
}
async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
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 = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {

@ -187,7 +187,7 @@ impl State {
}
#[cfg_attr(target_arch="wasm32", wasm_bindgen(start))]
pub fn run() {
pub async fn run() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
@ -220,7 +220,7 @@ pub fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {

@ -1,5 +1,5 @@
use tutorial3_pipeline::run;
fn main() {
run();
pollster::block_on(run());
}

@ -10,8 +10,6 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
cfg-if = "1"
image = "0.23"
cgmath = "0.18"
winit = "0.26"
wgpu = "0.12"
env_logger = "0.9"
@ -21,11 +19,12 @@ pollster = "0.2"
bytemuck = { version = "1.4", features = [ "derive" ] }
[target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook = "0.1.6"
console_log = "0.2.0"
console_error_panic_hook = "0.1"
console_log = "0.2"
wgpu = { version = "0.12", features = ["webgl"]}
wasm-bindgen = "0.2.76"
web-sys = { version = "0.3.53", features = [
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"
web-sys = { version = "0.3", features = [
"Document",
"Window",
"Element",

@ -326,12 +326,16 @@ impl State {
}
fn main() {
pollster::block_on(run());
}
async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
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 = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {

@ -261,7 +261,7 @@ impl State {
}
#[cfg_attr(target_arch="wasm32", wasm_bindgen(start))]
pub fn run() {
pub async fn run() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
@ -294,7 +294,7 @@ pub fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {

@ -1,5 +1,5 @@
use tutorial4_buffer::run;
fn main() {
run();
pollster::block_on(run());
}

@ -11,20 +11,24 @@ crate-type = ["cdylib", "rlib"]
cfg-if = "1"
anyhow = "1.0"
bytemuck = { version = "1.4", features = [ "derive" ] }
cgmath = "0.18"
env_logger = "0.9"
log = "0.4"
pollster = "0.2"
image = "0.23"
wgpu = "0.12"
winit = "0.26"
[dependencies.image]
version = "0.24"
default-features = false
features = ["png", "jpeg"]
[target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook = "0.1.6"
console_log = "0.2.0"
console_error_panic_hook = "0.1"
console_log = "0.2"
wgpu = { version = "0.12", features = ["webgl"]}
wasm-bindgen = "0.2.76"
web-sys = { version = "0.3.53", features = [
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"
web-sys = { version = "0.3", features = [
"Document",
"Window",
"Element",

@ -353,12 +353,16 @@ impl State {
}
fn main() {
pollster::block_on(run());
}
async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
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 = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {

@ -311,7 +311,7 @@ impl State {
}
#[cfg_attr(target_arch="wasm32", wasm_bindgen(start))]
pub fn run() {
pub async fn run() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
@ -344,7 +344,7 @@ pub fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {

@ -1,5 +1,5 @@
use tutorial5_textures::run;
fn main() {
run();
pollster::block_on(run());
}

@ -15,16 +15,21 @@ cgmath = "0.18"
env_logger = "0.9"
log = "0.4"
pollster = "0.2"
image = "0.23"
wgpu = "0.12"
winit = "0.26"
[dependencies.image]
version = "0.24"
default-features = false
features = ["png", "jpeg"]
[target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook = "0.1.6"
console_log = "0.2.0"
console_error_panic_hook = "0.1"
console_log = "0.2"
wgpu = { version = "0.12", features = ["webgl"]}
wasm-bindgen = "0.2.76"
web-sys = { version = "0.3.53", features = [
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"
web-sys = { version = "0.3", features = [
"Document",
"Window",
"Element",

@ -524,12 +524,16 @@ impl State {
}
fn main() {
pollster::block_on(run());
}
async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
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 = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {

@ -520,7 +520,7 @@ impl State {
}
#[cfg_attr(target_arch="wasm32", wasm_bindgen(start))]
pub fn run() {
pub async fn run() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
@ -553,7 +553,7 @@ pub fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {

@ -1,5 +1,5 @@
use tutorial6_uniforms::run;
fn main() {
run();
pollster::block_on(run());
}

@ -15,16 +15,21 @@ cgmath = "0.18"
env_logger = "0.9"
log = "0.4"
pollster = "0.2"
image = "0.23"
wgpu = "0.12"
winit = "0.26"
[dependencies.image]
version = "0.24"
default-features = false
features = ["png", "jpeg"]
[target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook = "0.1.6"
console_log = "0.2.0"
console_error_panic_hook = "0.1"
console_log = "0.2"
wgpu = { version = "0.12", features = ["webgl"]}
wasm-bindgen = "0.2.76"
web-sys = { version = "0.3.53", features = [
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"
web-sys = { version = "0.3", features = [
"Document",
"Window",
"Element",

@ -653,12 +653,16 @@ impl State {
}
fn main() {
pollster::block_on(run());
}
async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
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 = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {

@ -618,7 +618,7 @@ impl State {
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))]
pub fn run() {
pub async fn run() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
@ -651,7 +651,7 @@ pub fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {

@ -1,5 +1,5 @@
use tutorial7_instancing::run;
fn main() {
run();
pollster::block_on(run());
}

@ -14,17 +14,22 @@ bytemuck = { version = "1.4", features = [ "derive" ] }
cgmath = "0.18"
env_logger = "0.9"
pollster = "0.2"
image = "0.23"
log = "0.4"
wgpu = "0.12"
winit = "0.26"
[dependencies.image]
version = "0.24"
default-features = false
features = ["png", "jpeg"]
[target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook = "0.1.6"
console_log = "0.2.0"
console_error_panic_hook = "0.1"
console_log = "0.2"
wgpu = { version = "0.12", features = ["webgl"]}
wasm-bindgen = "0.2.76"
web-sys = { version = "0.3.53", features = [
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"
web-sys = { version = "0.3", features = [
"Document",
"Window",
"Element",

@ -819,12 +819,16 @@ impl State {
}
fn main() {
pollster::block_on(run());
}
async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
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 = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {

@ -645,7 +645,7 @@ impl State {
}
#[cfg_attr(target_arch="wasm32", wasm_bindgen(start))]
pub fn run() {
pub async fn run() {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
std::panic::set_hook(Box::new(console_error_panic_hook::hook));
@ -678,7 +678,7 @@ pub fn run() {
}
// State::new uses async code, so we're going to wait for it to finish
let mut state = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
match event {

@ -1,5 +1,5 @@
use tutorial8_depth::run;
fn main() {
run();
pollster::block_on(run());
}

@ -693,7 +693,7 @@ impl State {
}
}
pub fn run() {
pub async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
let title = env!("CARGO_PKG_NAME");
@ -701,7 +701,7 @@ pub fn run() {
.with_title(title)
.build(&event_loop)
.unwrap();
let mut state = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
match event {

@ -1,5 +1,5 @@
use tutorial10_lighting::run;
fn main() {
run();
pollster::block_on(run());
}

@ -742,7 +742,7 @@ impl State {
}
}
pub fn run() {
pub async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
let title = env!("CARGO_PKG_NAME");
@ -750,7 +750,7 @@ pub fn run() {
.with_title(title)
.build(&event_loop)
.unwrap();
let mut state = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
match event {

@ -1,5 +1,5 @@
use tutorial11_normals::run;
fn main() {
run();
pollster::block_on(run());
}

@ -649,7 +649,7 @@ impl State {
}
}
pub fn run() {
pub async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
let title = env!("CARGO_PKG_NAME");
@ -657,7 +657,7 @@ pub fn run() {
.with_title(title)
.build(&event_loop)
.unwrap();
let mut state = pollster::block_on(State::new(&window)); // 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;

@ -1,5 +1,5 @@
use tutorial12_camera::run;
fn main() {
run();
pollster::block_on(run());
}

@ -644,7 +644,7 @@ impl State {
}
}
pub fn run() {
pub async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
let title = env!("CARGO_PKG_NAME");
@ -652,7 +652,7 @@ pub fn run() {
.with_title(title)
.build(&event_loop)
.unwrap();
let mut state = pollster::block_on(State::new(&window)); // 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;

@ -1,5 +1,5 @@
use tutorial13_threading::run;
fn main() {
run();
pollster::block_on(run());
}

@ -603,6 +603,10 @@ impl State {
}
fn main() {
pollster::block_on(run());
}
async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
let title = env!("CARGO_PKG_NAME");
@ -610,7 +614,7 @@ fn main() {
.with_title(title)
.build(&event_loop)
.unwrap();
let mut state = pollster::block_on(State::new(&window)); // 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;

@ -8,13 +8,10 @@ For the beginner stuff, we're going to keep things very simple, we'll add things
```toml
[dependencies]
image = "0.23"
winit = "0.26"
cgmath = "0.18"
env_logger = "0.9"
log = "0.4"
wgpu = "0.12"
pollster = "0.2"
```
## Using Rust's new resolver
@ -35,7 +32,7 @@ use winit::{
window::WindowBuilder,
};
pub fn run() {
pub async fn run() {
env_logger::init();
let event_loop = EventLoop::new();
let window = WindowBuilder::new().build(&event_loop).unwrap();
@ -69,7 +66,7 @@ All this does is create a window, and keep it open until the user closes it, or
use tutorial1_window::run;
fn main() {
run();
pollster::block_on(run());
}
```
@ -141,7 +138,7 @@ Next we need to tell wasm-bindgen to run our `run()` function when the WASM is l
```rust
#[cfg_attr(target_arch="wasm32", wasm_bindgen(start))]
pub fn run() {
pub async fn run() {
// snipped...
}
```

@ -175,19 +175,64 @@ Now that we've configured our surface properly we can add these new fields at th
}
```
We'll want to call this in our main method before we enter the event loop.
Since our `State::new()` method is async we need to change run to be async as well so that we can await it.
```rust
// State::new uses async code, so we're going to wait for it to finish
let mut state = pollster::block_on(State::new(&window));
pub async fn run() {
// Window setup...
let mut state = State::new(&window).await;
// Event loop...
}
```
<div class="note">
Now that `run()` is async, `main()` will need some way to await the future. We could use a crate like [tokio](https://docs.rs/tokio), or [async-std](https://docs.rs/async-std), but I'm going to go with the much more lightweight [pollster](https://docs.rs/pollster). Add the following to your `Cargo.toml`:
You can use heavier libraries like [async_std](https://docs.rs/async_std) and [tokio](https://docs.rs/tokio) to make main async, so you can await futures. I've elected not to use these crates as this tutorial is not about writing an async application, and the futures created by wgpu do not require [special executor support](https://rust-lang.github.io/async-book/08_ecosystem/00_chapter.html#determining-ecosystem-compatibility). We just need some way to interact with wgpu's async functions, and the [pollster crate](https://docs.rs/pollster) is enough for that.
```toml
[dependencies]
# other deps...
pollster = "0.2"
```
We then use the `block_on` function provided by pollster to await our future:
```rust
fn main() {
pollster::block_on(run());
}
```
<div class="warning">
Don't use `block_on` inside of an async function if you plan to support WASM. Futures have to be run using the browsers executor. If you try to bring your own you code will crash when you encounter a future that doesn't execute immediately.
</div>
If we try to build WASM now it will fail because `wasm-bindgen` doesn't support using async functions as `start` methods. You could switch to calling `run` manually in javascript, but for simplicity we'll add the [wasm-bindgen-futures](https://docs.rs/wasm-bindgen-futures) crate to our WASM dependencies as that doesn't require us to change any code. Your dependecies should look something like this:
```toml
[dependencies]
cfg-if = "1"
winit = "0.26"
env_logger = "0.9"
log = "0.4"
wgpu = "0.12"
pollster = "0.2"
[target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook = "0.1.6"
console_log = "0.2.0"
wgpu = { version = "0.12", features = ["webgl"]}
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"
web-sys = { version = "0.3", features = [
"Document",
"Window",
"Element",
]}
```
## resize()
If we want to support resizing in our application, we're going to need to reconfigure the `surface` everytime the window's size changes. That's the reason we stored the physical `size` and the `config` used to configure the `surface`. With all of these, the resize method is very simple.

@ -10,7 +10,22 @@ If we want to map an image to our mesh, we first need an image. Let's use this h
![a happy tree](./happy-tree.png)
We'll use the [image crate](https://crates.io/crates/image) to load our tree. We already added to our dependencies in the first section, so all we have to do is use it.
We'll use the [image crate](https://docs.rs/image) to load our tree. Let's add it to our dependencies:
```toml
[dependencies.image]
version = "0.24"
default-features = false
features = ["png", "jpeg"]
```
The jpeg decoder that `image` includes uses [rayon](https://docs.rs/rayon) to speed up the decoding with threads. WASM doesn't support threads currently so we need to disable this so that our code won't crash when we try to load a jpeg on the web.
<div class="note">
Decoding jpegs in WASM isn't very performant. If you want to speed up image loadding in general in WASM you could opt to use the browsers builtin decoders instead of `image` when building with `wasm-bindgen`. This will involve creating an `<img>` tag in Rust to get the image, and then a `<canvas>` to get the pixel data, but I'll leave this as an exercise for the reader.
</div>
In `State`'s `new()` method add the following just after configuring the `surface`:

@ -4,7 +4,13 @@ While all of our previous work has seemed to be in 2d, we've actually been worki
## A perspective camera
This tutorial is more about learning to use wgpu and less about linear algebra, so I'm going to gloss over a lot of the math involved. There's plenty of reading material online if you're interested in what's going on under the hood. The first thing to know is that we need `cgmath = "0.18"` in our `Cargo.toml`.
This tutorial is more about learning to use wgpu and less about linear algebra, so I'm going to gloss over a lot of the math involved. There's plenty of reading material online if you're interested in what's going on under the hood. We're going to use the [cgmath](https://docs.rs/cgmath) to handle all the math for us. Add the following to your `Cargo.toml`.
```toml
[dependencies]
# other deps...
cgmath = "0.18"
```
Now that we have a math library, let's put it to use! Create a `Camera` struct above the `State` struct.

@ -424,7 +424,7 @@ We still need to calculate `dt`. Let's do that in the `main` function.
```rust
fn main() {
// ...
let mut state = pollster::block_on(State::new(&window));
let mut state = State::new(&window).await;
let mut last_render_time = std::time::Instant::now(); // NEW!
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;

@ -1,26 +1,28 @@
#!/bin/bash
cargo run --bin tutorial1-window
cargo run --bin tutorial2-surface
cargo run --bin tutorial2-challenge
cargo run --bin tutorial3-pipeline
cargo run --bin tutorial3-challenge
cargo run --bin tutorial4-buffer
cargo run --bin tutorial4-challenge
cargo run --bin tutorial5-textures
cargo run --bin tutorial5-challenge
cargo run --bin tutorial6-uniforms
cargo run --bin tutorial6-challenge
cargo run --bin tutorial7-instancing
cargo run --bin tutorial7-challenge
cargo run --bin tutorial8-depth
cargo run --bin tutorial8-challenge
cargo run --bin tutorial9-models
cargo run --bin tutorial10-lighting
cargo run --bin tutorial11-normals
cargo run --bin tutorial12-camera
cargo run --bin tutorial13-threading
cargo run --bin windowless
cargo run --bin gifs
cargo run --bin compute
(trap 'kill 0' SIGINT;
cargo run --bin tutorial1-window &
cargo run --bin tutorial2-surface &
cargo run --bin tutorial2-challenge &
cargo run --bin tutorial3-pipeline &
cargo run --bin tutorial3-challenge &
cargo run --bin tutorial4-buffer &
cargo run --bin tutorial4-challenge &
cargo run --bin tutorial5-textures &
cargo run --bin tutorial5-challenge &
cargo run --bin tutorial6-uniforms &
cargo run --bin tutorial6-challenge &
cargo run --bin tutorial7-instancing &
cargo run --bin tutorial7-challenge &
cargo run --bin tutorial8-depth &
cargo run --bin tutorial8-challenge &
cargo run --bin tutorial9-models &
cargo run --bin tutorial10-lighting &
cargo run --bin tutorial11-normals &
cargo run --bin tutorial12-camera &
cargo run --bin tutorial13-threading &
cargo run --bin windowless &
cargo run --bin gifs &
cargo run --bin compute &
cargo run --bin pong
)

Loading…
Cancel
Save