From a511a067097a858ba887521bca1edee095d5483e Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 22 Dec 2023 16:51:21 -0800 Subject: [PATCH] Migration to wgpu --- Cargo.lock | 1930 ++++++++++++++++++++++++++++++-- Cargo.toml | 16 +- src/doodad.rs | 24 +- src/inputstatus.rs | 34 +- src/main.rs | 264 +++-- src/physics/body.rs | 12 +- src/physics/mod.rs | 2 - src/physics/worldposition.rs | 48 - src/render/gpu.rs | 454 ++++++++ src/render/mod.rs | 6 + src/render/rawtexture.rs | 66 ++ src/render/shaders/shader.wgsl | 60 + src/render/texturearray.rs | 112 ++ src/ship.rs | 28 +- src/sprite.rs | 130 --- src/system.rs | 196 +--- 16 files changed, 2699 insertions(+), 683 deletions(-) delete mode 100644 src/physics/worldposition.rs create mode 100644 src/render/gpu.rs create mode 100644 src/render/mod.rs create mode 100644 src/render/rawtexture.rs create mode 100644 src/render/shaders/shader.wgsl create mode 100644 src/render/texturearray.rs delete mode 100644 src/sprite.rs diff --git a/Cargo.lock b/Cargo.lock index c82feec..e55e009 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,133 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ab_glyph" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80179d7dd5d7e8c285d67c4a1e652972a92de7475beddfb92028c76463b13225" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "android-activity" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64529721f27c2314ced0890ce45e469574a73e5e6fdd6e9da1860eb29285f5e0" +dependencies = [ + "android-properties", + "bitflags 1.3.2", + "cc", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum 0.6.1", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59d2a3357dde987206219e78ecfbbb6e8dad06cbb65292758d3270e6254f7355" + +[[package]] +name = "approx" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "ash" +version = "0.37.3+1.3.251" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" +dependencies = [ + "libloading 0.7.4", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -15,10 +136,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] -name = "bit_field" -version = "0.10.2" +name = "backtrace" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" [[package]] name = "bitflags" @@ -26,11 +171,62 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-sys" +version = "0.1.0-beta.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa55741ee90902547802152aaf3f8e5248aab7e21468089560d4c8840561146" +dependencies = [ + "objc-sys", +] + +[[package]] +name = "block2" +version = "0.2.0-alpha.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dd9e63c1744f755c2f60332b88de39d341e5e86239014ad839bd71c106dec42" +dependencies = [ + "block-sys", + "objc2-encode", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + [[package]] name = "bytemuck" version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.42", +] [[package]] name = "byteorder" @@ -39,10 +235,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] -name = "c_vec" -version = "2.0.0" +name = "calloop" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd7a427adc0135366d99db65b36dae9237130997e560ed61118041fb72be6e8" +checksum = "52e0d00eb1ea24371a97d2da6201c6747a633dc6dc1988ef503403b4c59504a8" +dependencies = [ + "bitflags 1.3.2", + "log", + "nix 0.25.1", + "slotmap", + "thiserror", + "vec_map", +] [[package]] name = "cc" @@ -50,6 +254,7 @@ version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ + "jobserver", "libc", ] @@ -60,12 +265,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "cmake" -version = "0.1.50" +name = "cfg_aliases" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cgmath" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a98d30140e3296250832bbaaff83b27dcd6fa3cc70fb6f1f3e5c9c0023b5317" dependencies = [ - "cc", + "approx", + "num-traits", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", ] [[package]] @@ -74,6 +296,52 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "com-rs" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf43edc576402991846b093a7ca18a3477e0ef9c588cde84964b5d3e43016642" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types 0.3.2", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + [[package]] name = "crc32fast" version = "1.3.2" @@ -84,63 +352,64 @@ dependencies = [ ] [[package]] -name = "crossbeam-deque" -version = "0.8.4" +name = "d3d12" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751" +checksum = "e16e44ab292b1dddfdaf7be62cfd8877df52f2f3fde5858d95bab606be259f20" dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", + "bitflags 2.4.1", + "libloading 0.8.1", + "winapi", ] [[package]] -name = "crossbeam-epoch" -version = "0.9.16" +name = "dispatch" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", + "libloading 0.8.1", ] [[package]] -name = "crossbeam-utils" -version = "0.8.17" +name = "downcast-rs" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "env_logger" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" dependencies = [ - "cfg-if", + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", ] [[package]] -name = "crunchy" -version = "0.2.2" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] -name = "either" -version = "1.9.0" +name = "errno" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" - -[[package]] -name = "exr" -version = "1.71.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "832a761f35ab3e6664babfbdc6cef35a4860e816ec3916dcfd0882954e98a8a8" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "bit_field", - "flume", - "half", - "lebe", - "miniz_oxide", - "rayon-core", - "smallvec", - "zune-inflate", + "libc", + "windows-sys 0.52.0", ] [[package]] @@ -168,16 +437,80 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" dependencies = [ + "futures-core", + "futures-sink", + "nanorand", "spin", ] +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.42", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + [[package]] name = "game" version = "0.1.0" dependencies = [ + "anyhow", + "bytemuck", + "cgmath", + "env_logger", "image", + "log", + "pollster", "rand", - "sdl2", + "wgpu", + "winit", ] [[package]] @@ -187,29 +520,146 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] -name = "gif" -version = "0.12.0" +name = "gimli" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" dependencies = [ - "color_quant", - "weezl", + "khronos_api", + "log", + "xml-rs", ] [[package]] -name = "half" -version = "2.2.1" +name = "glow" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" +checksum = "886c2a30b160c4c6fec8f987430c26b526b7988ca71f664e6a699ddf6f9601e4" dependencies = [ - "crunchy", + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", ] +[[package]] +name = "glutin_wgl_sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "gpu-alloc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" +dependencies = [ + "bitflags 2.4.1", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" +dependencies = [ + "bitflags 2.4.1", +] + +[[package]] +name = "gpu-allocator" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40fe17c8a05d60c38c0a4e5a3c802f2f1ceb66b76c67d96ffb34bef0475a7fad" +dependencies = [ + "backtrace", + "log", + "presser", + "thiserror", + "winapi", + "windows", +] + +[[package]] +name = "gpu-descriptor" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c" +dependencies = [ + "bitflags 2.4.1", + "gpu-descriptor-types", + "hashbrown", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bf0b36e6f090b7e1d8a4b49c0cb81c1f8376f72198c65dd3ad9ff3556b8b78c" +dependencies = [ + "bitflags 2.4.1", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hassle-rs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1397650ee315e8891a0df210707f0fc61771b0cc518c3023896064c5407cb3b0" +dependencies = [ + "bitflags 1.3.2", + "com-rs", + "libc", + "libloading 0.7.4", + "thiserror", + "widestring", + "winapi", +] + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "image" version = "0.24.7" @@ -219,43 +669,134 @@ dependencies = [ "bytemuck", "byteorder", "color_quant", - "exr", - "gif", - "jpeg-decoder", "num-rational", "num-traits", "png", - "qoi", - "tiff", ] [[package]] -name = "jpeg-decoder" +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "jni-sys" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" dependencies = [ - "rayon", + "libc", ] +[[package]] +name = "js-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "khronos-egl" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" +dependencies = [ + "libc", + "libloading 0.8.1", + "pkg-config", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lebe" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" - [[package]] name = "libc" version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libloading" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "libredox" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall 0.4.1", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" + [[package]] name = "lock_api" version = "0.4.11" @@ -267,14 +808,59 @@ dependencies = [ ] [[package]] -name = "memoffset" -version = "0.9.0" +name = "log" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] +[[package]] +name = "metal" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25" +dependencies = [ + "bitflags 2.4.1", + "block", + "core-graphics-types", + "foreign-types 0.5.0", + "log", + "objc", + "paste", +] + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -285,6 +871,101 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "naga" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae585df4b6514cf8842ac0f1ab4992edc975892704835b549cf818dc0191249e" +dependencies = [ + "bit-set", + "bitflags 2.4.1", + "codespan-reporting", + "hexf-parse", + "indexmap", + "log", + "num-traits", + "rustc-hash", + "spirv", + "termcolor", + "thiserror", + "unicode-xid", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + +[[package]] +name = "ndk" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +dependencies = [ + "bitflags 1.3.2", + "jni-sys", + "ndk-sys", + "num_enum 0.5.11", + "raw-window-handle", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.4.1+23.1.7779620" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "nix" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -315,19 +996,186 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive 0.5.11", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive 0.6.1", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.42", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc-sys" +version = "0.2.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7" + +[[package]] +name = "objc2" +version = "0.3.0-beta.3.patch-leaks.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e01640f9f2cb1220bbe80325e179e532cb3379ebcd1bf2279d703c19fe3a468" +dependencies = [ + "block2", + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "2.0.0-pre.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abfcac41015b00a120608fdaa6938c44cb983fee294351cc4bac7638b4e50512" +dependencies = [ + "objc-sys", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "orbclient" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" +dependencies = [ + "libredox", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4586edfe4c648c71797a74c84bacb32b52b212eff5dfe2bb9f2c599844023e7" +dependencies = [ + "ttf-parser", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pkg-config" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" + [[package]] name = "png" version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" dependencies = [ - "bitflags", + "bitflags 1.3.2", "crc32fast", "fdeflate", "flate2", "miniz_oxide", ] +[[package]] +name = "pollster" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -335,12 +1183,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] -name = "qoi" -version = "0.4.1" +name = "presser" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ - "bytemuck", + "once_cell", + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "profiling" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d135ede8821cf6376eb7a64148901e1690b788c11ae94dc297ae917dbc91dc0e" + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", ] [[package]] @@ -374,25 +1253,101 @@ dependencies = [ ] [[package]] -name = "rayon" -version = "1.8.0" +name = "range-alloc" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab" + +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "either", - "rayon-core", + "bitflags 1.3.2", ] [[package]] -name = "rayon-core" -version = "1.12.0" +name = "redox_syscall" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "crossbeam-deque", - "crossbeam-utils", + "bitflags 1.3.2", ] +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "renderdoc-sys" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216080ab382b992234dda86873c18d4c48358f5cfcb70fd693d7f6f2131b628b" + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -400,28 +1355,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] -name = "sdl2" -version = "0.36.0" +name = "sctk-adwaita" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8356b2697d1ead5a34f40bcc3c5d3620205fe0c7be0a14656223bfeec0258891" +checksum = "cda4e97be1fd174ccc2aae81c8b694e803fa99b34e8fd0f057a9d70698e3ed09" dependencies = [ - "bitflags", - "c_vec", - "lazy_static", - "libc", - "sdl2-sys", -] - -[[package]] -name = "sdl2-sys" -version = "0.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26bcacfdd45d539fb5785049feb0038a63931aa896c7763a2a12e125ec58bd29" -dependencies = [ - "cfg-if", - "cmake", - "libc", - "version-compare", + "ab_glyph", + "log", + "memmap2", + "smithay-client-toolkit", + "tiny-skia", ] [[package]] @@ -430,12 +1373,40 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + [[package]] name = "smallvec" version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +[[package]] +name = "smithay-client-toolkit" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870427e30b8f2cbe64bf43ec4b86e88fe39b0a84b3f15efd9c9c2d020bc86eb9" +dependencies = [ + "bitflags 1.3.2", + "calloop", + "dlib", + "lazy_static", + "log", + "memmap2", + "nix 0.24.3", + "pkg-config", + "wayland-client", + "wayland-cursor", + "wayland-protocols", +] + [[package]] name = "spin" version = "0.9.8" @@ -446,21 +1417,155 @@ dependencies = [ ] [[package]] -name = "tiff" -version = "0.9.0" +name = "spirv" +version = "0.2.0+1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211" +checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830" dependencies = [ - "flate2", - "jpeg-decoder", - "weezl", + "bitflags 1.3.2", + "num-traits", ] [[package]] -name = "version-compare" +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strict-num" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b7d0a2c048d661a1a59fcd7355baa232f7ed34e0ee4df2eef3c1c1c0d3852d8" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.42", +] + +[[package]] +name = "tiny-skia" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8493a203431061e901613751931f047d1971337153f96d0e5e363d6dbf6a67" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "png", + "tiny-skia-path", +] + +[[package]] +name = "tiny-skia-path" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adbfb5d3f3dd57a0e11d12f4f13d4ebbbc1b5c15b7ab0a156d030b21da5f677c" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "ttf-parser" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasi" @@ -469,16 +1574,593 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "weezl" -version = "0.1.7" +name = "wasm-bindgen" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] [[package]] -name = "zune-inflate" -version = "0.2.54" +name = "wasm-bindgen-backend" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ - "simd-adler32", + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.42", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.42", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" + +[[package]] +name = "wayland-client" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" +dependencies = [ + "bitflags 1.3.2", + "downcast-rs", + "libc", + "nix 0.24.3", + "scoped-tls", + "wayland-commons", + "wayland-scanner", + "wayland-sys", +] + +[[package]] +name = "wayland-commons" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" +dependencies = [ + "nix 0.24.3", + "once_cell", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-cursor" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" +dependencies = [ + "nix 0.24.3", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" +dependencies = [ + "bitflags 1.3.2", + "wayland-client", + "wayland-commons", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" +dependencies = [ + "proc-macro2", + "quote", + "xml-rs", +] + +[[package]] +name = "wayland-sys" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" +dependencies = [ + "dlib", + "lazy_static", + "pkg-config", +] + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "wgpu" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30e7d227c9f961f2061c26f4cb0fbd4df0ef37e056edd0931783599d6c94ef24" +dependencies = [ + "arrayvec", + "cfg-if", + "flume", + "js-sys", + "log", + "naga", + "parking_lot", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef91c1d62d1e9e81c79e600131a258edf75c9531cbdbde09c44a011a47312726" +dependencies = [ + "arrayvec", + "bit-vec", + "bitflags 2.4.1", + "codespan-reporting", + "log", + "naga", + "parking_lot", + "profiling", + "raw-window-handle", + "rustc-hash", + "smallvec", + "thiserror", + "web-sys", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b84ecc802da3eb67b4cf3dd9ea6fe45bbb47ef13e6c49c5c3240868a9cc6cdd9" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set", + "bitflags 2.4.1", + "block", + "core-graphics-types", + "d3d12", + "glow", + "glutin_wgl_sys", + "gpu-alloc", + "gpu-allocator", + "gpu-descriptor", + "hassle-rs", + "js-sys", + "khronos-egl", + "libc", + "libloading 0.8.1", + "log", + "metal", + "naga", + "objc", + "once_cell", + "parking_lot", + "profiling", + "range-alloc", + "raw-window-handle", + "renderdoc-sys", + "rustc-hash", + "smallvec", + "thiserror", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "winapi", +] + +[[package]] +name = "wgpu-types" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d5ed5f0edf0de351fe311c53304986315ce866f394a2e6df0c4b3c70774bcdd" +dependencies = [ + "bitflags 2.4.1", + "js-sys", + "web-sys", +] + +[[package]] +name = "widestring" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" +dependencies = [ + "windows-core", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "winit" +version = "0.28.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9596d90b45384f5281384ab204224876e8e8bf7d58366d9b795ad99aa9894b94" +dependencies = [ + "android-activity", + "bitflags 1.3.2", + "cfg_aliases", + "core-foundation", + "core-graphics", + "dispatch", + "instant", + "libc", + "log", + "mio", + "ndk", + "objc2", + "once_cell", + "orbclient", + "percent-encoding", + "raw-window-handle", + "redox_syscall 0.3.5", + "sctk-adwaita", + "smithay-client-toolkit", + "wasm-bindgen", + "wayland-client", + "wayland-commons", + "wayland-protocols", + "wayland-scanner", + "web-sys", + "windows-sys 0.45.0", + "x11-dl", +] + +[[package]] +name = "winnow" +version = "0.5.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b5c3db89721d50d0e2a673f5043fc4722f76dcc352d7b1ab8b8288bed4ed2c5" +dependencies = [ + "memchr", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "xcursor" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a0ccd7b4a5345edfcd0c3535718a4e9ff7798ffc536bb5b5a0e26ff84732911" + +[[package]] +name = "xml-rs" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.42", ] diff --git a/Cargo.toml b/Cargo.toml index 114c295..2e3bca5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,10 +27,18 @@ incremental = false rpath = false [dependencies] -image = "0.24.7" rand = "0.8.5" +winit = "0.28" +env_logger = "0.10" +log = "0.4" +wgpu = "0.18" +pollster = "0.3" +bytemuck = { version = "1.12", features = ["derive"] } +anyhow = "1.0" +cgmath = "0.18.0" -[dependencies.sdl2] -version = "0.36" + +[dependencies.image] +version = "0.24" default-features = false -features = ["ttf", "gfx", "bundled"] +features = ["png"] diff --git a/src/doodad.rs b/src/doodad.rs index feb735d..c6ae0ae 100644 --- a/src/doodad.rs +++ b/src/doodad.rs @@ -1,21 +1,17 @@ -use crate::DrawContext; -use crate::Drawable; -use crate::SpriteAtlas; -use crate::WorldPosition; - +use crate::{physics::Cartesian, Camera, Sprite}; pub struct Doodad { pub sprite: String, - pub pos: WorldPosition, - pub scale: u32, - pub angle: f64, + pub pos: Cartesian, } -impl Drawable for Doodad { - fn draw(&self, dc: &mut DrawContext, sa: &SpriteAtlas) -> Result<(), String> { - let pos = self.pos.screen_position(dc); - let sprite = sa.get(&self.sprite); - sprite.draw(dc.canvas, pos, self.angle, 1.0)?; +impl Doodad { + pub fn sprite(&self, camera: &Camera) -> Sprite { + let p = self.pos - camera.pos; - return Ok(()); + return Sprite { + position: (p.x, p.y), + name: self.sprite.clone(), + angle: 0.0, + }; } } diff --git a/src/inputstatus.rs b/src/inputstatus.rs index ec9e1fb..a0070f3 100644 --- a/src/inputstatus.rs +++ b/src/inputstatus.rs @@ -1,4 +1,4 @@ -use sdl2::{event::Event, keyboard::Keycode}; +use winit::event::{ElementState, VirtualKeyCode}; // TODO: no boolean modification (no pub) pub struct InputStatus { @@ -16,32 +16,12 @@ impl InputStatus { } } - fn handle_keyup(&mut self, keycode: Keycode) { - match keycode { - Keycode::Left => self.key_left = false, - Keycode::Right => self.key_right = false, - Keycode::Up => self.key_thrust = false, - _ => {} - } - } - - fn handle_keydown(&mut self, keycode: Keycode) { - match keycode { - Keycode::Left => self.key_left = true, - Keycode::Right => self.key_right = true, - Keycode::Up => self.key_thrust = true, - _ => {} - } - } - - pub fn update(&mut self, event: Event) { - match event { - Event::KeyDown { - keycode: Some(key), .. - } => self.handle_keydown(key), - Event::KeyUp { - keycode: Some(key), .. - } => self.handle_keyup(key), + pub fn process(&mut self, state: &ElementState, key: &VirtualKeyCode) { + let down = state == &ElementState::Pressed; + match key { + VirtualKeyCode::Left => self.key_left = down, + VirtualKeyCode::Right => self.key_right = down, + VirtualKeyCode::Up => self.key_thrust = down, _ => {} } } diff --git a/src/main.rs b/src/main.rs index 092814d..f47aa5f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,23 +1,26 @@ -use sdl2::{event::Event, keyboard::Keycode, render::Canvas, video::Window}; -use std::{time::Duration, time::Instant}; +use anyhow::Result; +use physics::Cartesian; +use winit::{ + event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent}, + event_loop::{ControlFlow, EventLoop}, + window::WindowBuilder, +}; mod doodad; mod inputstatus; mod physics; +mod render; mod ship; -mod sprite; mod system; use crate::{ - doodad::Doodad, inputstatus::InputStatus, physics::Cartesian, physics::WorldPosition, - ship::Ship, ship::ShipKind, sprite::SpriteAtlas, system::System, + doodad::Doodad, + inputstatus::InputStatus, + render::GPUState, + ship::{Ship, ShipKind}, + system::System, }; -trait Drawable { - // Draw this item on the screen - fn draw(&self, dc: &mut DrawContext, sa: &SpriteAtlas) -> Result<(), String>; -} - struct Camera { pos: Cartesian, } @@ -30,145 +33,132 @@ impl Camera { } } -static FTL: f64 = 1.0 / 200.0; // frame time limit - -struct DrawContext<'a> { - canvas: &'a mut Canvas, - camera: Camera, - - // Dimensions of the window - window_size: Cartesian, - - // Position of the top-left corner of the window, - // relative to camera position. - top_left: Cartesian, +struct Sprite { + // Image to use + name: String, + // World position + position: (f64, f64), + angle: f32, } -impl<'a> DrawContext<'a> { - fn new(canvas: &'a mut Canvas, camera: Camera) -> Self { - let mut s = Self { - canvas, - camera, - window_size: Cartesian::new(0.0, 0.0), - top_left: Cartesian::new(0.0, 0.0), - }; - s.update(); - return s; +struct Game { + input: InputStatus, + last_update: Instant, + player: Ship, + system: System, + camera: Camera, +} + +impl Game { + fn new() -> Self { + Game { + last_update: Instant::now(), + input: InputStatus::new(), + player: Ship::new(ShipKind::Gypsum, Cartesian::new(0.0, 0.0)), + camera: Camera::new(), + system: System::new(), + } + } + + fn process_input(&mut self, gpu: &ElementState, key: &VirtualKeyCode) { + self.input.process(gpu, key) } fn update(&mut self) { - self.window_size = Cartesian::from(self.canvas.window().size()); - self.top_left = (self.window_size / 2.0) * Cartesian::new(-1.0, 1.0); + let t = self.last_update.elapsed().as_secs_f64(); + println!("{:.02}", 1.0 / t); + + if self.input.key_thrust { + self.player.body.thrust(50.0 * t); + } + + if self.input.key_right { + self.player.body.rot(15.0 * t); + } + + if self.input.key_left { + self.player.body.rot(-15.0 * t); + } + + self.player.body.tick(t); + self.camera.pos = self.player.body.pos; + + self.last_update = Instant::now(); + } + + fn sprites(&self) -> Vec { + let mut sprites: Vec = Vec::new(); + + sprites.append(&mut self.system.sprites(&self.camera)); + sprites.push(self.player.sprite(&self.camera)); + + return sprites; } } -// Frame timing: -// -// Input -// Draw -// -// Physics -// -// Wait -// -// Apply input -// -#[derive(Debug, Default)] -struct PerformanceStats { - last_frame_draw: f64, - last_frame_phys: f64, - last_frame_wait: f64, - last_frame_total: f64, -} +use std::time::Instant; -fn main() -> Result<(), String> { - let sdl_context = sdl2::init()?; - let video_subsystem = sdl_context.video()?; - let mut stats = PerformanceStats::default(); +pub async fn run() -> Result<()> { + env_logger::init(); + let event_loop = EventLoop::new(); + let window = WindowBuilder::new().build(&event_loop).unwrap(); - let window = video_subsystem - .window("SDL2", 640, 480) - .position_centered() - .resizable() - .build() - .map_err(|e| e.to_string())?; + let mut gpu = GPUState::new(window).await?; + let mut game = Game::new(); - let mut canvas = window - .into_canvas() - .accelerated() - .build() - .map_err(|e| e.to_string())?; - let texture_creator = canvas.texture_creator(); - - let sa = SpriteAtlas::new(&texture_creator)?; - let mut event_pump = sdl_context.event_pump()?; - let mut dc = DrawContext::new(&mut canvas, Camera::new()); - let mut i = InputStatus::new(); - - let mut system = System::new(); - let mut s = Ship::new(ShipKind::Gypsum, Cartesian::new(0.0, 0.0)); - - let mut frame_start; - let mut running = true; - - while running { - frame_start = Instant::now(); - dc.update(); - - for event in event_pump.poll_iter() { - match event { - Event::Quit { .. } - | Event::KeyDown { - keycode: Some(Keycode::Escape), - .. - } => { - running = false; + event_loop.run(move |event, _, control_flow| { + match event { + Event::RedrawRequested(window_id) if window_id == gpu.window().id() => { + gpu.update(); + game.update(); + match gpu.render(&game.sprites()) { + Ok(_) => {} + // Reconfigure the surface if lost + Err(wgpu::SurfaceError::Lost) => gpu.resize(gpu.size), + // The system is out of memory, we should probably quit + Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit, + // All other errors (Outdated, Timeout) should be resolved by the next frame + Err(e) => eprintln!("{:?}", e), } - _ => i.update(event), } + + Event::MainEventsCleared => { + // RedrawRequested will only trigger once unless we manually + // request it. + gpu.window().request_redraw(); + } + + Event::WindowEvent { + ref event, + window_id, + } if window_id == gpu.window.id() => { + match event { + WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit, + WindowEvent::KeyboardInput { + input: + KeyboardInput { + state, + virtual_keycode: Some(key), + .. + }, + .. + } => game.process_input(state, key), + WindowEvent::Resized(physical_size) => { + gpu.resize(*physical_size); + } + WindowEvent::ScaleFactorChanged { new_inner_size, .. } => { + // new_inner_size is &&mut so we have to dereference it twice + gpu.resize(**new_inner_size); + } + _ => {} + } + } + _ => {} } - - dc.camera.pos = s.body.pos; - - // Draw - dc.canvas.clear(); - system.draw(&mut dc, &sa)?; - s.draw(&mut dc, &sa)?; - dc.canvas.present(); - stats.last_frame_draw = frame_start.elapsed().as_secs_f64(); - - // Physics goes here - - let frame_time = frame_start.elapsed().as_secs_f64(); - stats.last_frame_phys = frame_time; - - // Wait - // (limit frame rate) - if frame_time < FTL { - std::thread::sleep(Duration::from_secs_f64(FTL - frame_time)); - } - stats.last_frame_wait = frame_start.elapsed().as_secs_f64(); - - // Apply input - let frame_time = frame_start.elapsed().as_secs_f64(); - - s.body.tick(frame_time); - system.tick(frame_time); - - if i.key_thrust { - s.body.thrust(50.0 * frame_time); - } - - if i.key_right { - s.body.rot(-1.0 * frame_time); - } - - if i.key_left { - s.body.rot(1.0 * frame_time); - } - - stats.last_frame_total = frame_start.elapsed().as_secs_f64(); - } - - Ok(()) + }); +} + +fn main() -> Result<()> { + pollster::block_on(run())?; + return Ok(()); } diff --git a/src/physics/body.rs b/src/physics/body.rs index 1d22628..5e432b1 100644 --- a/src/physics/body.rs +++ b/src/physics/body.rs @@ -1,11 +1,10 @@ use crate::physics::Cartesian; -use std::f64::consts::{PI, TAU}; pub struct PhysBody { pub pos: Cartesian, pub vel: Cartesian, pub mass: f64, - pub angle: f64, // In radians + pub angle: f64, // In degrees } impl PhysBody { @@ -30,15 +29,18 @@ impl PhysBody { /// Apply force in the direction this object is pointing. pub fn thrust(&mut self, f: f64) { - let l = Cartesian::new(self.angle.sin(), self.angle.cos()) * f; + let l = Cartesian::new( + -self.angle.to_radians().sin(), + self.angle.to_radians().cos(), + ) * f; self.force(l); } // Rotate this object by `a` radians. pub fn rot(&mut self, a: f64) { self.angle -= a; - if self.angle.abs() > PI { - self.angle -= self.angle.signum() * TAU; + if self.angle.abs() > 180.0 { + self.angle -= self.angle.signum() * 360.0; } } } diff --git a/src/physics/mod.rs b/src/physics/mod.rs index 3086f2b..c0430fe 100644 --- a/src/physics/mod.rs +++ b/src/physics/mod.rs @@ -1,9 +1,7 @@ mod body; mod cartesian; mod polar; -mod worldposition; pub use body::PhysBody; pub use cartesian::Cartesian; pub use polar::Polar; -pub use worldposition::WorldPosition; diff --git a/src/physics/worldposition.rs b/src/physics/worldposition.rs deleted file mode 100644 index bb42704..0000000 --- a/src/physics/worldposition.rs +++ /dev/null @@ -1,48 +0,0 @@ -use super::Cartesian; -use crate::DrawContext; - -#[derive(Debug, Clone, Copy)] - -pub struct WorldPosition { - pub pos: Cartesian, // True world position - pub par: f64, // Parallax factor -} - -impl WorldPosition { - pub fn new(pos: Cartesian, par: f64) -> Self { - WorldPosition { pos: pos, par } - } - - /* - fn from_screen_position(dc: &DrawContext, pos: Cartesian, par: f64) -> Self { - WorldPosition { - par, - pos: ((pos * Cartesian::new(1.0, -1.0)) + dc.top_left) * par + dc.camera.pos, - } - } - */ - - /// Transform this world coordinate into a position on the screen, - /// taking parallax into account. (0, 0) is at top-left corner. - /// Returned position is this object's center. - pub fn screen_position(&self, dc: &DrawContext) -> Cartesian { - let par = self.par; - let pos: Cartesian = self.pos; - return (((pos - dc.camera.pos) / par) - dc.top_left) * Cartesian::new(1.0, -1.0); - } - - /* - /// Transform this world coordinate into a position on the screen, ignoring parallax. - /// Used for debugging. - pub fn screen_position_real(&self, dc: &DrawContext) -> Cartesian { - let pos: Cartesian = self.pos; - return ((pos - dc.camera.pos) - dc.top_left) * Cartesian::new(1.0, -1.0); - } - */ -} - -impl Into for WorldPosition { - fn into(self) -> Cartesian { - self.pos.into() - } -} diff --git a/src/render/gpu.rs b/src/render/gpu.rs new file mode 100644 index 0000000..141c32e --- /dev/null +++ b/src/render/gpu.rs @@ -0,0 +1,454 @@ +use anyhow::Result; +use bytemuck; +use cgmath::{Deg, Matrix4, Point2, Vector3}; +use std::{iter, mem}; +use wgpu::{self, util::DeviceExt}; +use winit::{self, window::Window}; + +use super::texturearray::TextureArray; +use crate::Sprite; + +pub struct GPUState { + device: wgpu::Device, + config: wgpu::SurfaceConfiguration, + surface: wgpu::Surface, + queue: wgpu::Queue, + + pub window: Window, + pub size: winit::dpi::PhysicalSize, + + render_pipeline: wgpu::RenderPipeline, + + vertex_buffer: wgpu::Buffer, + index_buffer: wgpu::Buffer, + texture_array: TextureArray, + instance_buffer: wgpu::Buffer, +} + +#[rustfmt::skip] +const OPENGL_TO_WGPU_MATRIX: Matrix4 = Matrix4::new( + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 0.5, 0.5, + 0.0, 0.0, 0.0, 1.0, +); + +struct Instance { + transform: Transform, + texture_index: u32, +} +impl Instance { + fn to_raw(&self) -> InstanceRaw { + InstanceRaw { + model: (self.transform.build_view_projection_matrix()).into(), + texture_index: self.texture_index, + } + } +} + +#[repr(C)] +#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] +struct InstanceRaw { + model: [[f32; 4]; 4], + texture_index: u32, +} + +impl InstanceRaw { + fn get_size() -> u64 { + 20 + } + + fn desc() -> wgpu::VertexBufferLayout<'static> { + wgpu::VertexBufferLayout { + array_stride: mem::size_of::() as wgpu::BufferAddress, + // We need to switch from using a step mode of Vertex to Instance + // This means that our shaders will only change to use the next + // instance when the shader starts processing a new instance + step_mode: wgpu::VertexStepMode::Instance, + attributes: &[ + // A mat4 takes up 4 vertex slots as it is technically 4 vec4s. We need to define a slot + // for each vec4. We'll have to reassemble the mat4 in the shader. + wgpu::VertexAttribute { + offset: 0, + // While our vertex shader only uses locations 0, and 1 now, in later tutorials, we'll + // be using 2, 3, and 4, for Vertex. We'll start at slot 5, not conflict with them later + shader_location: 5, + format: wgpu::VertexFormat::Float32x4, + }, + wgpu::VertexAttribute { + offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress, + shader_location: 6, + format: wgpu::VertexFormat::Float32x4, + }, + wgpu::VertexAttribute { + offset: mem::size_of::<[f32; 8]>() as wgpu::BufferAddress, + shader_location: 7, + format: wgpu::VertexFormat::Float32x4, + }, + wgpu::VertexAttribute { + offset: mem::size_of::<[f32; 12]>() as wgpu::BufferAddress, + shader_location: 8, + format: wgpu::VertexFormat::Float32x4, + }, + wgpu::VertexAttribute { + offset: mem::size_of::<[f32; 16]>() as wgpu::BufferAddress, + shader_location: 9, + format: wgpu::VertexFormat::Uint32, + }, + ], + } + } +} + +struct Transform { + pos: Point2, + aspect: f32, // width / height + scale: f32, + rotate: f32, // Around this object's center, in degrees measured ccw from vertical +} + +impl Transform { + fn build_view_projection_matrix(&self) -> Matrix4 { + // Apply aspect ratio and scale + let mut scale = Matrix4::from_nonuniform_scale(1.0, 1.0 / self.aspect, 1.0); + scale = scale * Matrix4::from_scale(self.scale); + + // Our mesh starts at (0, 0), so this will rotate around the object's center. + // Note that we translate AFTER scaling. + let rotate = Matrix4::from_angle_z(Deg { 0: self.rotate }); + + let translate = Matrix4::from_translation(Vector3 { + x: self.pos.x, + y: self.pos.y, + z: 0.0, + }); + + // Order matters! + // These are applied right-to-left + return OPENGL_TO_WGPU_MATRIX * translate * rotate * scale; + } +} + +// Datatype for vertex buffer +#[repr(C)] +#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] +struct Vertex { + position: [f32; 3], + tex_coords: [f32; 2], +} + +impl Vertex { + fn desc() -> wgpu::VertexBufferLayout<'static> { + wgpu::VertexBufferLayout { + array_stride: mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &[ + wgpu::VertexAttribute { + offset: 0, + shader_location: 0, + format: wgpu::VertexFormat::Float32x3, + }, + wgpu::VertexAttribute { + offset: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress, + shader_location: 1, + format: wgpu::VertexFormat::Float32x2, + }, + ], + } + } +} + +// This is centered at 0,0 intentionally, +// so scaling works properly. +const VERTICES: &[Vertex] = &[ + Vertex { + position: [-0.5, 0.5, 0.0], + tex_coords: [0.0, 0.0], + }, + Vertex { + position: [0.5, 0.5, 0.0], + tex_coords: [1.0, 0.0], + }, + Vertex { + position: [0.5, -0.5, 0.0], + tex_coords: [1.0, 1.0], + }, + Vertex { + position: [-0.5, -0.5, 0.0], + tex_coords: [0.0, 1.0], + }, +]; + +const INDICES: &[u16] = &[0, 3, 2, 0, 2, 1]; + +impl GPUState { + // We can draw at most this many sprites on the screen. + // TODO: compile-time option + pub const SPRITE_LIMIT: u64 = 100; + + pub async fn new(window: Window) -> Result { + let size = window.inner_size(); + + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { + backends: wgpu::Backends::all(), + ..Default::default() + }); + + let surface = unsafe { instance.create_surface(&window) }.unwrap(); + + // Basic setup + let device; + let queue; + let config; + + { + let adapter = instance + .request_adapter(&wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::default(), + compatible_surface: Some(&surface), + force_fallback_adapter: false, + }) + .await + .unwrap(); + + (device, queue) = adapter + .request_device( + &wgpu::DeviceDescriptor { + features: wgpu::Features::TEXTURE_BINDING_ARRAY | wgpu::Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, + // We may need limits if we compile for wasm + limits: wgpu::Limits::default(), + label: Some("gpu device"), + }, + None, + ) + .await + .unwrap(); + + // Assume sRGB + let surface_caps = surface.get_capabilities(&adapter); + let surface_format = surface_caps + .formats + .iter() + .copied() + .filter(|f| f.is_srgb()) + .filter(|f| f.has_stencil_aspect()) + .next() + .unwrap_or(surface_caps.formats[0]); + + config = wgpu::SurfaceConfiguration { + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + format: surface_format, + width: size.width, + height: size.height, + present_mode: surface_caps.present_modes[0], + alpha_mode: surface_caps.alpha_modes[0], + view_formats: vec![], + }; + + surface.configure(&device, &config); + } + + // Load textures + let texture_array = TextureArray::new(&device, &queue)?; + + // Render pipeline + let render_pipeline; + let render_pipeline_layout; + + { + let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { + label: Some("sprite shader"), + source: wgpu::ShaderSource::Wgsl( + include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/src/render/shaders/", + "shader.wgsl" + )) + .into(), + ), + }); + + render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("render pipeline layout"), + bind_group_layouts: &[&texture_array.bind_group_layout], + push_constant_ranges: &[], + }); + + render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("render pipeline"), + layout: Some(&render_pipeline_layout), + vertex: wgpu::VertexState { + module: &shader, + entry_point: "vertex_shader_main", + buffers: &[Vertex::desc(), InstanceRaw::desc()], + }, + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: "fragment_shader_main", + targets: &[Some(wgpu::ColorTargetState { + format: config.format, + blend: Some(wgpu::BlendState::ALPHA_BLENDING), + write_mask: wgpu::ColorWrites::ALL, + })], + }), + + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleList, + strip_index_format: None, + front_face: wgpu::FrontFace::Ccw, + cull_mode: Some(wgpu::Face::Back), + polygon_mode: wgpu::PolygonMode::Fill, + unclipped_depth: false, + conservative: false, + }, + + depth_stencil: None, + multisample: wgpu::MultisampleState { + count: 1, + mask: !0, + alpha_to_coverage_enabled: false, + }, + multiview: None, + }); + } + + let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("vertex buffer"), + contents: bytemuck::cast_slice(VERTICES), + usage: wgpu::BufferUsages::VERTEX, + }); + + let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("vertex index buffer"), + contents: bytemuck::cast_slice(INDICES), + usage: wgpu::BufferUsages::INDEX, + }); + + let instance_buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: Some("instance buffer"), + usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, + size: InstanceRaw::get_size() * Self::SPRITE_LIMIT, + mapped_at_creation: false, + }); + + return Ok(Self { + surface, + device, + queue, + config, + size, + window, + render_pipeline, + vertex_buffer, + index_buffer, + instance_buffer, + texture_array, + }); + } + + pub fn window(&self) -> &Window { + &self.window + } + + pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize) { + if new_size.width > 0 && new_size.height > 0 { + self.size = new_size; + self.config.width = new_size.width; + self.config.height = new_size.height; + self.surface.configure(&self.device, &self.config); + } + } + + pub fn update(&mut self) {} + + pub fn render(&mut self, sprites: &Vec) -> Result<(), wgpu::SurfaceError> { + let output = self.surface.get_current_texture()?; + let view = output + .texture + .create_view(&wgpu::TextureViewDescriptor::default()); + + let mut encoder = self + .device + .create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: Some("sprite render encoder"), + }); + + let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: Some("sprite render pass"), + + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: &view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color { + r: 0.0, + g: 0.0, + b: 0.0, + a: 1.0, + }), + store: wgpu::StoreOp::Store, + }, + })], + depth_stencil_attachment: None, + occlusion_query_set: None, + timestamp_writes: None, + }); + + // Correct for screen aspect ratio + // (it may not be square!) + let screen_aspect = self.size.width as f32 / self.size.height as f32; + + // TODO: warning when too many sprites are drawn. + let mut instances: Vec = Vec::new(); + for s in sprites { + let mut pos: Point2 = (s.position.0 as f32, s.position.1 as f32).into(); + + // TODO: dynamic + pos.x /= 400.0; + pos.y /= 400.0; + + let texture = self.texture_array.get_texture(&s.name[..]); + + instances.push(Instance { + transform: Transform { + pos, + aspect: texture.aspect / screen_aspect, + scale: 0.25, + rotate: s.angle, + }, + texture_index: texture.index, + }) + } + + // Enforce sprite limit + if sprites.len() as u64 >= Self::SPRITE_LIMIT { + // TODO: no panic, handle this better. + panic!("Sprite limit exceeded!") + } + + // Write new sprite data to buffer + let instance_data: Vec<_> = instances.iter().map(Instance::to_raw).collect(); + self.queue.write_buffer( + &self.instance_buffer, + 0, + bytemuck::cast_slice(&instance_data), + ); + + render_pass.set_pipeline(&self.render_pipeline); + render_pass.set_bind_group(0, &self.texture_array.bind_group, &[]); + render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); + render_pass.set_vertex_buffer(1, self.instance_buffer.slice(..)); + render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16); + render_pass.draw_indexed(0..INDICES.len() as u32, 0, 0..instances.len() as _); + + // begin_render_pass borrows encoder mutably, so we can't call finish() + // without dropping this variable. + drop(render_pass); + + self.queue.submit(iter::once(encoder.finish())); + output.present(); + + Ok(()) + } +} diff --git a/src/render/mod.rs b/src/render/mod.rs new file mode 100644 index 0000000..79ae029 --- /dev/null +++ b/src/render/mod.rs @@ -0,0 +1,6 @@ +mod gpu; +mod rawtexture; +mod texturearray; + +pub use gpu::GPUState; +pub use texturearray::Texture; diff --git a/src/render/rawtexture.rs b/src/render/rawtexture.rs new file mode 100644 index 0000000..c9ebbba --- /dev/null +++ b/src/render/rawtexture.rs @@ -0,0 +1,66 @@ +use anyhow::Result; +use image::GenericImageView; + +pub(super) struct RawTexture { + pub(super) view: wgpu::TextureView, + pub(super) dimensions: (u32, u32), +} + +impl RawTexture { + pub(super) fn from_bytes( + device: &wgpu::Device, + queue: &wgpu::Queue, + bytes: &[u8], + label: &str, + ) -> Result { + let img = image::load_from_memory(bytes)?; + Self::from_image(device, queue, &img, Some(label)) + } + + pub(super) fn from_image( + device: &wgpu::Device, + queue: &wgpu::Queue, + img: &image::DynamicImage, + label: Option<&str>, + ) -> Result { + let rgba = img.to_rgba8(); + let dimensions = img.dimensions(); + + let size = wgpu::Extent3d { + width: dimensions.0, + height: dimensions.1, + depth_or_array_layers: 1, + }; + + let texture = device.create_texture(&wgpu::TextureDescriptor { + label, + size, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rgba8UnormSrgb, + usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, + view_formats: &[], + }); + + let view = texture.create_view(&wgpu::TextureViewDescriptor::default()); + + queue.write_texture( + wgpu::ImageCopyTexture { + aspect: wgpu::TextureAspect::All, + texture: &texture, + mip_level: 0, + origin: wgpu::Origin3d::ZERO, + }, + &rgba, + wgpu::ImageDataLayout { + offset: 0, + bytes_per_row: Some(4 * dimensions.0), + rows_per_image: Some(dimensions.1), + }, + size, + ); + + Ok(Self { view, dimensions }) + } +} diff --git a/src/render/shaders/shader.wgsl b/src/render/shaders/shader.wgsl new file mode 100644 index 0000000..cc3380f --- /dev/null +++ b/src/render/shaders/shader.wgsl @@ -0,0 +1,60 @@ +struct InstanceInput { + @location(5) transform_matrix_0: vec4, + @location(6) transform_matrix_1: vec4, + @location(7) transform_matrix_2: vec4, + @location(8) transform_matrix_3: vec4, + @location(9) texture_idx: u32, +}; + + + +// Vertex shader + +struct VertexInput { + @location(0) position: vec3, + @location(1) tex_coords: vec2, +} + +struct VertexOutput { + @builtin(position) clip_position: vec4, + @location(0) tex_coords: vec2, + @location(1) index: u32, +} + +@vertex +fn vertex_shader_main( + model: VertexInput, + instance: InstanceInput, +) -> VertexOutput { + let transform_matrix = mat4x4( + instance.transform_matrix_0, + instance.transform_matrix_1, + instance.transform_matrix_2, + instance.transform_matrix_3, + ); + + var out: VertexOutput; + out.tex_coords = model.tex_coords; + out.clip_position = transform_matrix * vec4(model.position, 1.0); + out.index = instance.texture_idx; + return out; +} + + +// Fragment shader + +@group(0) @binding(0) +var texture_array: binding_array>; +@group(0) @binding(1) +var sampler_array: binding_array; + + +@fragment +fn fragment_shader_main(in: VertexOutput) -> @location(0) vec4 { + return textureSampleLevel( + texture_array[in.index], + sampler_array[in.index], + in.tex_coords, + 0.0 + ).rgba; +} \ No newline at end of file diff --git a/src/render/texturearray.rs b/src/render/texturearray.rs new file mode 100644 index 0000000..b2426cc --- /dev/null +++ b/src/render/texturearray.rs @@ -0,0 +1,112 @@ +use anyhow::Result; +use std::{collections::HashMap, fs::File, io::Read, num::NonZeroU32}; +use wgpu::BindGroupLayout; + +use super::rawtexture::RawTexture; + +pub struct TextureArray { + pub bind_group: wgpu::BindGroup, + pub bind_group_layout: BindGroupLayout, + texture_dims: Vec<(u32, u32)>, + texture_indices: HashMap, +} + +const TEX: &[&str] = &["error", "gypsum", "earth", "a0"]; + +pub struct Texture { + pub index: u32, + pub dimensions: (u32, u32), + pub aspect: f32, +} + +impl TextureArray { + pub fn get_texture(&self, name: &str) -> Texture { + let index = match self.texture_indices.get(name) { + Some(x) => *x, + None => 0, // Default texture + }; + + let dimensions = self.texture_dims[index as usize]; + + return Texture { + index, + dimensions, + aspect: dimensions.0 as f32 / dimensions.1 as f32, + }; + } + + pub fn new(device: &wgpu::Device, queue: &wgpu::Queue) -> Result { + let mut textures: Vec = Vec::new(); + let mut texture_indices: HashMap = HashMap::new(); + + let mut i = 0; + for t in TEX { + let p = format!("assets/{t}.png"); + let mut f = File::open(&p)?; + let mut bytes = Vec::new(); + f.read_to_end(&mut bytes)?; + textures.push(RawTexture::from_bytes(&device, &queue, &bytes, &p).unwrap()); + texture_indices.insert(t.to_string(), i); + i += 1; + } + + // One of these overall + let sampler = device.create_sampler(&wgpu::SamplerDescriptor { + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + mag_filter: wgpu::FilterMode::Linear, + min_filter: wgpu::FilterMode::Nearest, + mipmap_filter: wgpu::FilterMode::Nearest, + ..Default::default() + }); + + let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("texture_bind_group_layout"), + entries: &[ + // Texture data + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Texture { + multisampled: false, + view_dimension: wgpu::TextureViewDimension::D2, + sample_type: wgpu::TextureSampleType::Float { filterable: true }, + }, + count: NonZeroU32::new(textures.len() as u32), + }, + // Texture sampler + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), + count: NonZeroU32::new(textures.len() as u32), + }, + ], + }); + + let views: Vec<&wgpu::TextureView> = textures.iter().map(|x| &x.view).collect(); + let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: Some("texture_bind_group"), + layout: &bind_group_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + // Array of all views + resource: wgpu::BindingResource::TextureViewArray(&views), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::SamplerArray(&[&sampler].repeat(views.len())), + }, + ], + }); + + return Ok(Self { + bind_group, + bind_group_layout, + texture_dims: textures.iter().map(|x| x.dimensions).collect(), + texture_indices, + }); + } +} diff --git a/src/ship.rs b/src/ship.rs index 14b8d39..1a4ba24 100644 --- a/src/ship.rs +++ b/src/ship.rs @@ -1,8 +1,7 @@ use crate::physics::Cartesian; use crate::physics::PhysBody; -use crate::DrawContext; -use crate::Drawable; -use crate::SpriteAtlas; +use crate::Camera; +use crate::Sprite; pub enum ShipKind { Gypsum, @@ -11,7 +10,7 @@ pub enum ShipKind { impl ShipKind { fn sprite(&self) -> &'static str { match self { - Self::Gypsum => "gypsum.png", + Self::Gypsum => "gypsum", } } } @@ -29,20 +28,13 @@ impl Ship { } } - /// Get the position of this drawable on the screen - /// (0, 0) is at top-left corner. - /// - /// Returned position is this object's center. - fn screen_position(&self, dc: &DrawContext) -> Cartesian { - return ((self.body.pos - dc.camera.pos) - dc.top_left) * Cartesian::new(1.0, -1.0); - } -} + pub fn sprite(&self, camera: &Camera) -> Sprite { + let p = self.body.pos - camera.pos; -impl Drawable for Ship { - fn draw(&self, dc: &mut DrawContext, sa: &SpriteAtlas) -> Result<(), String> { - let pos = self.screen_position(dc); - let sprite = sa.get(self.kind.sprite()); - sprite.draw(dc.canvas, pos, self.body.angle.to_degrees(), 1.0)?; - return Ok(()); + return Sprite { + position: (p.x, p.y), + name: self.kind.sprite().to_owned(), + angle: self.body.angle as f32, + }; } } diff --git a/src/sprite.rs b/src/sprite.rs deleted file mode 100644 index 3a99f9f..0000000 --- a/src/sprite.rs +++ /dev/null @@ -1,130 +0,0 @@ -use image::io::Reader as ImageReader; -use sdl2::{ - rect::{Point, Rect}, - render::{Canvas, Texture, TextureCreator}, - video::{Window, WindowContext}, -}; - -use std::collections::HashMap; - -use crate::physics::Cartesian; - -/// A handle for a sprite inside a SpriteAtlas -pub struct Sprite<'a> { - texture: &'a Texture<'a>, - rect: Rect, - scale: f64, -} - -impl<'a> Sprite<'a> { - /// Draw this sprite on the screen. - /// - /// Position represents the center of the sprite - /// on-screen position, NOT in the world. - pub fn draw( - &self, - canvas: &mut Canvas, - position: Cartesian, - angle: f64, - scale: f64, - ) -> Result<(), String> { - let win_size = Cartesian::from(canvas.window().size()); - let scale = scale * self.scale; - - // Post-scale dimensions on the screen - let width = self.rect.width() as f64 * scale; - let height = self.rect.height() as f64 * scale; - - // Don't draw if we're not on the screen. - // An offset is included to ensure we're completely - // off the screen. We add the whole width intentionally. - if position.x < -1.0 * (width as f64) - || position.x > win_size.x + width as f64 - || position.y < -1.0 * (height as f64) - || position.y > win_size.y + height as f64 - { - return Ok(()); - } - - let mut dest = Rect::new(0, 0, width as u32, height as u32); - dest.center_on(Point::new((position.x) as i32, (position.y) as i32)); - - // copy the frame to the canvas - canvas.copy_ex( - &self.texture, - Some(self.rect), - Some(dest), - angle, // angle - Point::new((width / 2.0) as i32, (height / 2.0) as i32), // Rotation center - false, - false, - )?; - - return Ok(()); - } -} - -/// A cache of textures we use when drawing the screen. -/// -/// This is implemented very carefully, since SDL2 textures have tricky lifetimes. -pub struct SpriteAtlas<'a> { - data: HashMap, Rect, f64)>, -} - -impl<'a> SpriteAtlas<'a> { - pub fn new(texture_creator: &'a TextureCreator) -> Result { - let mut b = Self { - data: HashMap::new(), - }; - - b.load_one(texture_creator, "gypsum.png", 0.75)?; - b.load_one(texture_creator, "a0.png", 1.0)?; - b.load_one(texture_creator, "small.png", 1.0)?; - b.load_one(texture_creator, "earth.png", 1.0)?; - - return Ok(b); - } - - pub fn get(&'a self, name: &str) -> Sprite<'a> { - let (texture, rect, scale) = self.data.get(name).unwrap(); - return Sprite { - texture, - scale: scale.clone(), - rect: rect.clone(), - }; - } - - fn load_one( - &mut self, - texture_creator: &'a TextureCreator, - s: &str, - scale: f64, - ) -> Result<(), String> { - let im = ImageReader::open(format!("assets/{s}")) - .unwrap() - .decode() - .unwrap(); - let width = im.width(); - let height = im.height(); - let mut im = im.as_bytes().to_vec(); - - let surface = sdl2::surface::Surface::from_data( - &mut im, - width, - height, - width * 4, - sdl2::pixels::PixelFormatEnum::RGBA32, - )?; - - let texture = texture_creator - .create_texture_from_surface(&surface) - .map_err(|e| e.to_string())?; - - self.data.insert( - s.to_owned(), - (texture, Rect::new(0, 0, width, height), scale), - ); - - return Ok(()); - } -} diff --git a/src/system.rs b/src/system.rs index 1a473a9..d8a81b4 100644 --- a/src/system.rs +++ b/src/system.rs @@ -1,189 +1,37 @@ -use crate::{ - physics::Cartesian, physics::Polar, physics::WorldPosition, sprite::SpriteAtlas, Doodad, - DrawContext, Drawable, -}; -use rand::Rng; -use sdl2::{gfx::primitives::DrawRenderer, pixels::Color}; - -struct StarField { - stars: Vec, - width: f64, - height: f64, -} - -impl StarField { - fn new(width: f64, height: f64, d: f64) -> Self { - let mut s = StarField { - stars: Vec::new(), - width, - height, - }; - - let mut num = rand::thread_rng(); - let area = (width / 100.0) * (height / 100.0); - let n = (area * d) as i32; - for _ in 0..n { - s.stars.push(WorldPosition::new( - Cartesian::new( - num.gen_range(-width / 2.0..width / 2.0), - num.gen_range(-height / 2.0..height / 2.0), - ), - num.gen_range(3f64..4f64), - )) - } - - return s; - } - - fn draw_with_offset( - &self, - dc: &DrawContext, - pos_in_field: Cartesian, - offset: Cartesian, - ) -> Result<(), String> { - for wp in &self.stars { - // Coordinate of star on screen, - // with (0, 0) at top left - let p: Cartesian = wp.pos.into(); - let q = - ((p - pos_in_field + offset) / wp.par - dc.top_left) * Cartesian::new(1.0, -1.0); - - dc.canvas.filled_circle( - q.x as i16, - q.y as i16, - (5.0 - (1.0 * wp.par)) as i16, - Color::RGB(100, 100, 100), - )?; - } - return Ok(()); - } - - fn draw(&mut self, dc: &mut DrawContext, _sa: &SpriteAtlas) -> Result<(), String> { - let w = self.width; - let h = self.height; - let ww = w / 2.0; - let hh = h / 2.0; - - // Camera position relative to the center of this field. - let pos_in_field = Cartesian::new( - dc.camera.pos.x.signum() * (((dc.camera.pos.x.abs() + ww) % w) - ww), - dc.camera.pos.y.signum() * (((dc.camera.pos.y.abs() + hh) % h) - hh), - ); - - // Center of this field, in world coordinates - let field_center = dc.camera.pos - pos_in_field; - - // Compute tile bounds. - // We use neighboring tiles' corners instead of this tile's corner to properly account for parallax. - // If we use the current tiles corners, we'll see stars appear when a tile is drawn--parallax moves them - // into view. The bounds below guarantee that no *other* tiles' stars will be drawn inside. - // - // bound_nw is the screen position of the bottom-right corner of north-west tile - // bound_se is the screen position of the top-right corner of south-east tile - let bound_nw = - WorldPosition::new(field_center + Cartesian::new(-ww, hh), 4.0).screen_position(dc); - let bound_se = - WorldPosition::new(field_center + Cartesian::new(ww, -hh), 4.0).screen_position(dc); - - // Naturally, we show tiles only if we can see their edges. - let north = bound_nw.y > 0.0; - let south = bound_se.y < dc.window_size.y; - let east = bound_se.x < dc.window_size.x; - let west = bound_nw.x > 0.0; - - // Draw center tile - self.draw_with_offset(dc, pos_in_field, Cartesian::new(0.0, 0.0))?; - - // Draw surrounding tiles - // (which are just offset clones of the main one) - if north { - self.draw_with_offset(dc, pos_in_field, Cartesian::new(0.0, h))?; - } - if south { - self.draw_with_offset(dc, pos_in_field, Cartesian::new(0.0, -h))?; - } - if east { - self.draw_with_offset(dc, pos_in_field, Cartesian::new(w, 0.0))?; - } - if west { - self.draw_with_offset(dc, pos_in_field, Cartesian::new(-w, 0.0))?; - } - if north && east { - self.draw_with_offset(dc, pos_in_field, Cartesian::new(w, h))?; - } - if north && west { - self.draw_with_offset(dc, pos_in_field, Cartesian::new(-w, h))?; - } - if south && east { - self.draw_with_offset(dc, pos_in_field, Cartesian::new(w, -h))?; - } - if south && west { - self.draw_with_offset(dc, pos_in_field, Cartesian::new(-w, -h))?; - } - - // draw_circle doesn't clean up the color it uses, so we do that here. - dc.canvas.set_draw_color(Color::RGB(0, 0, 0)); - return Ok(()); - } -} +use crate::{physics::Cartesian, physics::Polar, Camera, Doodad, Sprite}; pub struct System { - bodies: Vec>, - starfield: StarField, + bodies: Vec, } impl System { pub fn new() -> Self { - let mut s = System { - bodies: Vec::new(), - starfield: StarField::new(6000.0, 6000.0, 1.0), - }; + let mut s = System { bodies: Vec::new() }; - s.bodies.push(Box::new(Doodad { - pos: WorldPosition::new(Cartesian::new(0.0, 0.0), 2.0), - sprite: "a0.png".to_owned(), - scale: 1, - angle: 0.0, - })); + s.bodies.push(Doodad { + pos: Cartesian::new(0.0, 0.0), + sprite: "a0".to_owned(), + }); - s.bodies.push(Box::new(Doodad { - pos: WorldPosition::new( - Polar { - center: Cartesian::new(0.0, 0.0), - radius: 300.0, - angle: 31.0, - } - .into(), - 1.5, - ), - sprite: "earth.png".to_owned(), - scale: 1, - angle: (180f64).to_radians(), - })); + s.bodies.push(Doodad { + pos: Polar { + center: Cartesian::new(0.0, 0.0), + radius: 300.0, + angle: 31.0, + } + .into(), + sprite: "earth".to_owned(), + }); - s.bodies.push(Box::new(Doodad { - pos: WorldPosition::new(Cartesian::new(1000.0, 1000.0), 2.0), - sprite: "small.png".to_owned(), - scale: 1, - angle: 0.0, - })); + s.bodies.push(Doodad { + pos: Cartesian::new(1000.0, 1000.0), + sprite: "small".to_owned(), + }); return s; } - /// Calculate the state of this body after t seconds. - pub fn tick(&mut self, _t: f64) { - //let body = &mut self.bodies[1]; - //body.pos.angle += 0.1 * t; - //body.angle -= 0.1 * t; - } - - pub fn draw(&mut self, dc: &mut DrawContext, sa: &SpriteAtlas) -> Result<(), String> { - self.starfield.draw(dc, sa)?; - for body in &self.bodies { - body.draw(dc, sa)?; - } - - return Ok(()); + pub fn sprites(&self, camera: &Camera) -> Vec { + return self.bodies.iter().map(|x| x.sprite(camera)).collect(); } }