Merge pull request #26 from Pointime/0.5

I found that the asynchronous I wrote is inconsistent with the author. . .
This commit is contained in:
sotrh 2020-04-22 15:53:57 -06:00 committed by GitHub
commit 590d44de9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 1556 additions and 785 deletions

364
Cargo.lock generated
View File

@ -5,6 +5,14 @@ name = "adler32"
version = "1.0.4" version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "aho-corasick"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "andrew" name = "andrew"
version = "0.2.1" version = "0.2.1"
@ -62,6 +70,16 @@ name = "atom"
version = "0.3.5" version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "0.1.7" version = "0.1.7"
@ -358,6 +376,15 @@ dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "deflate"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.7.6" version = "0.7.6"
@ -371,6 +398,11 @@ name = "dispatch"
version = "0.1.4" version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "dispatch"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "dlib" name = "dlib"
version = "0.4.1" version = "0.4.1"
@ -389,6 +421,18 @@ name = "either"
version = "1.5.3" version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "env_logger"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "failure" name = "failure"
version = "0.1.6" version = "0.1.6"
@ -858,6 +902,14 @@ dependencies = [
"atom 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "atom 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "humantime"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "image" name = "image"
version = "0.22.4" version = "0.22.4"
@ -874,6 +926,23 @@ dependencies = [
"tiff 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "tiff 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "image"
version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytemuck 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gif 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)",
"jpeg-decoder 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"num-iter 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"num-rational 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"png 0.16.3 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
"tiff 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "inflate" name = "inflate"
version = "0.4.5" version = "0.4.5"
@ -906,10 +975,10 @@ dependencies = [
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.35" version = "0.3.37"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -1037,6 +1106,14 @@ dependencies = [
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "miniz_oxide"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "mio" name = "mio"
version = "0.6.21" version = "0.6.21"
@ -1272,6 +1349,17 @@ dependencies = [
"inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "png"
version = "0.16.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"deflate 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
"inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.6" version = "0.2.6"
@ -1303,6 +1391,11 @@ dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "quote" name = "quote"
version = "0.6.13" version = "0.6.13"
@ -1508,6 +1601,22 @@ name = "redox_syscall"
version = "0.1.56" version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "regex"
version = "1.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.6.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "relevant" name = "relevant"
version = "0.4.2" version = "0.4.2"
@ -1653,7 +1762,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "smithay-client-toolkit" name = "smithay-client-toolkit"
version = "0.6.4" version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"andrew 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "andrew 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1672,8 +1781,8 @@ version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
"js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -1682,8 +1791,8 @@ version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)",
"js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -1757,6 +1866,22 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "termcolor"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "thread_local"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "tiff" name = "tiff"
version = "0.3.1" version = "0.3.1"
@ -1768,11 +1893,26 @@ dependencies = [
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "tiff"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "tobj" name = "tobj"
version = "0.1.11" version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "tobj"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "tutorial1-window" name = "tutorial1-window"
version = "0.1.0" version = "0.1.0"
@ -1789,13 +1929,15 @@ dependencies = [
name = "tutorial10-lighting" name = "tutorial10-lighting"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bytemuck 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"glsl-to-spirv 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "glsl-to-spirv 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.22.4 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.23.4 (registry+https://github.com/rust-lang/crates.io-index)",
"tobj 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tobj 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wgpu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "wgpu 0.5.0 (git+https://github.com/gfx-rs/wgpu-rs.git)",
"winit 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", "winit 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -1877,25 +2019,30 @@ dependencies = [
name = "tutorial8-depth" name = "tutorial8-depth"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bytemuck 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"glsl-to-spirv 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "glsl-to-spirv 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.22.4 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.23.4 (registry+https://github.com/rust-lang/crates.io-index)",
"wgpu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "tobj 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winit 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", "wgpu 0.5.0 (git+https://github.com/gfx-rs/wgpu-rs.git)",
"winit 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "tutorial9-models" name = "tutorial9-models"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bytemuck 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "cgmath 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"glsl-to-spirv 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "glsl-to-spirv 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.22.4 (registry+https://github.com/rust-lang/crates.io-index)", "image 0.23.4 (registry+https://github.com/rust-lang/crates.io-index)",
"tobj 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tobj 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wgpu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "wgpu 0.5.0 (git+https://github.com/gfx-rs/wgpu-rs.git)",
"winit 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", "winit 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -1940,16 +2087,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.58" version = "0.2.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-macro 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "wasm-bindgen-backend" name = "wasm-bindgen-backend"
version = "0.2.58" version = "0.2.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "bumpalo 3.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1958,33 +2105,44 @@ dependencies = [
"proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"js-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
"web-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.58" version = "0.2.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-macro-support 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.58" version = "0.2.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)", "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-backend 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.58" version = "0.2.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
@ -2042,6 +2200,15 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "web-sys"
version = "0.3.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"js-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "wgpu" name = "wgpu"
version = "0.4.0" version = "0.4.0"
@ -2053,6 +2220,25 @@ dependencies = [
"zerocopy 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "zerocopy 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "wgpu"
version = "0.5.0"
source = "git+https://github.com/gfx-rs/wgpu-rs.git#5f885ed3cc476962d9d7b55bec0b28da7c47a3b2"
dependencies = [
"arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"js-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"raw-window-handle 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
"wasm-bindgen-futures 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"web-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
"wgpu-core 0.5.0 (git+https://github.com/gfx-rs/wgpu?rev=49dbe08f37f8396cff0d6672667a48116ec487f5)",
"wgpu-native 0.5.0 (git+https://github.com/gfx-rs/wgpu?rev=49dbe08f37f8396cff0d6672667a48116ec487f5)",
"wgpu-types 0.5.0 (git+https://github.com/gfx-rs/wgpu?rev=49dbe08f37f8396cff0d6672667a48116ec487f5)",
]
[[package]] [[package]]
name = "wgpu" name = "wgpu"
version = "0.5.0" version = "0.5.0"
@ -2067,6 +2253,31 @@ dependencies = [
"wgpu-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "wgpu-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "wgpu-core"
version = "0.5.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=49dbe08f37f8396cff0d6672667a48116ec487f5#49dbe08f37f8396cff0d6672667a48116ec487f5"
dependencies = [
"arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx-backend-dx11 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx-backend-dx12 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx-backend-empty 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx-backend-metal 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx-backend-vulkan 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx-descriptor 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx-hal 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx-memory 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"peek-poke 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"wgpu-types 0.5.0 (git+https://github.com/gfx-rs/wgpu?rev=49dbe08f37f8396cff0d6672667a48116ec487f5)",
]
[[package]] [[package]]
name = "wgpu-core" name = "wgpu-core"
version = "0.5.3" version = "0.5.3"
@ -2117,6 +2328,21 @@ dependencies = [
"vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "wgpu-native"
version = "0.5.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=49dbe08f37f8396cff0d6672667a48116ec487f5#49dbe08f37f8396cff0d6672667a48116ec487f5"
dependencies = [
"arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"raw-window-handle 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"wgpu-core 0.5.0 (git+https://github.com/gfx-rs/wgpu?rev=49dbe08f37f8396cff0d6672667a48116ec487f5)",
"wgpu-types 0.5.0 (git+https://github.com/gfx-rs/wgpu?rev=49dbe08f37f8396cff0d6672667a48116ec487f5)",
]
[[package]] [[package]]
name = "wgpu-native" name = "wgpu-native"
version = "0.5.0" version = "0.5.0"
@ -2132,6 +2358,15 @@ dependencies = [
"wgpu-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "wgpu-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "wgpu-types"
version = "0.5.0"
source = "git+https://github.com/gfx-rs/wgpu?rev=49dbe08f37f8396cff0d6672667a48116ec487f5#49dbe08f37f8396cff0d6672667a48116ec487f5"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"peek-poke 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "wgpu-types" name = "wgpu-types"
version = "0.5.0" version = "0.5.0"
@ -2212,10 +2447,38 @@ dependencies = [
"parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"raw-window-handle 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "raw-window-handle 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smithay-client-toolkit 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "smithay-client-toolkit 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-client 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)", "wayland-client 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"x11-dl 2.18.4 (registry+https://github.com/rust-lang/crates.io-index)", "x11-dl 2.18.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winit"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"android_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cocoa 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-video-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"dispatch 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"instant 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"raw-window-handle 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smithay-client-toolkit 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-client 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"x11-dl 2.18.5 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -2246,7 +2509,7 @@ dependencies = [
[[package]] [[package]]
name = "x11-dl" name = "x11-dl"
version = "2.18.4" version = "2.18.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2286,6 +2549,7 @@ dependencies = [
[metadata] [metadata]
"checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" "checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
"checksum aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada"
"checksum andrew 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b7f09f89872c2b6b29e319377b1fbe91c6f5947df19a25596e121cf19a7b35e" "checksum andrew 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9b7f09f89872c2b6b29e319377b1fbe91c6f5947df19a25596e121cf19a7b35e"
"checksum android_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407" "checksum android_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407"
"checksum approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" "checksum approx 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3"
@ -2294,6 +2558,7 @@ dependencies = [
"checksum ash 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "003d1fb2eb12eb06d4a03dbe02eea67a9fac910fa97932ab9e3a75b96a1ea5e5" "checksum ash 0.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "003d1fb2eb12eb06d4a03dbe02eea67a9fac910fa97932ab9e3a75b96a1ea5e5"
"checksum ash 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)" = "69daec0742947f33a85931fa3cb0ce5f07929159dcbd1f0cbb5b2912e2978509" "checksum ash 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)" = "69daec0742947f33a85931fa3cb0ce5f07929159dcbd1f0cbb5b2912e2978509"
"checksum atom 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3c86699c3f02778ec07158376991c8f783dd1f2f95c579ffaf0738dc984b2fe2" "checksum atom 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3c86699c3f02778ec07158376991c8f783dd1f2f95c579ffaf0738dc984b2fe2"
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
"checksum backtrace 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e4036b9bf40f3cf16aba72a3d65e8a520fc4bafcdc7079aea8f848c58c5b5536" "checksum backtrace 0.3.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e4036b9bf40f3cf16aba72a3d65e8a520fc4bafcdc7079aea8f848c58c5b5536"
@ -2331,11 +2596,14 @@ dependencies = [
"checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" "checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
"checksum d3d12 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc7ed48e89905e5e146bcc1951cc3facb9e44aea9adf5dc01078cda1bd24b662" "checksum d3d12 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc7ed48e89905e5e146bcc1951cc3facb9e44aea9adf5dc01078cda1bd24b662"
"checksum deflate 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" "checksum deflate 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)" = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4"
"checksum deflate 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e7e5d2a2273fed52a7f947ee55b092c4057025d7a3e04e5ecdbd25d6c3fb1bd7"
"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90" "checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
"checksum dispatch 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e93ca78226c51902d7aa8c12c988338aadd9e85ed9c6be8aaac39192ff3605" "checksum dispatch 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e93ca78226c51902d7aa8c12c988338aadd9e85ed9c6be8aaac39192ff3605"
"checksum dispatch 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
"checksum dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a" "checksum dlib 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "77e51249a9d823a4cb79e3eca6dcd756153e8ed0157b6c04775d04bf1b13b76a"
"checksum downcast-rs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "52ba6eb47c2131e784a38b726eb54c1e1484904f013e576a25354d0124161af6" "checksum downcast-rs 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "52ba6eb47c2131e784a38b726eb54c1e1484904f013e576a25354d0124161af6"
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
"checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
"checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9"
"checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
@ -2376,12 +2644,14 @@ dependencies = [
"checksum glsl-to-spirv 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "28caebc98746d507603a2d3df66dcbe04e41d4febad0320f3eec1ef72b6bbef1" "checksum glsl-to-spirv 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "28caebc98746d507603a2d3df66dcbe04e41d4febad0320f3eec1ef72b6bbef1"
"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772" "checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772"
"checksum hibitset 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "47e7292fd9f7fe89fa35c98048f2d0a69b79ed243604234d18f6f8a1aa6f408d" "checksum hibitset 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "47e7292fd9f7fe89fa35c98048f2d0a69b79ed243604234d18f6f8a1aa6f408d"
"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
"checksum image 0.22.4 (registry+https://github.com/rust-lang/crates.io-index)" = "53cb19c4e35102e5c6fb9ade5e0e236c5588424dc171a849af3141bf0b47768a" "checksum image 0.22.4 (registry+https://github.com/rust-lang/crates.io-index)" = "53cb19c4e35102e5c6fb9ade5e0e236c5588424dc171a849af3141bf0b47768a"
"checksum image 0.23.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9117f4167a8f21fa2bb3f17a652a760acd7572645281c98e3b612a26242c96ee"
"checksum inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff" "checksum inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
"checksum instant 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6c346c299e3fe8ef94dc10c2c0253d858a69aac1245157a3bf4125915d528caf" "checksum instant 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6c346c299e3fe8ef94dc10c2c0253d858a69aac1245157a3bf4125915d528caf"
"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
"checksum jpeg-decoder 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0256f0aec7352539102a9efbcb75543227b7ab1117e0f95450023af730128451" "checksum jpeg-decoder 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "0256f0aec7352539102a9efbcb75543227b7ab1117e0f95450023af730128451"
"checksum js-sys 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "7889c7c36282151f6bf465be4700359318aef36baa951462382eae49e9577cf9" "checksum js-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)" = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
@ -2398,6 +2668,7 @@ dependencies = [
"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" "checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
"checksum metal 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f83c7dcc2038e12f68493fa3de44235df27b2497178e257185b4b5b5d028a1e4" "checksum metal 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f83c7dcc2038e12f68493fa3de44235df27b2497178e257185b4b5b5d028a1e4"
"checksum metal 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e198a0ee42bdbe9ef2c09d0b9426f3b2b47d90d93a4a9b0395c4cea605e92dc0" "checksum metal 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e198a0ee42bdbe9ef2c09d0b9426f3b2b47d90d93a4a9b0395c4cea605e92dc0"
"checksum miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5"
"checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" "checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
"checksum mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" "checksum mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
@ -2422,11 +2693,13 @@ dependencies = [
"checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587"
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
"checksum png 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef859a23054bbfee7811284275ae522f0434a3c8e7f4b74bd4a35ae7e1c4a283" "checksum png 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef859a23054bbfee7811284275ae522f0434a3c8e7f4b74bd4a35ae7e1c4a283"
"checksum png 0.16.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2c68a431ed29933a4eb5709aca9800989758c97759345860fa5db3cfced0b65d"
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
"checksum proc-macro-hack 0.5.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" "checksum proc-macro-hack 0.5.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63"
"checksum proc-macro-nested 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694" "checksum proc-macro-nested 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0319972dcae462681daf4da1adeeaa066e3ebd29c69be96c6abb1259d2ee2bcc" "checksum proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0319972dcae462681daf4da1adeeaa066e3ebd29c69be96c6abb1259d2ee2bcc"
"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
@ -2450,6 +2723,8 @@ dependencies = [
"checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" "checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
"checksum regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692"
"checksum regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
"checksum relevant 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bbc232e13d37f4547f5b9b42a5efc380cabe5dbc1807f8b893580640b2ab0308" "checksum relevant 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bbc232e13d37f4547f5b9b42a5efc380cabe5dbc1807f8b893580640b2ab0308"
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
"checksum rendy-descriptor 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f475bcc0505946e998590f1f0545c52ef4b559174a1b353a7ce6638def8b621e" "checksum rendy-descriptor 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f475bcc0505946e998590f1f0545c52ef4b559174a1b353a7ce6638def8b621e"
@ -2468,7 +2743,7 @@ dependencies = [
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
"checksum smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4" "checksum smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4"
"checksum smithay-client-toolkit 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "93960e8975909fcb14cc755de93af2149d8b8f4eb368315537d40cfd0f324054" "checksum smithay-client-toolkit 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "421c8dc7acf5cb205b88160f8b4cc2c5cfabe210e43b2f80f009f4c1ef910f1d"
"checksum spirv_cross 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fbbe441b3ac8ec0ae6a4f05234239bd372a241ce15793eef694e8b24afc267bb" "checksum spirv_cross 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fbbe441b3ac8ec0ae6a4f05234239bd372a241ce15793eef694e8b24afc267bb"
"checksum spirv_cross 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "946216f8793f7199e3ea5b995ee8dc20a0ace1fcf46293a0ef4c17e1d046dbde" "checksum spirv_cross 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "946216f8793f7199e3ea5b995ee8dc20a0ace1fcf46293a0ef4c17e1d046dbde"
"checksum stb_truetype 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f77b6b07e862c66a9f3e62a07588fee67cd90a9135a2b942409f195507b4fb51" "checksum stb_truetype 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f77b6b07e862c66a9f3e62a07588fee67cd90a9135a2b942409f195507b4fb51"
@ -2478,8 +2753,12 @@ dependencies = [
"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
"checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
"checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
"checksum tiff 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b7c2cfc4742bd8a32f2e614339dd8ce30dbcf676bb262bd63a2327bc5df57d" "checksum tiff 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7b7c2cfc4742bd8a32f2e614339dd8ce30dbcf676bb262bd63a2327bc5df57d"
"checksum tiff 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "002351e428db1eb1d8656d4ca61947c3519ac3191e1c804d4600cd32093b77ad"
"checksum tobj 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "1ed6f4ec3b7c466b7a72471179e55e2b6a7452b53691b6115185132fc2e06b1c" "checksum tobj 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "1ed6f4ec3b7c466b7a72471179e55e2b6a7452b53691b6115185132fc2e06b1c"
"checksum tobj 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2b9d0bafde95a2f8f50dd3c10bc127b462efa8c3c0b60dfa276b7e032100e21d"
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" "checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
@ -2487,21 +2766,27 @@ dependencies = [
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" "checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" "checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
"checksum wasm-bindgen 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "5205e9afdf42282b192e2310a5b463a6d1c1d774e30dc3c791ac37ab42d2616c" "checksum wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f"
"checksum wasm-bindgen-backend 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "11cdb95816290b525b32587d76419facd99662a07e59d3cdb560488a819d9a45" "checksum wasm-bindgen-backend 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd"
"checksum wasm-bindgen-macro 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "574094772ce6921576fb6f2e3f7497b8a76273b6db092be18fc48a082de09dc3" "checksum wasm-bindgen-futures 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "7add542ea1ac7fdaa9dc25e031a6af33b7d63376292bd24140c637d00d1c312a"
"checksum wasm-bindgen-macro-support 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "e85031354f25eaebe78bb7db1c3d86140312a911a106b2e29f9cc440ce3e7668" "checksum wasm-bindgen-macro 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4"
"checksum wasm-bindgen-shared 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e7e61fc929f4c0dddb748b102ebf9f632e2b8d739f2016542b4de2965a9601" "checksum wasm-bindgen-macro-support 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931"
"checksum wasm-bindgen-shared 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639"
"checksum wayland-client 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "af1080ebe0efabcf12aef2132152f616038f2d7dcbbccf7b2d8c5270fe14bcda" "checksum wayland-client 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "af1080ebe0efabcf12aef2132152f616038f2d7dcbbccf7b2d8c5270fe14bcda"
"checksum wayland-commons 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "bb66b0d1a27c39bbce712b6372131c6e25149f03ffb0cd017cf8f7de8d66dbdb" "checksum wayland-commons 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "bb66b0d1a27c39bbce712b6372131c6e25149f03ffb0cd017cf8f7de8d66dbdb"
"checksum wayland-protocols 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc286643656742777d55dc8e70d144fa4699e426ca8e9d4ef454f4bf15ffcf9" "checksum wayland-protocols 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc286643656742777d55dc8e70d144fa4699e426ca8e9d4ef454f4bf15ffcf9"
"checksum wayland-scanner 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93b02247366f395b9258054f964fe293ddd019c3237afba9be2ccbe9e1651c3d" "checksum wayland-scanner 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93b02247366f395b9258054f964fe293ddd019c3237afba9be2ccbe9e1651c3d"
"checksum wayland-sys 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d94e89a86e6d6d7c7c9b19ebf48a03afaac4af6bc22ae570e9a24124b75358f4" "checksum wayland-sys 0.23.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d94e89a86e6d6d7c7c9b19ebf48a03afaac4af6bc22ae570e9a24124b75358f4"
"checksum web-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6f51648d8c56c366144378a33290049eafdd784071077f6fe37dae64c1c4cb"
"checksum wgpu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e9c1ff587eddd68cdf2a78889c7a2128683161c72c67b94457cf498accaf7b" "checksum wgpu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e9c1ff587eddd68cdf2a78889c7a2128683161c72c67b94457cf498accaf7b"
"checksum wgpu 0.5.0 (git+https://github.com/gfx-rs/wgpu-rs.git)" = "<none>"
"checksum wgpu 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf715eb8571da470b856ecc67b057221360d9fce16f3e38001b2fb158d04012" "checksum wgpu 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf715eb8571da470b856ecc67b057221360d9fce16f3e38001b2fb158d04012"
"checksum wgpu-core 0.5.0 (git+https://github.com/gfx-rs/wgpu?rev=49dbe08f37f8396cff0d6672667a48116ec487f5)" = "<none>"
"checksum wgpu-core 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1c252c2442d874c794813ae037fd6cbeaa4a6d8035980e1179f2286ec0d179a6" "checksum wgpu-core 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1c252c2442d874c794813ae037fd6cbeaa4a6d8035980e1179f2286ec0d179a6"
"checksum wgpu-native 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "282dea6c13cfab27737dc34f131dd1ba72ff990f61c27f57f9299bec3d1c5de5" "checksum wgpu-native 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "282dea6c13cfab27737dc34f131dd1ba72ff990f61c27f57f9299bec3d1c5de5"
"checksum wgpu-native 0.5.0 (git+https://github.com/gfx-rs/wgpu?rev=49dbe08f37f8396cff0d6672667a48116ec487f5)" = "<none>"
"checksum wgpu-native 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "19a5051a357d071fd69c24671e0ea6d644a83c7418e47eac3511427379007403" "checksum wgpu-native 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "19a5051a357d071fd69c24671e0ea6d644a83c7418e47eac3511427379007403"
"checksum wgpu-types 0.5.0 (git+https://github.com/gfx-rs/wgpu?rev=49dbe08f37f8396cff0d6672667a48116ec487f5)" = "<none>"
"checksum wgpu-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67b69dfe001a8a6b78810c7e479717cd1898b9177dbf646611fa1f258f5a2512" "checksum wgpu-types 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67b69dfe001a8a6b78810c7e479717cd1898b9177dbf646611fa1f258f5a2512"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
@ -2510,10 +2795,11 @@ dependencies = [
"checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" "checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum winit 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba128780050481f453bec2a115b916dbc6ae79c303dee9bad8b9080bdccd4f5" "checksum winit 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ba128780050481f453bec2a115b916dbc6ae79c303dee9bad8b9080bdccd4f5"
"checksum winit 0.22.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fc53342d3d1a3d57f3949e0692d93d5a8adb7814d8683cef4a09c2b550e94246"
"checksum wio 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" "checksum wio 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
"checksum x11 2.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39697e3123f715483d311b5826e254b6f3cfebdd83cf7ef3358f579c3d68e235" "checksum x11 2.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39697e3123f715483d311b5826e254b6f3cfebdd83cf7ef3358f579c3d68e235"
"checksum x11-dl 2.18.4 (registry+https://github.com/rust-lang/crates.io-index)" = "be65e1342a3baae65439cd03306778831a3d133b0d20243a7fb83fd5cf403c58" "checksum x11-dl 2.18.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2bf981e3a5b3301209754218f962052d4d9ee97e478f4d26d4a6eced34c1fef8"
"checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" "checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"
"checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5" "checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5"
"checksum zerocopy 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "992b9b31f80fd4a167f903f879b8ca43d6716cc368ea01df90538baa2dd34056" "checksum zerocopy 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "992b9b31f80fd4a167f903f879b8ca43d6716cc368ea01df90538baa2dd34056"

View File

@ -7,14 +7,16 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
image = "0.22.4" image = "0.23"
winit = "0.20.0" winit = "0.22"
glsl-to-spirv = "0.1.7" glsl-to-spirv = "0.1"
cgmath = "0.17.0" cgmath = "0.17"
failure = "0.1" failure = "0.1"
tobj = "1"
wgpu = "0.4.0" bytemuck = "1.2"
# wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git" } futures = "0.3"
# wgpu = "0.5"
wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git" }
# zerocopy = "0.2.8" # zerocopy = "0.2.8"
[[bin]] [[bin]]
@ -25,3 +27,4 @@ path = "src/main.rs"
[[bin]] [[bin]]
name = "tutorial8-challenge" name = "tutorial8-challenge"
path = "src/challenge.rs" path = "src/challenge.rs"

View File

@ -7,15 +7,16 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
image = "0.22.4" image = "0.23"
winit = "0.20.0" winit = "0.22"
glsl-to-spirv = "0.1.7" glsl-to-spirv = "0.1"
cgmath = "0.17.0" cgmath = "0.17"
failure = "0.1" failure = "0.1"
tobj = "0.1" tobj = "1"
bytemuck = "1.2"
wgpu = "0.4.0" futures = "0.3"
# wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git" } # wgpu = "0.5"
wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git" }
# zerocopy = "0.2.8" # zerocopy = "0.2.8"
[[bin]] [[bin]]

View File

@ -1,18 +1,15 @@
use cgmath::prelude::*;
use winit::{ use winit::{
event::*, event::*,
event_loop::{EventLoop, ControlFlow}, event_loop::{ControlFlow, EventLoop},
window::{Window, WindowBuilder}, window::Window,
}; };
use cgmath::prelude::*;
mod texture;
mod model; mod model;
mod texture;
use model::{DrawModel, Vertex}; use model::{DrawModel, Vertex};
#[cfg_attr(rustfmt, rustfmt_skip)] #[cfg_attr(rustfmt, rustfmt_skip)]
pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new( pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
@ -55,10 +52,12 @@ impl Uniforms {
} }
fn update_view_proj(&mut self, camera: &Camera) { fn update_view_proj(&mut self, camera: &Camera) {
self.view_proj = OPENGL_TO_WGPU_MATRIX * camera.build_view_projection_matrix(); self.view_proj = camera.build_view_projection_matrix();
// self.view_proj = OPENGL_TO_WGPU_MATRIX * camera.build_view_projection_matrix();
} }
} }
unsafe impl bytemuck::Zeroable for Uniforms {}
unsafe impl bytemuck::Pod for Uniforms {}
struct CameraController { struct CameraController {
speed: f32, speed: f32,
is_up_pressed: bool, is_up_pressed: bool,
@ -85,11 +84,12 @@ impl CameraController {
fn process_events(&mut self, event: &WindowEvent) -> bool { fn process_events(&mut self, event: &WindowEvent) -> bool {
match event { match event {
WindowEvent::KeyboardInput { WindowEvent::KeyboardInput {
input: KeyboardInput { input:
state, KeyboardInput {
virtual_keycode: Some(keycode), state,
.. virtual_keycode: Some(keycode),
}, ..
},
.. ..
} => { } => {
let is_pressed = *state == ElementState::Pressed; let is_pressed = *state == ElementState::Pressed;
@ -158,77 +158,44 @@ impl Instance {
} }
struct State { struct State {
surface: wgpu::Surface,
device: wgpu::Device,
queue: wgpu::Queue,
sc_desc: wgpu::SwapChainDescriptor,
swap_chain: wgpu::SwapChain,
render_pipeline: wgpu::RenderPipeline, render_pipeline: wgpu::RenderPipeline,
obj_model: model::Model, obj_model: model::Model,
camera: Camera, camera: Camera,
camera_controller: CameraController, camera_controller: CameraController,
uniforms: Uniforms, uniforms: Uniforms,
uniform_buffer: wgpu::Buffer, uniform_buffer: wgpu::Buffer,
uniform_bind_group: wgpu::BindGroup, uniform_bind_group: wgpu::BindGroup,
size: winit::dpi::PhysicalSize<u32>,
instances: Vec<Instance>, instances: Vec<Instance>,
instance_buffer: wgpu::Buffer, instance_buffer: wgpu::Buffer,
depth_texture: wgpu::Texture, depth_texture: wgpu::Texture,
depth_texture_view: wgpu::TextureView, depth_texture_view: wgpu::TextureView,
} }
const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
fn create_depth_texture(device: &wgpu::Device, sc_desc: &wgpu::SwapChainDescriptor) -> wgpu::Texture {
let desc = wgpu::TextureDescriptor {
format: DEPTH_FORMAT,
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
..sc_desc.to_texture_desc()
};
device.create_texture(&desc)
}
impl State { impl State {
fn new(window: &Window) -> Self { fn new(
let size = window.inner_size(); sc_desc: &wgpu::SwapChainDescriptor,
device: &wgpu::Device,
let surface = wgpu::Surface::create(window); ) -> (Self, Option<Vec<wgpu::CommandBuffer>>) {
let texture_bind_group_layout =
let adapter = wgpu::Adapter::request(&Default::default()).unwrap(); device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
bindings: &[
let (device, mut queue) = adapter.request_device(&Default::default()); wgpu::BindGroupLayoutEntry {
binding: 0,
let sc_desc = wgpu::SwapChainDescriptor { visibility: wgpu::ShaderStage::FRAGMENT,
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, ty: wgpu::BindingType::SampledTexture {
format: wgpu::TextureFormat::Bgra8UnormSrgb, multisampled: false,
width: size.width, component_type: wgpu::TextureComponentType::Float,
height: size.height, dimension: wgpu::TextureViewDimension::D2,
present_mode: wgpu::PresentMode::Vsync, },
};
let swap_chain = device.create_swap_chain(&surface, &sc_desc);
let texture_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
bindings: &[
wgpu::BindGroupLayoutBinding {
binding: 0,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::SampledTexture {
multisampled: false,
dimension: wgpu::TextureViewDimension::D2,
}, },
}, wgpu::BindGroupLayoutEntry {
wgpu::BindGroupLayoutBinding { binding: 1,
binding: 1, visibility: wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStage::FRAGMENT, ty: wgpu::BindingType::Sampler { comparison: false },
ty: wgpu::BindingType::Sampler, },
}, ],
], label: None,
}); });
let camera = Camera { let camera = Camera {
eye: (0.0, 5.0, -10.0).into(), eye: (0.0, 5.0, -10.0).into(),
@ -244,56 +211,67 @@ impl State {
let mut uniforms = Uniforms::new(); let mut uniforms = Uniforms::new();
uniforms.update_view_proj(&camera); uniforms.update_view_proj(&camera);
let uniform_buffer = device let uniform_buffer = device.create_buffer_with_data(
.create_buffer_mapped(1, wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST) bytemuck::cast_slice(&[uniforms]),
.fill_from_slice(&[uniforms]); wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
);
const SPACE_BETWEEN: f32 = 3.0; const SPACE_BETWEEN: f32 = 3.0;
let instances = (0..NUM_INSTANCES_PER_ROW).flat_map(|z| { let instances = (0..NUM_INSTANCES_PER_ROW)
(0..NUM_INSTANCES_PER_ROW).map(move |x| { .flat_map(|z| {
let x = SPACE_BETWEEN * (x as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0); (0..NUM_INSTANCES_PER_ROW).map(move |x| {
let z = SPACE_BETWEEN * (z as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0); let x = SPACE_BETWEEN * (x as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0);
let z = SPACE_BETWEEN * (z as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0);
let position = cgmath::Vector3 { x, y: 0.0, z }; let position = cgmath::Vector3 { x, y: 0.0, z };
let rotation = if position.is_zero() { let rotation = if position.is_zero() {
cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_z(), cgmath::Deg(0.0)) cgmath::Quaternion::from_axis_angle(
} else { cgmath::Vector3::unit_z(),
cgmath::Quaternion::from_axis_angle(position.clone().normalize(), cgmath::Deg(45.0)) cgmath::Deg(0.0),
}; )
} else {
cgmath::Quaternion::from_axis_angle(
position.clone().normalize(),
cgmath::Deg(45.0),
)
};
Instance { Instance { position, rotation }
position, rotation, })
}
}) })
}).collect::<Vec<_>>(); .collect::<Vec<_>>();
let instance_data = instances.iter().map(Instance::to_matrix).collect::<Vec<_>>(); let instance_data = instances
let instance_buffer_size = instance_data.len() * std::mem::size_of::<cgmath::Matrix4<f32>>(); .iter()
let instance_buffer = device .map(Instance::to_matrix)
.create_buffer_mapped(instance_data.len(), wgpu::BufferUsage::STORAGE_READ) .collect::<Vec<_>>();
.fill_from_slice(&instance_data); let instance_buffer_size =
instance_data.len() * std::mem::size_of::<cgmath::Matrix4<f32>>();
let instance_buffer = device.create_buffer_with_data(
matrix4f_cast_slice(&[instance_data]),
wgpu::BufferUsage::STORAGE_READ,
);
let uniform_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { let uniform_bind_group_layout =
bindings: &[ device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
wgpu::BindGroupLayoutBinding { bindings: &[
binding: 0, wgpu::BindGroupLayoutEntry {
visibility: wgpu::ShaderStage::VERTEX, binding: 0,
ty: wgpu::BindingType::UniformBuffer { visibility: wgpu::ShaderStage::VERTEX,
dynamic: false, ty: wgpu::BindingType::UniformBuffer { dynamic: false },
}, },
}, wgpu::BindGroupLayoutEntry {
wgpu::BindGroupLayoutBinding { binding: 1,
binding: 1, visibility: wgpu::ShaderStage::VERTEX,
visibility: wgpu::ShaderStage::VERTEX, ty: wgpu::BindingType::StorageBuffer {
ty: wgpu::BindingType::StorageBuffer { dynamic: false,
dynamic: false, readonly: true,
readonly: true, },
} },
} ],
] label: None,
}); });
let uniform_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { let uniform_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &uniform_bind_group_layout, layout: &uniform_bind_group_layout,
@ -303,20 +281,25 @@ impl State {
resource: wgpu::BindingResource::Buffer { resource: wgpu::BindingResource::Buffer {
buffer: &uniform_buffer, buffer: &uniform_buffer,
range: 0..std::mem::size_of_val(&uniforms) as wgpu::BufferAddress, range: 0..std::mem::size_of_val(&uniforms) as wgpu::BufferAddress,
} },
}, },
wgpu::Binding { wgpu::Binding {
binding: 1, binding: 1,
resource: wgpu::BindingResource::Buffer { resource: wgpu::BindingResource::Buffer {
buffer: &instance_buffer, buffer: &instance_buffer,
range: 0..instance_buffer_size as wgpu::BufferAddress, range: 0..instance_buffer_size as wgpu::BufferAddress,
} },
} },
], ],
label: None,
}); });
let (obj_model, cmds) = model::Model::load(&device, &texture_bind_group_layout, "code/beginner/tutorial9-models/src/res/cube.obj").unwrap(); let (obj_model, cmds) = model::Model::load(
queue.submit(&cmds); &device,
&texture_bind_group_layout,
"code/beginner/tutorial9-models/src/res/cube.obj",
)
.unwrap();
let vs_src = include_str!("shader.vert"); let vs_src = include_str!("shader.vert");
let fs_src = include_str!("shader.frag"); let fs_src = include_str!("shader.frag");
@ -327,12 +310,13 @@ impl State {
let vs_module = device.create_shader_module(&vs_data); let vs_module = device.create_shader_module(&vs_data);
let fs_module = device.create_shader_module(&fs_data); let fs_module = device.create_shader_module(&fs_data);
let depth_texture = create_depth_texture(&device, &sc_desc); let depth_texture = texture::Texture::create_depth_texture(&device, &sc_desc).texture;
let depth_texture_view = depth_texture.create_default_view(); let depth_texture_view = depth_texture.create_default_view();
let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { let render_pipeline_layout =
bind_group_layouts: &[&texture_bind_group_layout, &uniform_bind_group_layout], device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
}); bind_group_layouts: &[&texture_bind_group_layout, &uniform_bind_group_layout],
});
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
layout: &render_pipeline_layout, layout: &render_pipeline_layout,
@ -352,16 +336,14 @@ impl State {
depth_bias_clamp: 0.0, depth_bias_clamp: 0.0,
}), }),
primitive_topology: wgpu::PrimitiveTopology::TriangleList, primitive_topology: wgpu::PrimitiveTopology::TriangleList,
color_states: &[ color_states: &[wgpu::ColorStateDescriptor {
wgpu::ColorStateDescriptor { format: sc_desc.format,
format: sc_desc.format, color_blend: wgpu::BlendDescriptor::REPLACE,
color_blend: wgpu::BlendDescriptor::REPLACE, alpha_blend: wgpu::BlendDescriptor::REPLACE,
alpha_blend: wgpu::BlendDescriptor::REPLACE, write_mask: wgpu::ColorWrite::ALL,
write_mask: wgpu::ColorWrite::ALL, }],
},
],
depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor { depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor {
format: DEPTH_FORMAT, format: texture::DEPTH_FORMAT,
depth_write_enabled: true, depth_write_enabled: true,
depth_compare: wgpu::CompareFunction::Less, depth_compare: wgpu::CompareFunction::Less,
stencil_front: wgpu::StencilStateFaceDescriptor::IGNORE, stencil_front: wgpu::StencilStateFaceDescriptor::IGNORE,
@ -369,21 +351,16 @@ impl State {
stencil_read_mask: 0, stencil_read_mask: 0,
stencil_write_mask: 0, stencil_write_mask: 0,
}), }),
index_format: wgpu::IndexFormat::Uint32,
vertex_buffers: &[
model::ModelVertex::desc(),
],
sample_count: 1, sample_count: 1,
sample_mask: !0, sample_mask: !0,
alpha_to_coverage_enabled: false, alpha_to_coverage_enabled: false,
vertex_state: wgpu::VertexStateDescriptor {
index_format: wgpu::IndexFormat::Uint32,
vertex_buffers: &[model::ModelVertex::desc()],
},
}); });
Self { let state = Self {
surface,
device,
queue,
sc_desc,
swap_chain,
render_pipeline, render_pipeline,
obj_model, obj_model,
camera, camera,
@ -391,71 +368,75 @@ impl State {
uniform_buffer, uniform_buffer,
uniform_bind_group, uniform_bind_group,
uniforms, uniforms,
size,
instances, instances,
instance_buffer, instance_buffer,
depth_texture, depth_texture,
depth_texture_view, depth_texture_view,
} };
(state, Some(cmds))
} }
fn resize(
fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) { &mut self,
self.size = new_size; sc_desc: &wgpu::SwapChainDescriptor,
self.sc_desc.width = new_size.width; device: &wgpu::Device,
self.sc_desc.height = new_size.height; ) -> Option<wgpu::CommandBuffer> {
self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc); self.depth_texture = texture::Texture::create_depth_texture(device, sc_desc).texture;
self.depth_texture = create_depth_texture(&self.device, &self.sc_desc);
self.depth_texture_view = self.depth_texture.create_default_view(); self.depth_texture_view = self.depth_texture.create_default_view();
self.camera.aspect = sc_desc.width as f32 / sc_desc.height as f32;
self.camera.aspect = self.sc_desc.width as f32 / self.sc_desc.height as f32; None
} }
fn input(&mut self, event: &WindowEvent) -> bool { fn input(&mut self, event: &WindowEvent) -> bool {
self.camera_controller.process_events(event) self.camera_controller.process_events(event)
} }
fn update(&mut self) { fn update(&mut self, device: &wgpu::Device) -> Option<wgpu::CommandBuffer> {
self.camera_controller.update_camera(&mut self.camera); self.camera_controller.update_camera(&mut self.camera);
self.uniforms.update_view_proj(&self.camera); self.uniforms.update_view_proj(&self.camera);
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { let mut encoder =
todo: 0, device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
});
let staging_buffer = self.device let staging_buffer = device.create_buffer_with_data(
.create_buffer_mapped(1, wgpu::BufferUsage::COPY_SRC) bytemuck::cast_slice(&[self.uniforms]),
.fill_from_slice(&[self.uniforms]); wgpu::BufferUsage::COPY_SRC,
);
encoder.copy_buffer_to_buffer(&staging_buffer, 0, &self.uniform_buffer, 0, std::mem::size_of::<Uniforms>() as wgpu::BufferAddress); encoder.copy_buffer_to_buffer(
&staging_buffer,
0,
&self.uniform_buffer,
0,
std::mem::size_of::<Uniforms>() as wgpu::BufferAddress,
);
self.queue.submit(&[encoder.finish()]); Some(encoder.finish())
} }
fn render(&mut self) { fn render(
let frame = self.swap_chain.get_next_texture(); &mut self,
frame: &wgpu::SwapChainOutput,
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { device: &wgpu::Device,
todo: 0, ) -> wgpu::CommandBuffer {
}); let mut encoder =
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
{ {
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[ color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
wgpu::RenderPassColorAttachmentDescriptor { attachment: &frame.view,
attachment: &frame.view, resolve_target: None,
resolve_target: None, load_op: wgpu::LoadOp::Clear,
load_op: wgpu::LoadOp::Clear, store_op: wgpu::StoreOp::Store,
store_op: wgpu::StoreOp::Store, clear_color: wgpu::Color {
clear_color: wgpu::Color { r: 0.1,
r: 0.1, g: 0.2,
g: 0.2, b: 0.3,
b: 0.3, a: 1.0,
a: 1.0, },
}, }],
}
],
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor { depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor {
attachment: &self.depth_texture_view, attachment: &self.depth_texture_view,
depth_load_op: wgpu::LoadOp::Clear, depth_load_op: wgpu::LoadOp::Clear,
@ -468,63 +449,123 @@ impl State {
}); });
render_pass.set_pipeline(&self.render_pipeline); render_pass.set_pipeline(&self.render_pipeline);
render_pass.draw_model_instanced(&self.obj_model, 0..self.instances.len() as u32, &self.uniform_bind_group); render_pass.draw_model_instanced(
&self.obj_model,
0..self.instances.len() as u32,
&self.uniform_bind_group,
);
} }
self.queue.submit(&[ encoder.finish()
encoder.finish()
]);
} }
} }
async fn run_async(event_loop: EventLoop<()>, window: Window) {
let size = window.inner_size();
let surface = wgpu::Surface::create(&window);
let adapter = wgpu::Adapter::request(
&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: Some(&surface),
},
wgpu::BackendBit::PRIMARY,
)
.await
.unwrap();
let (device, queue) = adapter
.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: wgpu::Limits::default(),
})
.await;
let mut sc_desc = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: if cfg!(target_arch = "wasm32") {
wgpu::TextureFormat::Bgra8Unorm
} else {
wgpu::TextureFormat::Bgra8UnormSrgb
},
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Mailbox,
};
let mut swap_chain = device.create_swap_chain(&surface, &sc_desc);
fn main() { let (mut state, init_cmds_buf) = State::new(&sc_desc, &device);
let event_loop = EventLoop::new();
let window = WindowBuilder::new()
.build(&event_loop)
.unwrap();
let mut state = State::new(&window);
if let Some(cmds_buf) = init_cmds_buf {
queue.submit(&cmds_buf);
}
event_loop.run(move |event, _, control_flow| { event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
match event { match event {
Event::MainEventsCleared => window.request_redraw(),
Event::WindowEvent { Event::WindowEvent {
ref event, ref event,
window_id, window_id,
} if window_id == window.id() => if state.input(event) { } if window_id == window.id() => {
*control_flow = ControlFlow::Wait; if !state.input(event) {
} else { match event {
match event { WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, WindowEvent::KeyboardInput { input, .. } => match input {
WindowEvent::KeyboardInput {
input,
..
} => {
match input {
KeyboardInput { KeyboardInput {
state: ElementState::Pressed, state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape), virtual_keycode: Some(VirtualKeyCode::Escape),
.. ..
} => *control_flow = ControlFlow::Exit, } => {
_ => *control_flow = ControlFlow::Wait, *control_flow = ControlFlow::Exit;
}
_ => {}
},
WindowEvent::Resized(physical_size) => {
sc_desc.width = physical_size.width;
sc_desc.height = physical_size.height;
swap_chain = device.create_swap_chain(&surface, &sc_desc);
let cmd_buf = state.resize(&sc_desc, &device);
if let Some(cmd_buf) = cmd_buf {
queue.submit(&[cmd_buf]);
}
} }
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
sc_desc.width = new_inner_size.width;
sc_desc.height = new_inner_size.height;
swap_chain = device.create_swap_chain(&surface, &sc_desc);
let cmd_buf = state.resize(&sc_desc, &device);
if let Some(cmd_buf) = cmd_buf {
queue.submit(&[cmd_buf]);
}
}
_ => {}
} }
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
*control_flow = ControlFlow::Wait;
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
state.resize(**new_inner_size);
*control_flow = ControlFlow::Wait;
}
_ => *control_flow = ControlFlow::Wait,
} }
} }
Event::MainEventsCleared => { Event::RedrawRequested(_) => {
state.update(); if let Some(cmd_buf) = state.update(&device) {
state.render(); queue.submit(&[cmd_buf]);
*control_flow = ControlFlow::Wait; }
let frame = swap_chain
.get_next_texture()
.expect("Timeout when acquiring next swap chain texture");
let command_buf = state.render(&frame, &device);
queue.submit(&[command_buf]);
} }
_ => *control_flow = ControlFlow::Wait, _ => {}
} }
}); });
} }
fn main() {
let event_loop = EventLoop::new();
let title = "tutorial9-models";
let window = winit::window::WindowBuilder::new()
.with_title(title)
.build(&event_loop)
.unwrap();
futures::executor::block_on(run_async(event_loop, window));
}
#[inline]
pub fn matrix4f_cast_slice(a: &[Vec<cgmath::Matrix4<f32>>]) -> &[u8] {
let new_len = a[0].len() * std::mem::size_of::<cgmath::Matrix4<f32>>();
unsafe { core::slice::from_raw_parts(a[0].as_ptr() as *const u8, new_len) }
}

View File

@ -1,5 +1,5 @@
use std::path::Path;
use std::ops::Range; use std::ops::Range;
use std::path::Path;
use crate::texture; use crate::texture;
@ -14,6 +14,8 @@ pub struct ModelVertex {
tex_coords: [f32; 2], tex_coords: [f32; 2],
normal: [f32; 3], normal: [f32; 3],
} }
unsafe impl bytemuck::Zeroable for ModelVertex {}
unsafe impl bytemuck::Pod for ModelVertex {}
impl Vertex for ModelVertex { impl Vertex for ModelVertex {
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> { fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
@ -37,7 +39,7 @@ impl Vertex for ModelVertex {
shader_location: 2, shader_location: 2,
format: wgpu::VertexFormat::Float3, format: wgpu::VertexFormat::Float3,
}, },
] ],
} }
} }
} }
@ -61,9 +63,12 @@ pub struct Model {
pub materials: Vec<Material>, pub materials: Vec<Material>,
} }
impl Model { impl Model {
pub fn load<P: AsRef<Path>>(device: &wgpu::Device, layout: &wgpu::BindGroupLayout, path: P) -> Result<(Self, Vec<wgpu::CommandBuffer>), failure::Error> { pub fn load<P: AsRef<Path>>(
device: &wgpu::Device,
layout: &wgpu::BindGroupLayout,
path: P,
) -> Result<(Self, Vec<wgpu::CommandBuffer>), failure::Error> {
let (obj_models, obj_materials) = tobj::load_obj(path.as_ref())?; let (obj_models, obj_materials) = tobj::load_obj(path.as_ref())?;
// We're assuming that the texture files are stored with the obj file // We're assuming that the texture files are stored with the obj file
@ -75,7 +80,8 @@ impl Model {
let mut materials = Vec::new(); let mut materials = Vec::new();
for mat in obj_materials { for mat in obj_materials {
let diffuse_path = mat.diffuse_texture; let diffuse_path = mat.diffuse_texture;
let (diffuse_texture, cmds) = texture::Texture::load(&device, containing_folder.join(diffuse_path))?; let (diffuse_texture, cmds) =
texture::Texture::load(&device, containing_folder.join(diffuse_path))?;
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout, layout,
@ -88,7 +94,8 @@ impl Model {
binding: 1, binding: 1,
resource: wgpu::BindingResource::Sampler(&diffuse_texture.sampler), resource: wgpu::BindingResource::Sampler(&diffuse_texture.sampler),
}, },
] ],
label: None,
}); });
materials.push(Material { materials.push(Material {
@ -109,10 +116,7 @@ impl Model {
m.mesh.positions[i * 3 + 1], m.mesh.positions[i * 3 + 1],
m.mesh.positions[i * 3 + 2], m.mesh.positions[i * 3 + 2],
], ],
tex_coords: [ tex_coords: [m.mesh.texcoords[i * 2], m.mesh.texcoords[i * 2 + 1]],
m.mesh.texcoords[i * 2],
m.mesh.texcoords[i * 2 + 1],
],
normal: [ normal: [
m.mesh.normals[i * 3], m.mesh.normals[i * 3],
m.mesh.normals[i * 3 + 1], m.mesh.normals[i * 3 + 1],
@ -121,13 +125,14 @@ impl Model {
}); });
} }
let vertex_buffer = device let vertex_buffer = device.create_buffer_with_data(
.create_buffer_mapped(vertices.len(), wgpu::BufferUsage::VERTEX) bytemuck::cast_slice(&vertices),
.fill_from_slice(&vertices); wgpu::BufferUsage::VERTEX,
);
let index_buffer = device let index_buffer = device.create_buffer_with_data(
.create_buffer_mapped(m.mesh.indices.len(), wgpu::BufferUsage::INDEX) bytemuck::cast_slice(&m.mesh.indices),
.fill_from_slice(&m.mesh.indices); wgpu::BufferUsage::INDEX,
);
meshes.push(Mesh { meshes.push(Mesh {
name: m.name, name: m.name,
@ -138,36 +143,64 @@ impl Model {
}); });
} }
Ok((Self { meshes, materials, }, command_buffers)) Ok((Self { meshes, materials }, command_buffers))
} }
} }
pub trait DrawModel { pub trait DrawModel<'a, 'b>
fn draw_mesh(&mut self, mesh: &Mesh, material: &Material, uniforms: &wgpu::BindGroup); where
fn draw_mesh_instanced(&mut self, mesh: &Mesh, material: &Material, instances: Range<u32>, uniforms: &wgpu::BindGroup); 'b: 'a,
{
fn draw_mesh(&mut self, mesh: &'b Mesh, material: &'b Material, uniforms: &'b wgpu::BindGroup);
fn draw_mesh_instanced(
&mut self,
mesh: &'b Mesh,
material: &'b Material,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
);
fn draw_model(&mut self, model: &Model, uniforms: &wgpu::BindGroup); fn draw_model(&mut self, model: &'b Model, uniforms: &'b wgpu::BindGroup);
fn draw_model_instanced(&mut self, model: &Model, instances: Range<u32>, uniforms: &wgpu::BindGroup); fn draw_model_instanced(
&mut self,
model: &'b Model,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
);
} }
impl<'a> DrawModel for wgpu::RenderPass<'a> { impl<'a, 'b> DrawModel<'a, 'b> for wgpu::RenderPass<'a>
fn draw_mesh(&mut self, mesh: &Mesh, material: &Material, uniforms: &wgpu::BindGroup) { where
'b: 'a,
{
fn draw_mesh(&mut self, mesh: &'b Mesh, material: &'b Material, uniforms: &'b wgpu::BindGroup) {
self.draw_mesh_instanced(mesh, material, 0..1, uniforms); self.draw_mesh_instanced(mesh, material, 0..1, uniforms);
} }
fn draw_mesh_instanced(&mut self, mesh: &Mesh, material: &Material, instances: Range<u32>, uniforms: &wgpu::BindGroup) { fn draw_mesh_instanced(
self.set_vertex_buffers(0, &[(&mesh.vertex_buffer, 0)]); &mut self,
self.set_index_buffer(&mesh.index_buffer, 0); mesh: &'b Mesh,
material: &'b Material,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
) {
self.set_vertex_buffer(0, &mesh.vertex_buffer, 0, 0);
self.set_index_buffer(&mesh.index_buffer, 0, 0);
self.set_bind_group(0, &material.bind_group, &[]); self.set_bind_group(0, &material.bind_group, &[]);
self.set_bind_group(1, &uniforms, &[]); self.set_bind_group(1, &uniforms, &[]);
self.draw_indexed(0..mesh.num_elements, 0, instances); self.draw_indexed(0..mesh.num_elements, 0, instances);
} }
fn draw_model(&mut self, model: &Model, uniforms: &wgpu::BindGroup) { fn draw_model(&mut self, model: &'b Model, uniforms: &'b wgpu::BindGroup) {
self.draw_model_instanced(model, 0..1, uniforms); self.draw_model_instanced(model, 0..1, uniforms);
} }
fn draw_model_instanced(&mut self, model: &Model, instances: Range<u32>, uniforms: &wgpu::BindGroup) { fn draw_model_instanced(
&mut self,
model: &'b Model,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
) {
for mesh in &model.meshes { for mesh in &model.meshes {
let material = &model.materials[mesh.material]; let material = &model.materials[mesh.material];
self.draw_mesh_instanced(mesh, material, instances.clone(), uniforms); self.draw_mesh_instanced(mesh, material, instances.clone(), uniforms);

View File

@ -10,5 +10,5 @@ Ke 0.000000 0.000000 0.000000
Ni 1.450000 Ni 1.450000
d 1.000000 d 1.000000
illum 2 illum 2
map_Bump /home/benjamin/Downloads/tuto-14-normal.png map_Bump cube-normal.png
map_Kd /home/benjamin/Downloads/tuto-14-diffuse.jpg map_Kd cube-diffuse.jpg

View File

@ -1,6 +1,7 @@
use image::GenericImageView; use image::GenericImageView;
use std::path::Path; use std::path::Path;
pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
pub struct Texture { pub struct Texture {
pub texture: wgpu::Texture, pub texture: wgpu::Texture,
@ -9,18 +10,30 @@ pub struct Texture {
} }
impl Texture { impl Texture {
pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float; pub fn load<P: AsRef<Path>>(
device: &wgpu::Device,
pub fn load<P: AsRef<Path>>(device: &wgpu::Device, path: P) -> Result<(Self, wgpu::CommandBuffer), failure::Error> { path: P,
) -> Result<(Self, wgpu::CommandBuffer), failure::Error> {
let img = image::open(path)?; let img = image::open(path)?;
Self::from_image(device, &img) Self::from_image(device, &img)
} }
pub fn create_depth_texture(device: &wgpu::Device, sc_desc: &wgpu::SwapChainDescriptor) -> Self { pub fn create_depth_texture(
device: &wgpu::Device,
sc_desc: &wgpu::SwapChainDescriptor,
) -> Self {
let desc = wgpu::TextureDescriptor { let desc = wgpu::TextureDescriptor {
format: Self::DEPTH_FORMAT, label: None,
size: wgpu::Extent3d {
width: sc_desc.width,
height: sc_desc.height,
depth: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: DEPTH_FORMAT,
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
..sc_desc.to_texture_desc()
}; };
let texture = device.create_texture(&desc); let texture = device.create_texture(&desc);
@ -34,18 +47,28 @@ impl Texture {
mipmap_filter: wgpu::FilterMode::Nearest, mipmap_filter: wgpu::FilterMode::Nearest,
lod_min_clamp: -100.0, lod_min_clamp: -100.0,
lod_max_clamp: 100.0, lod_max_clamp: 100.0,
compare_function: wgpu::CompareFunction::Always, compare: wgpu::CompareFunction::Always,
}); });
Self { texture, view, sampler } Self {
texture,
view,
sampler,
}
} }
pub fn from_bytes(device: &wgpu::Device, bytes: &[u8]) -> Result<(Self, wgpu::CommandBuffer), failure::Error> { pub fn from_bytes(
device: &wgpu::Device,
bytes: &[u8],
) -> Result<(Self, wgpu::CommandBuffer), failure::Error> {
let img = image::load_from_memory(bytes)?; let img = image::load_from_memory(bytes)?;
Self::from_image(device, &img) Self::from_image(device, &img)
} }
pub fn from_image(device: &wgpu::Device, img: &image::DynamicImage) -> Result<(Self, wgpu::CommandBuffer), failure::Error> { pub fn from_image(
device: &wgpu::Device,
img: &image::DynamicImage,
) -> Result<(Self, wgpu::CommandBuffer), failure::Error> {
let rgba = img.to_rgba(); let rgba = img.to_rgba();
let dimensions = img.dimensions(); let dimensions = img.dimensions();
@ -55,8 +78,8 @@ impl Texture {
depth: 1, depth: 1,
}; };
let texture = device.create_texture(&wgpu::TextureDescriptor { let texture = device.create_texture(&wgpu::TextureDescriptor {
label: None,
size, size,
array_layer_count: 1,
mip_level_count: 1, mip_level_count: 1,
sample_count: 1, sample_count: 1,
dimension: wgpu::TextureDimension::D2, dimension: wgpu::TextureDimension::D2,
@ -65,8 +88,7 @@ impl Texture {
}); });
let buffer = device let buffer = device
.create_buffer_mapped(rgba.len(), wgpu::BufferUsage::COPY_SRC) .create_buffer_with_data(bytemuck::cast_slice(&rgba), wgpu::BufferUsage::COPY_SRC);
.fill_from_slice(&rgba);
let mut encoder = device.create_command_encoder(&Default::default()); let mut encoder = device.create_command_encoder(&Default::default());
@ -74,8 +96,8 @@ impl Texture {
wgpu::BufferCopyView { wgpu::BufferCopyView {
buffer: &buffer, buffer: &buffer,
offset: 0, offset: 0,
row_pitch: 4 * dimensions.0, bytes_per_row: 4 * dimensions.0,
image_height: dimensions.1, rows_per_image: dimensions.1,
}, },
wgpu::TextureCopyView { wgpu::TextureCopyView {
texture: &texture, texture: &texture,
@ -98,9 +120,16 @@ impl Texture {
mipmap_filter: wgpu::FilterMode::Nearest, mipmap_filter: wgpu::FilterMode::Nearest,
lod_min_clamp: -100.0, lod_min_clamp: -100.0,
lod_max_clamp: 100.0, lod_max_clamp: 100.0,
compare_function: wgpu::CompareFunction::Always, compare: wgpu::CompareFunction::Always,
}); });
Ok((Self { texture, view, sampler }, cmd_buffer)) Ok((
Self {
texture,
view,
sampler,
},
cmd_buffer,
))
} }
} }

View File

@ -7,15 +7,18 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
image = "0.22.4" image = "0.23"
winit = "0.20.0" winit = "0.22"
glsl-to-spirv = "0.1.7" glsl-to-spirv = "0.1"
cgmath = "0.17.0" cgmath = "0.17"
failure = "0.1" failure = "0.1"
tobj = "0.1" tobj = "1"
bytemuck = "1.2"
futures = "0.3"
# wgpu = "0.5"
wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git" }
wgpu = "0.4.0"
# wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git" }
# zerocopy = "0.2.8" # zerocopy = "0.2.8"
[[bin]] [[bin]]

View File

@ -1,16 +1,14 @@
use cgmath::prelude::*;
use winit::{ use winit::{
event::*, event::*,
event_loop::{EventLoop, ControlFlow}, event_loop::{ControlFlow, EventLoop},
window::{Window, WindowBuilder}, window::Window,
}; };
use cgmath::prelude::*;
mod texture;
mod model; mod model;
mod texture;
use model::{DrawLight, DrawModel, Vertex};
use model::{DrawModel, DrawLight, Vertex};
#[cfg_attr(rustfmt, rustfmt_skip)] #[cfg_attr(rustfmt, rustfmt_skip)]
pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new( pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
@ -61,10 +59,12 @@ impl Uniforms {
// the easiest way to convert to Vector4. We're using Vector4 because of // the easiest way to convert to Vector4. We're using Vector4 because of
// the uniforms 16 byte spacing requirement // the uniforms 16 byte spacing requirement
self.view_position = camera.eye.to_homogeneous(); self.view_position = camera.eye.to_homogeneous();
self.view_proj = OPENGL_TO_WGPU_MATRIX * camera.build_view_projection_matrix(); // self.view_proj = OPENGL_TO_WGPU_MATRIX * camera.build_view_projection_matrix();
self.view_proj = camera.build_view_projection_matrix();
} }
} }
unsafe impl bytemuck::Zeroable for Uniforms {}
unsafe impl bytemuck::Pod for Uniforms {}
struct CameraController { struct CameraController {
speed: f32, speed: f32,
is_up_pressed: bool, is_up_pressed: bool,
@ -91,11 +91,12 @@ impl CameraController {
fn process_events(&mut self, event: &WindowEvent) -> bool { fn process_events(&mut self, event: &WindowEvent) -> bool {
match event { match event {
WindowEvent::KeyboardInput { WindowEvent::KeyboardInput {
input: KeyboardInput { input:
state, KeyboardInput {
virtual_keycode: Some(keycode), state,
.. virtual_keycode: Some(keycode),
}, ..
},
.. ..
} => { } => {
let is_pressed = *state == ElementState::Pressed; let is_pressed = *state == ElementState::Pressed;
@ -172,47 +173,27 @@ struct Light {
color: cgmath::Vector3<f32>, color: cgmath::Vector3<f32>,
} }
unsafe impl bytemuck::Zeroable for Light {}
unsafe impl bytemuck::Pod for Light {}
struct State { struct State {
surface: wgpu::Surface,
device: wgpu::Device,
queue: wgpu::Queue,
sc_desc: wgpu::SwapChainDescriptor,
swap_chain: wgpu::SwapChain,
render_pipeline: wgpu::RenderPipeline, render_pipeline: wgpu::RenderPipeline,
obj_model: model::Model, obj_model: model::Model,
camera: Camera, camera: Camera,
camera_controller: CameraController, camera_controller: CameraController,
uniforms: Uniforms, uniforms: Uniforms,
uniform_buffer: wgpu::Buffer, uniform_buffer: wgpu::Buffer,
uniform_bind_group: wgpu::BindGroup, uniform_bind_group: wgpu::BindGroup,
size: winit::dpi::PhysicalSize<u32>,
instances: Vec<Instance>, instances: Vec<Instance>,
instance_buffer: wgpu::Buffer, instance_buffer: wgpu::Buffer,
depth_texture: wgpu::Texture, depth_texture: wgpu::Texture,
depth_texture_view: wgpu::TextureView, depth_texture_view: wgpu::TextureView,
light: Light, light: Light,
light_buffer: wgpu::Buffer, light_buffer: wgpu::Buffer,
light_bind_group: wgpu::BindGroup, light_bind_group: wgpu::BindGroup,
light_render_pipeline: wgpu::RenderPipeline, light_render_pipeline: wgpu::RenderPipeline,
} }
const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
fn create_depth_texture(device: &wgpu::Device, sc_desc: &wgpu::SwapChainDescriptor) -> wgpu::Texture {
let desc = wgpu::TextureDescriptor {
format: DEPTH_FORMAT,
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
..sc_desc.to_texture_desc()
};
device.create_texture(&desc)
}
fn create_render_pipeline( fn create_render_pipeline(
device: &wgpu::Device, device: &wgpu::Device,
layout: &wgpu::PipelineLayout, layout: &wgpu::PipelineLayout,
@ -247,69 +228,56 @@ fn create_render_pipeline(
depth_bias_clamp: 0.0, depth_bias_clamp: 0.0,
}), }),
primitive_topology: wgpu::PrimitiveTopology::TriangleList, primitive_topology: wgpu::PrimitiveTopology::TriangleList,
color_states: &[ color_states: &[wgpu::ColorStateDescriptor {
wgpu::ColorStateDescriptor { format: color_format,
format: color_format, color_blend: wgpu::BlendDescriptor::REPLACE,
color_blend: wgpu::BlendDescriptor::REPLACE, alpha_blend: wgpu::BlendDescriptor::REPLACE,
alpha_blend: wgpu::BlendDescriptor::REPLACE, write_mask: wgpu::ColorWrite::ALL,
write_mask: wgpu::ColorWrite::ALL, }],
}, depth_stencil_state: depth_format.map(|format| wgpu::DepthStencilStateDescriptor {
], format,
depth_stencil_state: depth_format.map(|format| { depth_write_enabled: true,
wgpu::DepthStencilStateDescriptor { depth_compare: wgpu::CompareFunction::Less,
format, stencil_front: wgpu::StencilStateFaceDescriptor::IGNORE,
depth_write_enabled: true, stencil_back: wgpu::StencilStateFaceDescriptor::IGNORE,
depth_compare: wgpu::CompareFunction::Less, stencil_read_mask: 0,
stencil_front: wgpu::StencilStateFaceDescriptor::IGNORE, stencil_write_mask: 0,
stencil_back: wgpu::StencilStateFaceDescriptor::IGNORE,
stencil_read_mask: 0,
stencil_write_mask: 0,
}
}), }),
index_format: wgpu::IndexFormat::Uint32,
vertex_buffers: vertex_descs,
sample_count: 1, sample_count: 1,
sample_mask: !0, sample_mask: !0,
alpha_to_coverage_enabled: false, alpha_to_coverage_enabled: false,
vertex_state: wgpu::VertexStateDescriptor {
index_format: wgpu::IndexFormat::Uint32,
vertex_buffers: vertex_descs,
},
}) })
} }
impl State { impl State {
fn new(window: &Window) -> Self { fn new(
let size = window.inner_size(); sc_desc: &wgpu::SwapChainDescriptor,
device: &wgpu::Device,
let surface = wgpu::Surface::create(window); ) -> (Self, Option<Vec<wgpu::CommandBuffer>>) {
let texture_bind_group_layout =
let adapter = wgpu::Adapter::request(&Default::default()).unwrap(); device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
bindings: &[
let (device, mut queue) = adapter.request_device(&Default::default()); wgpu::BindGroupLayoutEntry {
binding: 0,
let sc_desc = wgpu::SwapChainDescriptor { visibility: wgpu::ShaderStage::FRAGMENT,
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, ty: wgpu::BindingType::SampledTexture {
format: wgpu::TextureFormat::Bgra8UnormSrgb, multisampled: false,
width: size.width, component_type: wgpu::TextureComponentType::Float,
height: size.height, dimension: wgpu::TextureViewDimension::D2,
present_mode: wgpu::PresentMode::Vsync, },
};
let swap_chain = device.create_swap_chain(&surface, &sc_desc);
let texture_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
bindings: &[
wgpu::BindGroupLayoutBinding {
binding: 0,
visibility: wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::SampledTexture {
multisampled: false,
dimension: wgpu::TextureViewDimension::D2,
}, },
}, wgpu::BindGroupLayoutEntry {
wgpu::BindGroupLayoutBinding { binding: 1,
binding: 1, visibility: wgpu::ShaderStage::FRAGMENT,
visibility: wgpu::ShaderStage::FRAGMENT, ty: wgpu::BindingType::Sampler { comparison: false },
ty: wgpu::BindingType::Sampler, },
}, ],
], label: None,
}); });
let camera = Camera { let camera = Camera {
eye: (0.0, 5.0, -10.0).into(), eye: (0.0, 5.0, -10.0).into(),
@ -320,61 +288,74 @@ impl State {
znear: 0.1, znear: 0.1,
zfar: 100.0, zfar: 100.0,
}; };
let camera_controller = CameraController::new(0.2); let camera_controller = CameraController::new(0.2);
let mut uniforms = Uniforms::new(); let mut uniforms = Uniforms::new();
uniforms.update_view_proj(&camera); uniforms.update_view_proj(&camera);
let uniform_buffer = device let uniform_buffer = device.create_buffer_with_data(
.create_buffer_mapped(1, wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST) bytemuck::cast_slice(&[uniforms]),
.fill_from_slice(&[uniforms]); wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
);
const SPACE_BETWEEN: f32 = 3.0; const SPACE_BETWEEN: f32 = 3.0;
let instances = (0..NUM_INSTANCES_PER_ROW).flat_map(|z| { let instances = (0..NUM_INSTANCES_PER_ROW)
(0..NUM_INSTANCES_PER_ROW).map(move |x| { .flat_map(|z| {
let x = SPACE_BETWEEN * (x as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0); (0..NUM_INSTANCES_PER_ROW).map(move |x| {
let z = SPACE_BETWEEN * (z as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0); let x = SPACE_BETWEEN * (x as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0);
let z = SPACE_BETWEEN * (z as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0);
let position = cgmath::Vector3 { x, y: 0.0, z }; let position = cgmath::Vector3 { x, y: 0.0, z };
let rotation = if position.is_zero() { let rotation = if position.is_zero() {
cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_z(), cgmath::Deg(0.0)) cgmath::Quaternion::from_axis_angle(
} else { cgmath::Vector3::unit_z(),
cgmath::Quaternion::from_axis_angle(position.clone().normalize(), cgmath::Deg(45.0)) cgmath::Deg(0.0),
}; )
} else {
cgmath::Quaternion::from_axis_angle(
position.clone().normalize(),
cgmath::Deg(45.0),
)
};
Instance { Instance { position, rotation }
position, rotation, })
}
}) })
}).collect::<Vec<_>>(); .collect::<Vec<_>>();
let instance_data = instances.iter().map(Instance::to_matrix).collect::<Vec<_>>(); let instance_data = instances
let instance_buffer_size = instance_data.len() * std::mem::size_of::<cgmath::Matrix4<f32>>(); .iter()
let instance_buffer = device .map(Instance::to_matrix)
.create_buffer_mapped(instance_data.len(), wgpu::BufferUsage::STORAGE_READ) .collect::<Vec<_>>();
.fill_from_slice(&instance_data);
let uniform_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { let instance_buffer_size =
bindings: &[ instance_data.len() * std::mem::size_of::<cgmath::Matrix4<f32>>();
wgpu::BindGroupLayoutBinding { let instance_buffer = device.create_buffer_with_data(
binding: 0, matrix4f_cast_slice(&[instance_data]),
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, wgpu::BufferUsage::STORAGE_READ,
ty: wgpu::BindingType::UniformBuffer { );
dynamic: false,
let uniform_bind_group_layout =
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
bindings: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
}, },
}, wgpu::BindGroupLayoutEntry {
wgpu::BindGroupLayoutBinding { binding: 1,
binding: 1, visibility: wgpu::ShaderStage::VERTEX,
visibility: wgpu::ShaderStage::VERTEX, ty: wgpu::BindingType::StorageBuffer {
ty: wgpu::BindingType::StorageBuffer { dynamic: false,
dynamic: false, readonly: true,
readonly: true, },
} },
} ],
] label: None,
}); });
let uniform_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { let uniform_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &uniform_bind_group_layout, layout: &uniform_bind_group_layout,
@ -384,20 +365,21 @@ impl State {
resource: wgpu::BindingResource::Buffer { resource: wgpu::BindingResource::Buffer {
buffer: &uniform_buffer, buffer: &uniform_buffer,
range: 0..std::mem::size_of_val(&uniforms) as wgpu::BufferAddress, range: 0..std::mem::size_of_val(&uniforms) as wgpu::BufferAddress,
} },
}, },
wgpu::Binding { wgpu::Binding {
binding: 1, binding: 1,
resource: wgpu::BindingResource::Buffer { resource: wgpu::BindingResource::Buffer {
buffer: &instance_buffer, buffer: &instance_buffer,
range: 0..instance_buffer_size as wgpu::BufferAddress, range: 0..instance_buffer_size as wgpu::BufferAddress,
} },
} },
], ],
label: None,
}); });
let (obj_model, cmds) = model::Model::load(&device, &texture_bind_group_layout, "code/beginner/tutorial9-models/src/res/cube.obj").unwrap(); let (obj_model, cmds) =
queue.submit(&cmds); model::Model::load(&device, &texture_bind_group_layout, "code/intermediate/tutorial10-lighting/src/res/cube.obj").unwrap();
let light = Light { let light = Light {
position: (2.0, 2.0, 2.0).into(), position: (2.0, 2.0, 2.0).into(),
@ -405,47 +387,44 @@ impl State {
color: (1.0, 1.0, 1.0).into(), color: (1.0, 1.0, 1.0).into(),
}; };
let light_buffer = device let light_buffer = device.create_buffer_with_data(
// We'll want to update our lights position, so we use COPY_DST bytemuck::cast_slice(&[light]),
.create_buffer_mapped(1, wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST) wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
.fill_from_slice(&[light]); );
let light_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { let light_bind_group_layout =
bindings: &[ device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
wgpu::BindGroupLayoutBinding { bindings: &[wgpu::BindGroupLayoutEntry {
binding: 0, binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::UniformBuffer { ty: wgpu::BindingType::UniformBuffer { dynamic: false },
dynamic: false }],
}, label: None,
} });
],
});
let light_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { let light_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &light_bind_group_layout, layout: &light_bind_group_layout,
bindings: &[ bindings: &[wgpu::Binding {
wgpu::Binding { binding: 0,
binding: 0, resource: wgpu::BindingResource::Buffer {
resource: wgpu::BindingResource::Buffer { buffer: &light_buffer,
buffer: &light_buffer, range: 0..std::mem::size_of_val(&light) as wgpu::BufferAddress,
range: 0..std::mem::size_of_val(&light) as wgpu::BufferAddress, },
} }],
} label: None,
],
}); });
let depth_texture = create_depth_texture(&device, &sc_desc); let depth_texture = texture::Texture::create_depth_texture(&device, &sc_desc).texture;
let depth_texture_view = depth_texture.create_default_view(); let depth_texture_view = depth_texture.create_default_view();
let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { let render_pipeline_layout =
bind_group_layouts: &[ device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
&texture_bind_group_layout, bind_group_layouts: &[
&uniform_bind_group_layout, &texture_bind_group_layout,
&light_bind_group_layout, &uniform_bind_group_layout,
], &light_bind_group_layout,
}); ],
});
let render_pipeline = { let render_pipeline = {
let vs_src = include_str!("shader.vert"); let vs_src = include_str!("shader.vert");
@ -455,19 +434,16 @@ impl State {
&device, &device,
&render_pipeline_layout, &render_pipeline_layout,
sc_desc.format, sc_desc.format,
Some(DEPTH_FORMAT), Some(texture::DEPTH_FORMAT),
&[model::ModelVertex::desc()], &[model::ModelVertex::desc()],
vs_src, vs_src,
fs_src fs_src,
) )
}; };
let light_render_pipeline = { let light_render_pipeline = {
let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
bind_group_layouts: &[ bind_group_layouts: &[&uniform_bind_group_layout, &light_bind_group_layout],
&uniform_bind_group_layout,
&light_bind_group_layout,
]
}); });
let vs_src = include_str!("light.vert"); let vs_src = include_str!("light.vert");
@ -477,19 +453,14 @@ impl State {
&device, &device,
&layout, &layout,
sc_desc.format, sc_desc.format,
Some(DEPTH_FORMAT), Some(texture::DEPTH_FORMAT),
&[model::ModelVertex::desc()], &[model::ModelVertex::desc()],
vs_src, vs_src,
fs_src, fs_src,
) )
}; };
Self { let state = Self {
surface,
device,
queue,
sc_desc,
swap_chain,
render_pipeline, render_pipeline,
obj_model, obj_model,
camera, camera,
@ -497,7 +468,6 @@ impl State {
uniform_buffer, uniform_buffer,
uniform_bind_group, uniform_bind_group,
uniforms, uniforms,
size,
instances, instances,
instance_buffer, instance_buffer,
depth_texture, depth_texture,
@ -506,75 +476,85 @@ impl State {
light_buffer, light_buffer,
light_bind_group, light_bind_group,
light_render_pipeline, light_render_pipeline,
} };
(state, Some(cmds))
} }
fn resize(
&mut self,
fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) { sc_desc: &wgpu::SwapChainDescriptor,
self.size = new_size; device: &wgpu::Device,
self.sc_desc.width = new_size.width; ) -> Option<wgpu::CommandBuffer> {
self.sc_desc.height = new_size.height; self.depth_texture = texture::Texture::create_depth_texture(device, sc_desc).texture;
self.swap_chain = self.device.create_swap_chain(&self.surface, &self.sc_desc);
self.depth_texture = create_depth_texture(&self.device, &self.sc_desc);
self.depth_texture_view = self.depth_texture.create_default_view(); self.depth_texture_view = self.depth_texture.create_default_view();
self.camera.aspect = sc_desc.width as f32 / sc_desc.height as f32;
self.camera.aspect = self.sc_desc.width as f32 / self.sc_desc.height as f32; None
} }
fn input(&mut self, event: &WindowEvent) -> bool { fn input(&mut self, event: &WindowEvent) -> bool {
self.camera_controller.process_events(event) self.camera_controller.process_events(event)
} }
fn update(&mut self, device: &wgpu::Device) -> Option<wgpu::CommandBuffer> {
fn update(&mut self) {
self.camera_controller.update_camera(&mut self.camera); self.camera_controller.update_camera(&mut self.camera);
self.uniforms.update_view_proj(&self.camera); self.uniforms.update_view_proj(&self.camera);
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { let mut encoder =
todo: 0, device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
});
let staging_buffer = self.device let staging_buffer = device.create_buffer_with_data(
.create_buffer_mapped(1, wgpu::BufferUsage::COPY_SRC) bytemuck::cast_slice(&[self.uniforms]),
.fill_from_slice(&[self.uniforms]); wgpu::BufferUsage::COPY_SRC,
);
encoder.copy_buffer_to_buffer(&staging_buffer, 0, &self.uniform_buffer, 0, std::mem::size_of::<Uniforms>() as wgpu::BufferAddress); encoder.copy_buffer_to_buffer(
&staging_buffer,
0,
&self.uniform_buffer,
0,
std::mem::size_of::<Uniforms>() as wgpu::BufferAddress,
);
// Update the light // Update the light
let old_position = self.light.position; let old_position = self.light.position;
self.light.position = cgmath::Quaternion::from_axis_angle((0.0, 1.0, 0.0).into(), cgmath::Deg(1.0)) * old_position; self.light.position =
cgmath::Quaternion::from_axis_angle((0.0, 1.0, 0.0).into(), cgmath::Deg(1.0))
* old_position;
let staging_buffer = self.device let staging_buffer = device.create_buffer_with_data(
.create_buffer_mapped(1, wgpu::BufferUsage::COPY_SRC) bytemuck::cast_slice(&[self.light]),
.fill_from_slice(&[self.light]); wgpu::BufferUsage::COPY_SRC,
encoder.copy_buffer_to_buffer(&staging_buffer, 0, &self.light_buffer, 0, std::mem::size_of::<Light>() as wgpu::BufferAddress); );
encoder.copy_buffer_to_buffer(
&staging_buffer,
0,
&self.light_buffer,
0,
std::mem::size_of::<Light>() as wgpu::BufferAddress,
);
self.queue.submit(&[encoder.finish()]); Some(encoder.finish())
} }
fn render(
fn render(&mut self) { &mut self,
let frame = self.swap_chain.get_next_texture(); frame: &wgpu::SwapChainOutput,
device: &wgpu::Device,
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { ) -> wgpu::CommandBuffer {
todo: 0, let mut encoder =
}); device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
{ {
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[ color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
wgpu::RenderPassColorAttachmentDescriptor { attachment: &frame.view,
attachment: &frame.view, resolve_target: None,
resolve_target: None, load_op: wgpu::LoadOp::Clear,
load_op: wgpu::LoadOp::Clear, store_op: wgpu::StoreOp::Store,
store_op: wgpu::StoreOp::Store, clear_color: wgpu::Color {
clear_color: wgpu::Color { r: 0.1,
r: 0.1, g: 0.2,
g: 0.2, b: 0.3,
b: 0.3, a: 1.0,
a: 1.0, },
}, }],
}
],
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor { depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachmentDescriptor {
attachment: &self.depth_texture_view, attachment: &self.depth_texture_view,
depth_load_op: wgpu::LoadOp::Clear, depth_load_op: wgpu::LoadOp::Clear,
@ -585,42 +565,74 @@ impl State {
clear_stencil: 0, clear_stencil: 0,
}), }),
}); });
render_pass.set_pipeline(&self.light_render_pipeline); render_pass.set_pipeline(&self.light_render_pipeline);
render_pass.draw_light_model(&self.obj_model, &self.uniform_bind_group, &self.light_bind_group); render_pass.draw_light_model(
&self.obj_model,
&self.uniform_bind_group,
&self.light_bind_group,
);
render_pass.set_pipeline(&self.render_pipeline); render_pass.set_pipeline(&self.render_pipeline);
render_pass.draw_model_instanced(&self.obj_model, 0..self.instances.len() as u32, &self.uniform_bind_group, &self.light_bind_group); render_pass.draw_model_instanced(
&self.obj_model,
0..self.instances.len() as u32,
&self.uniform_bind_group,
&self.light_bind_group,
);
} }
encoder.finish()
self.queue.submit(&[
encoder.finish()
]);
} }
} }
fn main() { async fn run_async(event_loop: EventLoop<()>, window: Window) {
let event_loop = EventLoop::new(); let size = window.inner_size();
let window = WindowBuilder::new() let surface = wgpu::Surface::create(&window);
.build(&event_loop) let adapter = wgpu::Adapter::request(
.unwrap(); &wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::Default,
compatible_surface: Some(&surface),
},
wgpu::BackendBit::PRIMARY,
)
.await
.unwrap();
let (device, queue) = adapter
.request_device(&wgpu::DeviceDescriptor {
extensions: wgpu::Extensions {
anisotropic_filtering: false,
},
limits: wgpu::Limits::default(),
})
.await;
let mut sc_desc = wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
format: if cfg!(target_arch = "wasm32") {
wgpu::TextureFormat::Bgra8Unorm
} else {
wgpu::TextureFormat::Bgra8UnormSrgb
},
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Mailbox,
};
let mut swap_chain = device.create_swap_chain(&surface, &sc_desc);
let mut state = State::new(&window); let (mut state, init_cmds_buf) = State::new(&sc_desc, &device);
if let Some(cmds_buf) = init_cmds_buf {
queue.submit(&cmds_buf);
}
event_loop.run(move |event, _, control_flow| { event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll; *control_flow = ControlFlow::Poll;
match event { match event {
Event::MainEventsCleared => window.request_redraw(),
Event::WindowEvent { Event::WindowEvent {
ref event, ref event,
window_id, window_id,
} if window_id == window.id() => if !state.input(event) { } if window_id == window.id() => {
match event { if !state.input(event) {
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, match event {
WindowEvent::KeyboardInput { WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
input, WindowEvent::KeyboardInput { input, .. } => match input {
..
} => {
match input {
KeyboardInput { KeyboardInput {
state: ElementState::Pressed, state: ElementState::Pressed,
virtual_keycode: Some(VirtualKeyCode::Escape), virtual_keycode: Some(VirtualKeyCode::Escape),
@ -629,22 +641,56 @@ fn main() {
*control_flow = ControlFlow::Exit; *control_flow = ControlFlow::Exit;
} }
_ => {} _ => {}
},
WindowEvent::Resized(physical_size) => {
sc_desc.width = physical_size.width;
sc_desc.height = physical_size.height;
swap_chain = device.create_swap_chain(&surface, &sc_desc);
let cmd_buf = state.resize(&sc_desc, &device);
if let Some(cmd_buf) = cmd_buf {
queue.submit(&[cmd_buf]);
}
} }
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
sc_desc.width = new_inner_size.width;
sc_desc.height = new_inner_size.height;
swap_chain = device.create_swap_chain(&surface, &sc_desc);
let cmd_buf = state.resize(&sc_desc, &device);
if let Some(cmd_buf) = cmd_buf {
queue.submit(&[cmd_buf]);
}
}
_ => {}
} }
WindowEvent::Resized(physical_size) => {
state.resize(*physical_size);
}
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
state.resize(**new_inner_size);
}
_ => {},
} }
} }
Event::MainEventsCleared => { Event::RedrawRequested(_) => {
state.update(); if let Some(cmd_buf) = state.update(&device) {
state.render(); queue.submit(&[cmd_buf]);
}
let frame = swap_chain
.get_next_texture()
.expect("Timeout when acquiring next swap chain texture");
let command_buf = state.render(&frame, &device);
queue.submit(&[command_buf]);
} }
_ => {} _ => {}
} }
}); });
} }
fn main() {
let event_loop = EventLoop::new();
let title = "tutorial10-lighting";
let window = winit::window::WindowBuilder::new()
.with_title(title)
.build(&event_loop)
.unwrap();
futures::executor::block_on(run_async(event_loop, window));
}
#[inline]
pub fn matrix4f_cast_slice(a: &[Vec<cgmath::Matrix4<f32>>]) -> &[u8] {
let new_len = a[0].len() * std::mem::size_of::<cgmath::Matrix4<f32>>();
unsafe { core::slice::from_raw_parts(a[0].as_ptr() as *const u8, new_len) }
}

View File

@ -1,5 +1,5 @@
use std::path::Path;
use std::ops::Range; use std::ops::Range;
use std::path::Path;
use crate::texture; use crate::texture;
@ -14,6 +14,8 @@ pub struct ModelVertex {
tex_coords: [f32; 2], tex_coords: [f32; 2],
normal: [f32; 3], normal: [f32; 3],
} }
unsafe impl bytemuck::Zeroable for ModelVertex {}
unsafe impl bytemuck::Pod for ModelVertex {}
impl Vertex for ModelVertex { impl Vertex for ModelVertex {
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> { fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
@ -37,7 +39,7 @@ impl Vertex for ModelVertex {
shader_location: 2, shader_location: 2,
format: wgpu::VertexFormat::Float3, format: wgpu::VertexFormat::Float3,
}, },
] ],
} }
} }
} }
@ -61,9 +63,12 @@ pub struct Model {
pub materials: Vec<Material>, pub materials: Vec<Material>,
} }
impl Model { impl Model {
pub fn load<P: AsRef<Path>>(device: &wgpu::Device, layout: &wgpu::BindGroupLayout, path: P) -> Result<(Self, Vec<wgpu::CommandBuffer>), failure::Error> { pub fn load<P: AsRef<Path>>(
device: &wgpu::Device,
layout: &wgpu::BindGroupLayout,
path: P,
) -> Result<(Self, Vec<wgpu::CommandBuffer>), failure::Error> {
let (obj_models, obj_materials) = tobj::load_obj(path.as_ref())?; let (obj_models, obj_materials) = tobj::load_obj(path.as_ref())?;
// We're assuming that the texture files are stored with the obj file // We're assuming that the texture files are stored with the obj file
@ -75,7 +80,8 @@ impl Model {
let mut materials = Vec::new(); let mut materials = Vec::new();
for mat in obj_materials { for mat in obj_materials {
let diffuse_path = mat.diffuse_texture; let diffuse_path = mat.diffuse_texture;
let (diffuse_texture, cmds) = texture::Texture::load(&device, containing_folder.join(diffuse_path))?; let (diffuse_texture, cmds) =
texture::Texture::load(&device, containing_folder.join(diffuse_path))?;
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout, layout,
@ -88,7 +94,8 @@ impl Model {
binding: 1, binding: 1,
resource: wgpu::BindingResource::Sampler(&diffuse_texture.sampler), resource: wgpu::BindingResource::Sampler(&diffuse_texture.sampler),
}, },
] ],
label: None,
}); });
materials.push(Material { materials.push(Material {
@ -109,10 +116,7 @@ impl Model {
m.mesh.positions[i * 3 + 1], m.mesh.positions[i * 3 + 1],
m.mesh.positions[i * 3 + 2], m.mesh.positions[i * 3 + 2],
], ],
tex_coords: [ tex_coords: [m.mesh.texcoords[i * 2], m.mesh.texcoords[i * 2 + 1]],
m.mesh.texcoords[i * 2],
m.mesh.texcoords[i * 2 + 1],
],
normal: [ normal: [
m.mesh.normals[i * 3], m.mesh.normals[i * 3],
m.mesh.normals[i * 3 + 1], m.mesh.normals[i * 3 + 1],
@ -121,13 +125,15 @@ impl Model {
}); });
} }
let vertex_buffer = device let vertex_buffer = device.create_buffer_with_data(
.create_buffer_mapped(vertices.len(), wgpu::BufferUsage::VERTEX) bytemuck::cast_slice(&vertices),
.fill_from_slice(&vertices); wgpu::BufferUsage::VERTEX,
);
let index_buffer = device let index_buffer = device.create_buffer_with_data(
.create_buffer_mapped(m.mesh.indices.len(), wgpu::BufferUsage::INDEX) bytemuck::cast_slice(&m.mesh.indices),
.fill_from_slice(&m.mesh.indices); wgpu::BufferUsage::INDEX,
);
meshes.push(Mesh { meshes.push(Mesh {
name: m.name, name: m.name,
@ -138,37 +144,91 @@ impl Model {
}); });
} }
Ok((Self { meshes, materials, }, command_buffers)) Ok((Self { meshes, materials }, command_buffers))
} }
} }
pub trait DrawModel { pub trait DrawModel<'a, 'b>
fn draw_mesh(&mut self, mesh: &Mesh, material: &Material, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); where
fn draw_mesh_instanced(&mut self, mesh: &Mesh, material: &Material, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); 'b: 'a,
{
fn draw_mesh(
&mut self,
mesh: &'b Mesh,
material: &'b Material,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
);
fn draw_mesh_instanced(
&mut self,
mesh: &'b Mesh,
material: &'b Material,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
);
fn draw_model(&mut self, model: &Model, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); fn draw_model(
fn draw_model_instanced(&mut self, model: &Model, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); &mut self,
model: &'b Model,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
);
fn draw_model_instanced(
&mut self,
model: &'b Model,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
);
} }
impl<'a> DrawModel for wgpu::RenderPass<'a> { impl<'a, 'b> DrawModel<'a, 'b> for wgpu::RenderPass<'a>
fn draw_mesh(&mut self, mesh: &Mesh, material: &Material, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { where
'b: 'a,
{
fn draw_mesh(
&mut self,
mesh: &'b Mesh,
material: &'b Material,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
self.draw_mesh_instanced(mesh, material, 0..1, uniforms, light); self.draw_mesh_instanced(mesh, material, 0..1, uniforms, light);
} }
fn draw_mesh_instanced(&mut self, mesh: &Mesh, material: &Material, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { fn draw_mesh_instanced(
self.set_vertex_buffers(0, &[(&mesh.vertex_buffer, 0)]); &mut self,
self.set_index_buffer(&mesh.index_buffer, 0); mesh: &'b Mesh,
material: &'b Material,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
self.set_vertex_buffer(0, &mesh.vertex_buffer, 0, 0);
self.set_index_buffer(&mesh.index_buffer, 0, 0);
self.set_bind_group(0, &material.bind_group, &[]); self.set_bind_group(0, &material.bind_group, &[]);
self.set_bind_group(1, &uniforms, &[]); self.set_bind_group(1, &uniforms, &[]);
self.set_bind_group(2, &light, &[]); self.set_bind_group(2, &light, &[]);
self.draw_indexed(0..mesh.num_elements, 0, instances); self.draw_indexed(0..mesh.num_elements, 0, instances);
} }
fn draw_model(&mut self, model: &Model, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { fn draw_model(
&mut self,
model: &'b Model,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
self.draw_model_instanced(model, 0..1, uniforms, light); self.draw_model_instanced(model, 0..1, uniforms, light);
} }
fn draw_model_instanced(&mut self, model: &Model, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { fn draw_model_instanced(
&mut self,
model: &'b Model,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
for mesh in &model.meshes { for mesh in &model.meshes {
let material = &model.materials[mesh.material]; let material = &model.materials[mesh.material];
self.draw_mesh_instanced(mesh, material, instances.clone(), uniforms, light); self.draw_mesh_instanced(mesh, material, instances.clone(), uniforms, light);
@ -176,32 +236,82 @@ impl<'a> DrawModel for wgpu::RenderPass<'a> {
} }
} }
pub trait DrawLight { pub trait DrawLight<'a, 'b>
fn draw_light_mesh(&mut self, mesh: &Mesh, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); where
fn draw_light_mesh_instanced(&mut self, mesh: &Mesh, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); 'b: 'a,
{
fn draw_light_mesh(
&mut self,
mesh: &'b Mesh,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
);
fn draw_light_mesh_instanced(
&mut self,
mesh: &'b Mesh,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) where
'b: 'a;
fn draw_light_model(&mut self, model: &Model, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); fn draw_light_model(
fn draw_light_model_instanced(&mut self, model: &Model, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); &mut self,
model: &'b Model,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
);
fn draw_light_model_instanced(
&mut self,
model: &'b Model,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
);
} }
impl<'a, 'b> DrawLight<'a, 'b> for wgpu::RenderPass<'a>
impl<'a> DrawLight for wgpu::RenderPass<'a> { where
fn draw_light_mesh(&mut self, mesh: &Mesh, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { 'b: 'a,
{
fn draw_light_mesh(
&mut self,
mesh: &'b Mesh,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
self.draw_light_mesh_instanced(mesh, 0..1, uniforms, light); self.draw_light_mesh_instanced(mesh, 0..1, uniforms, light);
} }
fn draw_light_mesh_instanced(&mut self, mesh: &Mesh, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { fn draw_light_mesh_instanced(
self.set_vertex_buffers(0, &[(&mesh.vertex_buffer, 0)]); &mut self,
self.set_index_buffer(&mesh.index_buffer, 0); mesh: &'b Mesh,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
self.set_vertex_buffer(0, &mesh.vertex_buffer, 0, 0);
self.set_index_buffer(&mesh.index_buffer, 0, 0);
self.set_bind_group(0, uniforms, &[]); self.set_bind_group(0, uniforms, &[]);
self.set_bind_group(1, light, &[]); self.set_bind_group(1, light, &[]);
self.draw_indexed(0..mesh.num_elements, 0, instances); self.draw_indexed(0..mesh.num_elements, 0, instances);
} }
fn draw_light_model(&mut self, model: &Model, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { fn draw_light_model(
&mut self,
model: &'b Model,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
self.draw_light_model_instanced(model, 0..1, uniforms, light); self.draw_light_model_instanced(model, 0..1, uniforms, light);
} }
fn draw_light_model_instanced(&mut self, model: &Model, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { fn draw_light_model_instanced(
&mut self,
model: &'b Model,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
for mesh in &model.meshes { for mesh in &model.meshes {
self.draw_light_mesh_instanced(mesh, instances.clone(), uniforms, light); self.draw_light_mesh_instanced(mesh, instances.clone(), uniforms, light);
} }

View File

@ -10,5 +10,5 @@ Ke 0.000000 0.000000 0.000000
Ni 1.450000 Ni 1.450000
d 1.000000 d 1.000000
illum 2 illum 2
map_Bump /home/benjamin/Downloads/tuto-14-normal.png map_Bump cube-normal.png
map_Kd /home/benjamin/Downloads/tuto-14-diffuse.jpg map_Kd cube-diffuse.jpg

View File

@ -1,6 +1,7 @@
use image::GenericImageView; use image::GenericImageView;
use std::path::Path; use std::path::Path;
pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float;
pub struct Texture { pub struct Texture {
pub texture: wgpu::Texture, pub texture: wgpu::Texture,
@ -9,18 +10,30 @@ pub struct Texture {
} }
impl Texture { impl Texture {
pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth32Float; pub fn load<P: AsRef<Path>>(
device: &wgpu::Device,
pub fn load<P: AsRef<Path>>(device: &wgpu::Device, path: P) -> Result<(Self, wgpu::CommandBuffer), failure::Error> { path: P,
) -> Result<(Self, wgpu::CommandBuffer), failure::Error> {
let img = image::open(path)?; let img = image::open(path)?;
Self::from_image(device, &img) Self::from_image(device, &img)
} }
pub fn create_depth_texture(device: &wgpu::Device, sc_desc: &wgpu::SwapChainDescriptor) -> Self { pub fn create_depth_texture(
device: &wgpu::Device,
sc_desc: &wgpu::SwapChainDescriptor,
) -> Self {
let desc = wgpu::TextureDescriptor { let desc = wgpu::TextureDescriptor {
format: Self::DEPTH_FORMAT, label: None,
size: wgpu::Extent3d {
width: sc_desc.width,
height: sc_desc.height,
depth: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: DEPTH_FORMAT,
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
..sc_desc.to_texture_desc()
}; };
let texture = device.create_texture(&desc); let texture = device.create_texture(&desc);
@ -34,16 +47,32 @@ impl Texture {
mipmap_filter: wgpu::FilterMode::Nearest, mipmap_filter: wgpu::FilterMode::Nearest,
lod_min_clamp: -100.0, lod_min_clamp: -100.0,
lod_max_clamp: 100.0, lod_max_clamp: 100.0,
compare_function: wgpu::CompareFunction::Always, compare: wgpu::CompareFunction::Always,
}); });
Self { texture, view, sampler } Self {
texture,
view,
sampler,
}
} }
pub fn create_render_target(device: &wgpu::Device, sc_desc: &wgpu::SwapChainDescriptor) -> Self { pub fn create_render_target(
device: &wgpu::Device,
sc_desc: &wgpu::SwapChainDescriptor,
) -> Self {
let desc = wgpu::TextureDescriptor { let desc = wgpu::TextureDescriptor {
label: None,
size: wgpu::Extent3d {
width: sc_desc.width,
height: sc_desc.height,
depth: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: sc_desc.format,
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT | wgpu::TextureUsage::SAMPLED, usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT | wgpu::TextureUsage::SAMPLED,
..sc_desc.to_texture_desc()
}; };
let texture = device.create_texture(&desc); let texture = device.create_texture(&desc);
@ -57,18 +86,28 @@ impl Texture {
mipmap_filter: wgpu::FilterMode::Nearest, mipmap_filter: wgpu::FilterMode::Nearest,
lod_min_clamp: -100.0, lod_min_clamp: -100.0,
lod_max_clamp: 100.0, lod_max_clamp: 100.0,
compare_function: wgpu::CompareFunction::Always, compare: wgpu::CompareFunction::Always,
}); });
Self { texture, view, sampler } Self {
texture,
view,
sampler,
}
} }
pub fn from_bytes(device: &wgpu::Device, bytes: &[u8]) -> Result<(Self, wgpu::CommandBuffer), failure::Error> { pub fn from_bytes(
device: &wgpu::Device,
bytes: &[u8],
) -> Result<(Self, wgpu::CommandBuffer), failure::Error> {
let img = image::load_from_memory(bytes)?; let img = image::load_from_memory(bytes)?;
Self::from_image(device, &img) Self::from_image(device, &img)
} }
pub fn from_image(device: &wgpu::Device, img: &image::DynamicImage) -> Result<(Self, wgpu::CommandBuffer), failure::Error> { pub fn from_image(
device: &wgpu::Device,
img: &image::DynamicImage,
) -> Result<(Self, wgpu::CommandBuffer), failure::Error> {
let rgba = img.to_rgba(); let rgba = img.to_rgba();
let dimensions = img.dimensions(); let dimensions = img.dimensions();
@ -78,8 +117,8 @@ impl Texture {
depth: 1, depth: 1,
}; };
let texture = device.create_texture(&wgpu::TextureDescriptor { let texture = device.create_texture(&wgpu::TextureDescriptor {
label: None,
size, size,
array_layer_count: 1,
mip_level_count: 1, mip_level_count: 1,
sample_count: 1, sample_count: 1,
dimension: wgpu::TextureDimension::D2, dimension: wgpu::TextureDimension::D2,
@ -88,8 +127,7 @@ impl Texture {
}); });
let buffer = device let buffer = device
.create_buffer_mapped(rgba.len(), wgpu::BufferUsage::COPY_SRC) .create_buffer_with_data(bytemuck::cast_slice(&rgba), wgpu::BufferUsage::COPY_SRC);
.fill_from_slice(&rgba);
let mut encoder = device.create_command_encoder(&Default::default()); let mut encoder = device.create_command_encoder(&Default::default());
@ -97,8 +135,8 @@ impl Texture {
wgpu::BufferCopyView { wgpu::BufferCopyView {
buffer: &buffer, buffer: &buffer,
offset: 0, offset: 0,
row_pitch: 4 * dimensions.0, bytes_per_row: 4 * dimensions.0,
image_height: dimensions.1, rows_per_image: dimensions.1,
}, },
wgpu::TextureCopyView { wgpu::TextureCopyView {
texture: &texture, texture: &texture,
@ -121,9 +159,16 @@ impl Texture {
mipmap_filter: wgpu::FilterMode::Nearest, mipmap_filter: wgpu::FilterMode::Nearest,
lod_min_clamp: -100.0, lod_min_clamp: -100.0,
lod_max_clamp: 100.0, lod_max_clamp: 100.0,
compare_function: wgpu::CompareFunction::Always, compare: wgpu::CompareFunction::Always,
}); });
Ok((Self { texture, view, sampler }, cmd_buffer)) Ok((
Self {
texture,
view,
sampler,
},
cmd_buffer,
))
} }
} }

View File

@ -65,9 +65,10 @@ This is basically the same as the original `VertexBufferDescriptor`, but we adde
```rust ```rust
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
// ... // ...
vertex_buffers: &[ vertex_state: wgpu::VertexStateDescriptor {
model::ModelVertex::desc(), index_format: wgpu::IndexFormat::Uint16,
], vertex_buffers: &[model::ModelVertex::desc()],
},
// ... // ...
}); });
``` ```
@ -133,7 +134,11 @@ With all that out of the way, we can get to loading our model.
```rust ```rust
impl Model { impl Model {
pub fn load<P: AsRef<Path>>(device: &wgpu::Device, path: P) -> Result<(Self, Vec<wgpu::CommandBuffer>), failure::Error> { pub fn load<P: AsRef<Path>>(
device: &wgpu::Device,
layout: &wgpu::BindGroupLayout,
path: P,
) -> Result<(Self, Vec<wgpu::CommandBuffer>), failure::Error> {
let (obj_models, obj_materials) = tobj::load_obj(path.as_ref())?; let (obj_models, obj_materials) = tobj::load_obj(path.as_ref())?;
// We're assuming that the texture files are stored with the obj file // We're assuming that the texture files are stored with the obj file
@ -145,7 +150,24 @@ impl Model {
let mut materials = Vec::new(); let mut materials = Vec::new();
for mat in obj_materials { for mat in obj_materials {
let diffuse_path = mat.diffuse_texture; let diffuse_path = mat.diffuse_texture;
let (diffuse_texture, cmds) = texture::Texture::load(&device, containing_folder.join(diffuse_path))?; let (diffuse_texture, cmds) =
texture::Texture::load(&device, containing_folder.join(diffuse_path))?;
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout,
bindings: &[
wgpu::Binding {
binding: 0,
resource: wgpu::BindingResource::TextureView(&diffuse_texture.view),
},
wgpu::Binding {
binding: 1,
resource: wgpu::BindingResource::Sampler(&diffuse_texture.sampler),
},
],
label: None,
});
materials.push(Material { materials.push(Material {
name: mat.name, name: mat.name,
diffuse_texture, diffuse_texture,
@ -163,10 +185,7 @@ impl Model {
m.mesh.positions[i * 3 + 1], m.mesh.positions[i * 3 + 1],
m.mesh.positions[i * 3 + 2], m.mesh.positions[i * 3 + 2],
], ],
tex_coords: [ tex_coords: [m.mesh.texcoords[i * 2], m.mesh.texcoords[i * 2 + 1]],
m.mesh.texcoords[i * 2],
m.mesh.texcoords[i * 2 + 1],
],
normal: [ normal: [
m.mesh.normals[i * 3], m.mesh.normals[i * 3],
m.mesh.normals[i * 3 + 1], m.mesh.normals[i * 3 + 1],
@ -175,13 +194,14 @@ impl Model {
}); });
} }
let vertex_buffer = device let vertex_buffer = device.create_buffer_with_data(
.create_buffer_mapped(vertices.len(), wgpu::BufferUsage::VERTEX) bytemuck::cast_slice(&vertices),
.fill_from_slice(&vertices); wgpu::BufferUsage::VERTEX,
);
let index_buffer = device let index_buffer = device.create_buffer_with_data(
.create_buffer_mapped(m.mesh.indices.len(), wgpu::BufferUsage::INDEX) bytemuck::cast_slice(&m.mesh.indices),
.fill_from_slice(&m.mesh.indices); wgpu::BufferUsage::INDEX,
);
meshes.push(Mesh { meshes.push(Mesh {
name: m.name, name: m.name,
@ -192,7 +212,7 @@ impl Model {
}); });
} }
Ok((Self { meshes, materials, }, command_buffers)) Ok((Self { meshes, materials }, command_buffers))
} }
} }
``` ```
@ -202,8 +222,10 @@ Make sure that you change the `IndexFormat` that the `RenderPipeline` uses from
```rust ```rust
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
// ... // ...
index_format: wgpu::IndexFormat::Uint32, vertex_state: wgpu::VertexStateDescriptor {
// ... index_format: wgpu::IndexFormat::Uint32,
vertex_buffers: &[model::ModelVertex::desc()],
}, // ...
}); });
``` ```
@ -212,19 +234,32 @@ let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescrip
Before we can draw the model, we need to be able to draw an individual mesh. Let's create a trait called `DrawModel`, and implement it for `RenderPass`. Before we can draw the model, we need to be able to draw an individual mesh. Let's create a trait called `DrawModel`, and implement it for `RenderPass`.
```rust ```rust
pub trait DrawModel { pub trait DrawModel<'a, 'b>
fn draw_mesh(&mut self, mesh: &Mesh); where
fn draw_mesh_instanced(&mut self, mesh: &Mesh, instances: Range<u32>); 'b: 'a,
{
fn draw_mesh(&mut self, mesh: &'b Mesh);
fn draw_mesh_instanced(
&mut self,
mesh: &'b Mesh,
instances: Range<u32>,
);
} }
impl<'a, 'b> DrawModel<'a, 'b> for wgpu::RenderPass<'a>
impl<'a> DrawModel for wgpu::RenderPass<'a> { where
fn draw_mesh(&mut self, mesh: &Mesh) { 'b: 'a,
{
fn draw_mesh(&mut self, mesh: &'b Mesh) {
self.draw_mesh_instanced(mesh, 0..1); self.draw_mesh_instanced(mesh, 0..1);
} }
fn draw_mesh_instanced(&mut self, mesh: &Mesh, instances: Range<u32>) { fn draw_mesh_instanced(
self.set_vertex_buffers(0, &[(&mesh.vertex_buffer, 0)]); &mut self,
self.set_index_buffer(&mesh.index_buffer, 0); mesh: &'b Mesh,
instances: Range<u32>,
){
self.set_vertex_buffer(0, &mesh.vertex_buffer, 0, 0);
self.set_index_buffer(&mesh.index_buffer, 0, 0);
self.draw_indexed(0..mesh.num_elements, 0, instances); self.draw_indexed(0..mesh.num_elements, 0, instances);
} }
} }
@ -246,7 +281,6 @@ Before that though we need to actually load the model and save it to `State`. Pu
```rust ```rust
let (obj_model, cmds) = model::Model::load(&device, "code/beginner/tutorial9-models/src/res/cube.obj").unwrap(); let (obj_model, cmds) = model::Model::load(&device, "code/beginner/tutorial9-models/src/res/cube.obj").unwrap();
queue.submit(&cmds);
``` ```
The path to the obj will be different for you, so keep that in mind. The path to the obj will be different for you, so keep that in mind.
@ -299,22 +333,39 @@ pub struct Material {
We're going to add a material parameter to `DrawModel`. We're going to add a material parameter to `DrawModel`.
```rust ```rust
pub trait DrawModel { pub trait DrawModel<'a, 'b>
fn draw_mesh(&mut self, mesh: &Mesh, material: &Material, uniforms: &wgpu::BindGroup); where
fn draw_mesh_instanced(&mut self, mesh: &Mesh, material: &Material, instances: Range<u32>, uniforms: &wgpu::BindGroup); 'b: 'a,
{
fn draw_mesh(&mut self, mesh: &'b Mesh, material: &'b Material, uniforms: &'b wgpu::BindGroup);
fn draw_mesh_instanced(
&mut self,
mesh: &'b Mesh,
material: &'b Material,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
);
} }
impl<'a> DrawModel for wgpu::RenderPass<'a> { impl<'a, 'b> DrawModel<'a, 'b> for wgpu::RenderPass<'a>
fn draw_mesh(&mut self, mesh: &Mesh, material: &Material, uniforms: &wgpu::BindGroup) { where
'b: 'a,
{
fn draw_mesh(&mut self, mesh: &'b Mesh, material: &'b Material, uniforms: &'b wgpu::BindGroup) {
self.draw_mesh_instanced(mesh, material, 0..1, uniforms); self.draw_mesh_instanced(mesh, material, 0..1, uniforms);
} }
fn draw_mesh_instanced(&mut self, mesh: &Mesh, material: &Material, instances: Range<u32>, uniforms: &wgpu::BindGroup) { fn draw_mesh_instanced(
self.set_vertex_buffers(0, &[(&mesh.vertex_buffer, 0)]); &mut self,
self.set_index_buffer(&mesh.index_buffer, 0); mesh: &'b Mesh,
material: &'b Material,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
) {
self.set_vertex_buffer(0, &mesh.vertex_buffer, 0, 0);
self.set_index_buffer(&mesh.index_buffer, 0, 0);
self.set_bind_group(0, &material.bind_group, &[]); self.set_bind_group(0, &material.bind_group, &[]);
// Do to a bug in 0.4, we need to pass in the uniforms and bind them here.
// This will be fixed in 0.5
self.set_bind_group(1, &uniforms, &[]); self.set_bind_group(1, &uniforms, &[]);
self.draw_indexed(0..mesh.num_elements, 0, instances); self.draw_indexed(0..mesh.num_elements, 0, instances);
} }
@ -340,21 +391,34 @@ With all that in place we should get the following.
Right now we are specifying the mesh and the material directly. This is useful if we want to draw a mesh with a different material. We're also not rendering other parts of the model (if we had some). Let's create a method for `DrawModel` that will draw all the parts of the model with their respective materials. Right now we are specifying the mesh and the material directly. This is useful if we want to draw a mesh with a different material. We're also not rendering other parts of the model (if we had some). Let's create a method for `DrawModel` that will draw all the parts of the model with their respective materials.
```rust ```rust
pub trait DrawModel { pub trait DrawModel<'a, 'b>
where
'b: 'a,
{
// ... // ...
fn draw_model(&mut self, model: &'b Model, uniforms: &'b wgpu::BindGroup);
fn draw_model(&mut self, model: &Model, uniforms: &wgpu::BindGroup); fn draw_model_instanced(
fn draw_model_instanced(&mut self, model: &Model, instances: Range<u32>, uniforms: &wgpu::BindGroup); &mut self,
model: &'b Model,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
);
} }
impl<'a> DrawModel for wgpu::RenderPass<'a> { impl<'a, 'b> DrawModel<'a, 'b> for wgpu::RenderPass<'a>
where
'b: 'a, {
// ... // ...
fn draw_model(&mut self, model: &'b Model, uniforms: &'b wgpu::BindGroup) {
fn draw_model(&mut self, model: &Model, uniforms: &wgpu::BindGroup) {
self.draw_model_instanced(model, 0..1, uniforms); self.draw_model_instanced(model, 0..1, uniforms);
} }
fn draw_model_instanced(&mut self, model: &Model, instances: Range<u32>, uniforms: &wgpu::BindGroup) { fn draw_model_instanced(
&mut self,
model: &'b Model,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
) {
for mesh in &model.meshes { for mesh in &model.meshes {
let material = &model.materials[mesh.material]; let material = &model.materials[mesh.material];
self.draw_mesh_instanced(mesh, material, instances.clone(), uniforms); self.draw_mesh_instanced(mesh, material, instances.clone(), uniforms);

View File

@ -42,39 +42,39 @@ let light = Light {
_padding: 0, _padding: 0,
color: (1.0, 1.0, 1.0).into(), color: (1.0, 1.0, 1.0).into(),
}; };
//If we want to use bytemuck, we must first implement these two traits
let light_buffer = device unsafe impl bytemuck::Zeroable for Light {}
// We'll want to update our lights position, so we use COPY_DST unsafe impl bytemuck::Pod for Light {}
.create_buffer_mapped(1, wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST) // We'll want to update our lights position, so we use COPY_DST
.fill_from_slice(&[light]); let light_buffer = device.create_buffer_with_data(
bytemuck::cast_slice(&[light]),
wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
);
``` ```
Don't forget to add the `light` and `light_buffer` to `State`. After that we need to create a bind group layout and bind group for our light. Don't forget to add the `light` and `light_buffer` to `State`. After that we need to create a bind group layout and bind group for our light.
```rust ```rust
let light_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { let light_bind_group_layout =
bindings: &[ device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
wgpu::BindGroupLayoutBinding { bindings: &[wgpu::BindGroupLayoutEntry {
binding: 0, binding: 0,
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT, visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
ty: wgpu::BindingType::UniformBuffer { ty: wgpu::BindingType::UniformBuffer { dynamic: false },
dynamic: false }],
}, label: None,
} });
],
});
let light_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { let light_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &light_bind_group_layout, layout: &light_bind_group_layout,
bindings: &[ bindings: &[wgpu::Binding {
wgpu::Binding { binding: 0,
binding: 0, resource: wgpu::BindingResource::Buffer {
resource: wgpu::BindingResource::Buffer { buffer: &light_buffer,
buffer: &light_buffer, range: 0..std::mem::size_of_val(&light) as wgpu::BufferAddress,
range: 0..std::mem::size_of_val(&light) as wgpu::BufferAddress, },
} }],
} label: None,
],
}); });
``` ```
@ -97,9 +97,10 @@ Let's also update the lights position in the `update()` method, so we can see wh
let old_position = self.light.position; let old_position = self.light.position;
self.light.position = cgmath::Quaternion::from_axis_angle((0.0, 1.0, 0.0).into(), cgmath::Deg(1.0)) * old_position; self.light.position = cgmath::Quaternion::from_axis_angle((0.0, 1.0, 0.0).into(), cgmath::Deg(1.0)) * old_position;
let staging_buffer = self.device let staging_buffer = device.create_buffer_with_data(
.create_buffer_mapped(1, wgpu::BufferUsage::COPY_SRC) bytemuck::cast_slice(&[self.light]),
.fill_from_slice(&[self.light]); wgpu::BufferUsage::COPY_SRC,
);
encoder.copy_buffer_to_buffer(&staging_buffer, 0, &self.light_buffer, 0, std::mem::size_of::<Light>() as wgpu::BufferAddress); encoder.copy_buffer_to_buffer(&staging_buffer, 0, &self.light_buffer, 0, std::mem::size_of::<Light>() as wgpu::BufferAddress);
``` ```
@ -164,11 +165,13 @@ fn create_render_pipeline(
stencil_write_mask: 0, stencil_write_mask: 0,
} }
}), }),
index_format: wgpu::IndexFormat::Uint32,
vertex_buffers: vertex_descs,
sample_count: 1, sample_count: 1,
sample_mask: !0, sample_mask: !0,
alpha_to_coverage_enabled: false, alpha_to_coverage_enabled: false,
vertex_state: wgpu::VertexStateDescriptor {
index_format: wgpu::IndexFormat::Uint32,
vertex_buffers: vertex_descs,
},
}) })
} }
``` ```
@ -184,7 +187,7 @@ let render_pipeline = {
&device, &device,
&render_pipeline_layout, &render_pipeline_layout,
sc_desc.format, sc_desc.format,
Some(DEPTH_FORMAT), Some(texture::DEPTH_FORMAT),
&[model::ModelVertex::desc()], &[model::ModelVertex::desc()],
vs_src, vs_src,
fs_src fs_src
@ -195,33 +198,87 @@ let render_pipeline = {
We're going to need to modify `model::DrawModel` to use our `light_bind_group`. We're going to need to modify `model::DrawModel` to use our `light_bind_group`.
```rust ```rust
pub trait DrawModel { pub trait DrawModel<'a, 'b>
fn draw_mesh(&mut self, mesh: &Mesh, material: &Material, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); where
fn draw_mesh_instanced(&mut self, mesh: &Mesh, material: &Material, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); 'b: 'a,
{
fn draw_mesh(
&mut self,
mesh: &'b Mesh,
material: &'b Material,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
);
fn draw_mesh_instanced(
&mut self,
mesh: &'b Mesh,
material: &'b Material,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
);
fn draw_model(&mut self, model: &Model, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); fn draw_model(
fn draw_model_instanced(&mut self, model: &Model, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); &mut self,
model: &'b Model,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
);
fn draw_model_instanced(
&mut self,
model: &'b Model,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
);
} }
impl<'a> DrawModel for wgpu::RenderPass<'a> { impl<'a, 'b> DrawModel<'a, 'b> for wgpu::RenderPass<'a>
fn draw_mesh(&mut self, mesh: &Mesh, material: &Material, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { where
'b: 'a,
{
fn draw_mesh(
&mut self,
mesh: &'b Mesh,
material: &'b Material,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
self.draw_mesh_instanced(mesh, material, 0..1, uniforms, light); self.draw_mesh_instanced(mesh, material, 0..1, uniforms, light);
} }
fn draw_mesh_instanced(&mut self, mesh: &Mesh, material: &Material, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { fn draw_mesh_instanced(
self.set_vertex_buffers(0, &[(&mesh.vertex_buffer, 0)]); &mut self,
self.set_index_buffer(&mesh.index_buffer, 0); mesh: &'b Mesh,
material: &'b Material,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
self.set_vertex_buffer(0, &mesh.vertex_buffer, 0, 0);
self.set_index_buffer(&mesh.index_buffer, 0, 0);
self.set_bind_group(0, &material.bind_group, &[]); self.set_bind_group(0, &material.bind_group, &[]);
self.set_bind_group(1, &uniforms, &[]); self.set_bind_group(1, &uniforms, &[]);
self.set_bind_group(2, &light, &[]); self.set_bind_group(2, &light, &[]);
self.draw_indexed(0..mesh.num_elements, 0, instances); self.draw_indexed(0..mesh.num_elements, 0, instances);
} }
fn draw_model(&mut self, model: &Model, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { fn draw_model(
&mut self,
model: &'b Model,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
self.draw_model_instanced(model, 0..1, uniforms, light); self.draw_model_instanced(model, 0..1, uniforms, light);
} }
fn draw_model_instanced(&mut self, model: &Model, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { fn draw_model_instanced(
&mut self,
model: &'b Model,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
for mesh in &model.meshes { for mesh in &model.meshes {
let material = &model.materials[mesh.material]; let material = &model.materials[mesh.material];
self.draw_mesh_instanced(mesh, material, instances.clone(), uniforms, light); self.draw_mesh_instanced(mesh, material, instances.clone(), uniforms, light);
@ -248,7 +305,7 @@ let light_render_pipeline = {
&device, &device,
&layout, &layout,
sc_desc.format, sc_desc.format,
Some(DEPTH_FORMAT), Some(texture::DEPTH_FORMAT),
&[model::ModelVertex::desc()], &[model::ModelVertex::desc()],
vs_src, vs_src,
fs_src, fs_src,
@ -305,32 +362,82 @@ void main() {
Now we could manually implement the draw code for the light in `render()`, but to keep with the pattern we developed, let's create a new trait called `DrawLight`. Now we could manually implement the draw code for the light in `render()`, but to keep with the pattern we developed, let's create a new trait called `DrawLight`.
```rust ```rust
pub trait DrawLight { pub trait DrawLight<'a, 'b>
fn draw_light_mesh(&mut self, mesh: &Mesh, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); where
fn draw_light_mesh_instanced(&mut self, mesh: &Mesh, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); 'b: 'a,
{
fn draw_light_mesh(
&mut self,
mesh: &'b Mesh,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
);
fn draw_light_mesh_instanced(
&mut self,
mesh: &'b Mesh,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) where
'b: 'a;
fn draw_light_model(&mut self, model: &Model, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); fn draw_light_model(
fn draw_light_model_instanced(&mut self, model: &Model, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup); &mut self,
model: &'b Model,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
);
fn draw_light_model_instanced(
&mut self,
model: &'b Model,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
);
} }
impl<'a, 'b> DrawLight<'a, 'b> for wgpu::RenderPass<'a>
impl<'a> DrawLight for wgpu::RenderPass<'a> { where
fn draw_light_mesh(&mut self, mesh: &Mesh, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { 'b: 'a,
{
fn draw_light_mesh(
&mut self,
mesh: &'b Mesh,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
self.draw_light_mesh_instanced(mesh, 0..1, uniforms, light); self.draw_light_mesh_instanced(mesh, 0..1, uniforms, light);
} }
fn draw_light_mesh_instanced(&mut self, mesh: &Mesh, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { fn draw_light_mesh_instanced(
self.set_vertex_buffers(0, &[(&mesh.vertex_buffer, 0)]); &mut self,
self.set_index_buffer(&mesh.index_buffer, 0); mesh: &'b Mesh,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
self.set_vertex_buffer(0, &mesh.vertex_buffer, 0, 0);
self.set_index_buffer(&mesh.index_buffer, 0, 0);
self.set_bind_group(0, uniforms, &[]); self.set_bind_group(0, uniforms, &[]);
self.set_bind_group(1, light, &[]); self.set_bind_group(1, light, &[]);
self.draw_indexed(0..mesh.num_elements, 0, instances); self.draw_indexed(0..mesh.num_elements, 0, instances);
} }
fn draw_light_model(&mut self, model: &Model, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { fn draw_light_model(
&mut self,
model: &'b Model,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
self.draw_light_model_instanced(model, 0..1, uniforms, light); self.draw_light_model_instanced(model, 0..1, uniforms, light);
} }
fn draw_light_model_instanced(&mut self, model: &Model, instances: Range<u32>, uniforms: &wgpu::BindGroup, light: &wgpu::BindGroup) { fn draw_light_model_instanced(
&mut self,
model: &'b Model,
instances: Range<u32>,
uniforms: &'b wgpu::BindGroup,
light: &'b wgpu::BindGroup,
) {
for mesh in &model.meshes { for mesh in &model.meshes {
self.draw_light_mesh_instanced(mesh, instances.clone(), uniforms, light); self.draw_light_mesh_instanced(mesh, instances.clone(), uniforms, light);
} }
@ -513,7 +620,9 @@ struct Uniforms {
view_position: cgmath::Vector4<f32>, view_position: cgmath::Vector4<f32>,
view_proj: cgmath::Matrix4<f32>, view_proj: cgmath::Matrix4<f32>,
} }
//If we want to use bytemuck, we must first implement these two traits
unsafe impl bytemuck::Zeroable for Uniforms {}
unsafe impl bytemuck::Pod for Uniforms {}
impl Uniforms { impl Uniforms {
fn new() -> Self { fn new() -> Self {
Self { Self {
@ -547,7 +656,8 @@ let uniform_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroup
}, },
}, },
// ... // ...
] ],
label: None,
}); });
``` ```