From 604c1b9a5712a8858a3ed3bfc8feb2750c7ea9f8 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sat, 6 Jan 2024 20:41:43 +0100 Subject: [PATCH 01/58] Update dependencies to latest versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before upgrading, I got the following error when running rust-doom on Ubuntu 23.10: ``` [INFO engine::context] Creating system "tick"... │ [INFO engine::context] Creating system "frame_timers"... │ [INFO engine::context] Creating system "window"... │ interface 'wl_output' has no event 4 │ thread 'main' panicked at /home/hovinen/.cargo/registry/src/index.crates.io-6f17d22bba15001f/winit-0.21.0/src/platform_impl/linux/wayland/event_loop.rs:395:10: │ called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" } │ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace │ ``` This attempts to do just the minimum needed to bring winit and glium up to their latest versions. This requires several changes due to API changes in those libraries. Other than that, I am avoiding any rearchitecting or other changes. After upgrading, the program runs without crashing. One can navigate the levels, but the graphics and animation are a messed up. I don't know the code well enough to be able to fix that problem easily. --- Cargo.lock | 1665 +++++++++++++++++++++++++++----------- Cargo.toml | 4 +- engine/Cargo.toml | 9 +- engine/src/context.rs | 87 +- engine/src/errors.rs | 14 +- engine/src/input.rs | 45 +- engine/src/lib.rs | 2 +- engine/src/platform.rs | 2 - engine/src/window.rs | 51 +- engine_derive/Cargo.toml | 2 +- game/Cargo.toml | 3 +- game/src/game.rs | 10 +- game/src/hud.rs | 18 +- game/src/player.rs | 27 +- src/main.rs | 2 +- wad/Cargo.toml | 4 +- wad/src/meta.rs | 6 +- 17 files changed, 1324 insertions(+), 627 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d985668..66a2179 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,17 @@ # This file is automatically @generated by Cargo. # 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 0.20.0", +] + [[package]] name = "ab_glyph_rasterizer" version = "0.1.4" @@ -21,6 +33,19 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "0.7.15" @@ -31,24 +56,31 @@ dependencies = [ ] [[package]] -name = "andrew" -version = "0.2.1" +name = "android-activity" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7f09f89872c2b6b29e319377b1fbe91c6f5947df19a25596e121cf19a7b35e" +checksum = "39b801912a977c3fd52d80511fe1c0c8480c6f957f21ae2ce1b92ffe970cf4b9" dependencies = [ - "bitflags", - "line_drawing", - "rusttype 0.7.9", - "walkdir", - "xdg", - "xml-rs", + "android-properties", + "bitflags 2.4.1", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum", + "thiserror", ] [[package]] -name = "android_glue" -version = "0.2.3" +name = "android-properties" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" [[package]] name = "ansi_term" @@ -56,26 +88,41 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] name = "approx" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3" +checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" dependencies = [ "num-traits", ] [[package]] -name = "approx" -version = "0.4.0" +name = "arrayref" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278" -dependencies = [ - "num-traits", -] +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "atty" @@ -83,9 +130,9 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.18", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -101,7 +148,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d117600f438b1707d4e4ae15d3595657288f8235a0eb593e80ecc98ab34e1bc" dependencies = [ "addr2line", - "cfg-if 1.0.0", + "cfg-if", "libc", "miniz_oxide", "object", @@ -125,10 +172,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] -name = "block" -version = "0.1.6" +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "block-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dd7cf50912cddc06dc5ea7c08c5e81c1b2c842a70d19def1848d54c586fed92" +dependencies = [ + "objc-sys", +] + +[[package]] +name = "block2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" +dependencies = [ + "block-sys", + "objc2", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "bytemuck" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" [[package]] name = "byteorder" @@ -136,15 +214,36 @@ version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + [[package]] name = "calloop" -version = "0.4.4" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aa2097be53a00de9e8fc349fea6d76221f398f5c4fa550d420669906962d160" +checksum = "7b50b5a44d59a98c55a9eeb518f39bf7499ba19fd98ee7d22618687f3f10adbf" dependencies = [ - "mio", - "mio-extras", - "nix", + "bitflags 2.4.1", + "log", + "polling", + "rustix", + "slab", + "thiserror", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" +dependencies = [ + "calloop", + "rustix", + "wayland-backend", + "wayland-client", ] [[package]] @@ -152,12 +251,15 @@ name = "cc" version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" +dependencies = [ + "jobserver", +] [[package]] -name = "cfg-if" -version = "0.1.10" +name = "cesu8" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfg-if" @@ -165,6 +267,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "cgl" version = "0.3.2" @@ -180,7 +288,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a98d30140e3296250832bbaaff83b27dcd6fa3cc70fb6f1f3e5c9c0023b5317" dependencies = [ - "approx 0.4.0", + "approx", "num-traits", ] @@ -192,7 +300,7 @@ checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ "ansi_term", "atty", - "bitflags", + "bitflags 1.2.1", "strsim", "textwrap", "unicode-width", @@ -205,93 +313,83 @@ version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "bitflags", + "bitflags 1.2.1", ] [[package]] -name = "cocoa" -version = "0.19.1" +name = "combine" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29f7768b2d1be17b96158e3285951d366b40211320fb30826a76cb7a0da6400" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" dependencies = [ - "bitflags", - "block", - "core-foundation 0.6.4", - "core-graphics 0.17.3", - "foreign-types", - "libc", - "objc", + "bytes", + "memchr", ] [[package]] -name = "core-foundation" -version = "0.6.4" +name = "concurrent-queue" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" dependencies = [ - "core-foundation-sys 0.6.2", - "libc", + "crossbeam-utils", ] [[package]] name = "core-foundation" -version = "0.7.0" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ - "core-foundation-sys 0.7.0", + "core-foundation-sys", "libc", ] [[package]] name = "core-foundation-sys" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" - -[[package]] -name = "core-foundation-sys" -version = "0.7.0" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core-graphics" -version = "0.17.3" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56790968ab1c8a1202a102e6de05fc6e1ec87da99e4e93e9a7d13efbfc1e95a9" +checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212" dependencies = [ - "bitflags", - "core-foundation 0.6.4", + "bitflags 1.2.1", + "core-foundation", + "core-graphics-types", "foreign-types", "libc", ] [[package]] -name = "core-graphics" -version = "0.19.2" +name = "core-graphics-types" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ - "bitflags", - "core-foundation 0.7.0", - "foreign-types", + "bitflags 1.2.1", + "core-foundation", "libc", ] [[package]] -name = "core-video-sys" -version = "0.1.4" +name = "crossbeam-utils" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" +checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" dependencies = [ - "cfg-if 0.1.10", - "core-foundation-sys 0.7.0", - "core-graphics 0.19.2", - "libc", - "objc", + "cfg-if", ] +[[package]] +name = "cursor-icon" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" + [[package]] name = "dispatch" version = "0.2.0" @@ -300,11 +398,11 @@ checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" [[package]] name = "dlib" -version = "0.4.2" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b11f15d1e3268f140f68d390637d5e76d849782d971ae7063e0da69fe9709a76" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading 0.6.7", + "libloading", ] [[package]] @@ -327,32 +425,49 @@ dependencies = [ "log", "math", "num-traits", - "rusttype 0.9.2", + "rusttype", "unicode-normalization", + "winit", ] [[package]] name = "engine_derive" version = "0.1.0" dependencies = [ - "proc-macro2 1.0.26", - "quote 1.0.9", - "syn", + "proc-macro2", + "quote", + "syn 2.0.48", ] [[package]] name = "env_logger" -version = "0.8.3" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" dependencies = [ - "atty", "humantime", + "is-terminal", "log", "regex", "termcolor", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "failchain" version = "0.1018.2" @@ -378,9 +493,9 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ - "proc-macro2 1.0.26", - "quote 1.0.9", - "syn", + "proc-macro2", + "quote", + "syn 1.0.68", "synstructure", ] @@ -392,18 +507,30 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foreign-types" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ + "foreign-types-macros", "foreign-types-shared", ] +[[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.48", +] + [[package]] name = "foreign-types-shared" -version = "0.1.1" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "fuchsia-cprng" @@ -411,22 +538,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - [[package]] name = "game" version = "0.1.0" @@ -440,6 +551,28 @@ dependencies = [ "math", "vec_map", "wad", + "winit", +] + +[[package]] +name = "gethostname" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +dependencies = [ + "libc", + "windows-targets 0.48.5", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", ] [[package]] @@ -461,25 +594,27 @@ dependencies = [ [[package]] name = "glium" -version = "0.26.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a46e88b2c64cfa63d54ed54dc2a0d25136470eb1721e10be49d857ab583f8663" +checksum = "94d5813c960a54b76e20fe4ef7e54fbeb12545776a11ecf14f42a946a1c65964" dependencies = [ "backtrace", "fnv", "gl_generator", "glutin", + "glutin-winit", "lazy_static", - "memoffset", + "memoffset 0.9.0", + "raw-window-handle 0.5.2", "smallvec", "takeable-option", + "winit", ] [[package]] name = "glium-typed-buffer-any" version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10bbb7843348dc7b6da12810451ab77e4417d6e7ca569fd787775bcf6ad7a2c4" +source = "git+https://github.com/hovinen/glium-typed-buffer-any?branch=update-dependency#7345beb3904df211d699ee05875934cc7ac20b55" dependencies = [ "glium", "smallvec", @@ -487,62 +622,55 @@ dependencies = [ [[package]] name = "glutin" -version = "0.23.0" +version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf22d4e90c55d9be9f2ad52410e7a2c0d7e9c99d93a13df73a672e7ef4e8c7f7" +checksum = "005459a22af86adc706522d78d360101118e2638ec21df3852fcc626e0dbb212" dependencies = [ - "android_glue", + "bitflags 2.4.1", + "cfg_aliases", "cgl", - "cocoa", - "core-foundation 0.6.4", - "core-graphics 0.17.3", + "core-foundation", + "dispatch", "glutin_egl_sys", - "glutin_emscripten_sys", - "glutin_gles2_sys", "glutin_glx_sys", "glutin_wgl_sys", - "lazy_static", - "libloading 0.5.2", - "log", - "objc", - "osmesa-sys", - "parking_lot", - "wayland-client", - "winapi 0.3.9", - "winit", + "icrate", + "libloading", + "objc2", + "once_cell", + "raw-window-handle 0.5.2", + "wayland-sys", + "windows-sys 0.48.0", + "x11-dl", ] [[package]] -name = "glutin_egl_sys" -version = "0.1.5" +name = "glutin-winit" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2abb6aa55523480c4adc5a56bbaa249992e2dddb2fc63dc96e04a3355364c211" +checksum = "1ebcdfba24f73b8412c5181e56f092b5eff16671c514ce896b258a0a64bd7735" dependencies = [ - "gl_generator", - "winapi 0.3.9", + "cfg_aliases", + "glutin", + "raw-window-handle 0.5.2", + "winit", ] [[package]] -name = "glutin_emscripten_sys" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80de4146df76e8a6c32b03007bc764ff3249dcaeb4f675d68a06caf1bac363f1" - -[[package]] -name = "glutin_gles2_sys" -version = "0.1.5" +name = "glutin_egl_sys" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094e708b730a7c8a1954f4f8a31880af00eb8a1c5b5bf85d28a0a3c6d69103" +checksum = "77cc5623f5309ef433c3dd4ca1223195347fe62c413da8e2fdd0eb76db2d9bcd" dependencies = [ "gl_generator", - "objc", + "windows-sys 0.48.0", ] [[package]] name = "glutin_glx_sys" -version = "0.1.7" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e393c8fc02b807459410429150e9c4faffdb312d59b8c038566173c81991351" +checksum = "a165fd686c10dcc2d45380b35796e577eacfd43d4660ee741ec8ebe2201b3b4f" dependencies = [ "gl_generator", "x11-dl", @@ -550,18 +678,18 @@ dependencies = [ [[package]] name = "glutin_wgl_sys" -version = "0.1.5" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da5951a1569dbab865c6f2a863efafff193a93caf05538d193e9e3816d21696" +checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" dependencies = [ "gl_generator", ] [[package]] name = "hashbrown" -version = "0.9.1" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "heck" @@ -581,12 +709,29 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "icrate" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" +dependencies = [ + "block2", + "dispatch", + "objc2", +] + [[package]] name = "idcontain" version = "0.7.6" @@ -598,40 +743,63 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.6.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ - "autocfg", + "equivalent", "hashbrown", ] [[package]] -name = "instant" -version = "0.1.9" +name = "is-terminal" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" dependencies = [ - "cfg-if 1.0.0", + "hermit-abi 0.3.3", + "rustix", + "windows-sys 0.52.0", ] [[package]] -name = "iovec" -version = "0.1.4" +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" dependencies = [ "libc", ] [[package]] -name = "kernel32-sys" -version = "0.2.2" +name = "js-sys" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "wasm-bindgen", ] [[package]] @@ -646,55 +814,38 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "libc" -version = "0.2.92" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56d855069fafbb9b344c0f962150cd2c1187975cb1c22c1522c240d8c4986714" - -[[package]] -name = "libloading" -version = "0.5.2" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" -dependencies = [ - "cc", - "winapi 0.3.9", -] +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libloading" -version = "0.6.7" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" dependencies = [ - "cfg-if 1.0.0", - "winapi 0.3.9", + "cfg-if", + "windows-sys 0.48.0", ] [[package]] -name = "line_drawing" -version = "0.7.0" +name = "libredox" +version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc7ad3d82c845bdb5dde34ffdcc7a5fb4d2996e1e1ee0f19c33bc80e15196b9" +checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" dependencies = [ - "num-traits", + "bitflags 2.4.1", + "libc", + "redox_syscall 0.4.1", ] [[package]] -name = "lock_api" -version = "0.3.4" +name = "linux-raw-sys" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" -dependencies = [ - "scopeguard", -] +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "log" @@ -702,16 +853,7 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", + "cfg-if", ] [[package]] @@ -722,112 +864,90 @@ dependencies = [ "num-traits", ] -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - [[package]] name = "memchr" -version = "2.3.4" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] -name = "memmap" -version = "0.7.0" +name = "memmap2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +checksum = "45fd3a57831bf88bc63f8cebc0cf956116276e97fef3966103e96416209f7c92" dependencies = [ "libc", - "winapi 0.3.9", ] [[package]] name = "memoffset" -version = "0.5.6" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ "autocfg", ] [[package]] -name = "miniz_oxide" -version = "0.4.4" +name = "memoffset" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ - "adler", "autocfg", ] [[package]] -name = "mio" -version = "0.6.23" +name = "miniz_oxide" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow", - "net2", - "slab", - "winapi 0.2.8", + "adler", + "autocfg", ] [[package]] -name = "mio-extras" -version = "2.0.6" +name = "ndk" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" dependencies = [ - "lazycell", + "bitflags 2.4.1", + "jni-sys", "log", - "mio", - "slab", + "ndk-sys", + "num_enum", + "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", + "thiserror", ] [[package]] -name = "miow" -version = "0.2.2" +name = "ndk-context" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", -] +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" [[package]] -name = "net2" -version = "0.2.37" +name = "ndk-sys" +version = "0.5.0+25.2.9519653" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", + "jni-sys", ] [[package]] name = "nix" -version = "0.14.1" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ - "bitflags", - "cc", - "cfg-if 0.1.10", + "bitflags 1.2.1", + "cfg-if", "libc", - "void", + "memoffset 0.7.1", ] [[package]] @@ -840,69 +960,85 @@ dependencies = [ ] [[package]] -name = "objc" -version = "0.2.7" +name = "num_enum" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +checksum = "683751d591e6d81200c39fb0d1032608b77724f34114db54f571ff1317b337c0" dependencies = [ - "malloc_buf", + "num_enum_derive", ] [[package]] -name = "object" -version = "0.23.0" +name = "num_enum_derive" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4" +checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.48", +] [[package]] -name = "ordered-float" -version = "1.1.1" +name = "objc-sys" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3305af35278dd29f46fcdd139e0b1fbfae2153f0e5928b39b035542dd31e37b7" -dependencies = [ - "num-traits", -] +checksum = "c7c71324e4180d0899963fc83d9d241ac39e699609fc1025a850aadac8257459" [[package]] -name = "osmesa-sys" -version = "0.1.2" +name = "objc2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b" +checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" dependencies = [ - "shared_library", + "objc-sys", + "objc2-encode", ] [[package]] -name = "owned_ttf_parser" -version = "0.6.0" +name = "objc2-encode" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f923fb806c46266c02ab4a5b239735c144bdeda724a50ed058e5226f594cde3" +checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" + +[[package]] +name = "object" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4" + +[[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 = [ - "ttf-parser", + "libredox", ] [[package]] -name = "parking_lot" -version = "0.10.2" +name = "owned_ttf_parser" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +checksum = "9f923fb806c46266c02ab4a5b239735c144bdeda724a50ed058e5226f594cde3" dependencies = [ - "lock_api", - "parking_lot_core", + "ttf-parser 0.6.2", ] [[package]] -name = "parking_lot_core" -version = "0.7.2" +name = "owned_ttf_parser" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +checksum = "d4586edfe4c648c71797a74c84bacb32b52b212eff5dfe2bb9f2c599844023e7" dependencies = [ - "cfg-if 0.1.10", - "cloudabi", - "libc", - "redox_syscall", - "smallvec", - "winapi 0.3.9", + "ttf-parser 0.20.0", ] [[package]] @@ -911,11 +1047,40 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + [[package]] name = "pkg-config" -version = "0.3.19" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" + +[[package]] +name = "polling" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" +dependencies = [ + "cfg-if", + "concurrent-queue", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.2", +] [[package]] name = "proc-macro-error" @@ -924,9 +1089,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.26", - "quote 1.0.9", - "syn", + "proc-macro2", + "quote", + "syn 1.0.68", "version_check", ] @@ -936,45 +1101,36 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.26", - "quote 1.0.9", + "proc-macro2", + "quote", "version_check", ] [[package]] name = "proc-macro2" -version = "0.4.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" -dependencies = [ - "unicode-xid 0.1.0", -] - -[[package]] -name = "proc-macro2" -version = "1.0.26" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ - "unicode-xid 0.2.1", + "unicode-ident", ] [[package]] -name = "quote" -version = "0.6.13" +name = "quick-xml" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" dependencies = [ - "proc-macro2 0.4.30", + "memchr", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ - "proc-macro2 1.0.26", + "proc-macro2", ] [[package]] @@ -987,7 +1143,7 @@ dependencies = [ "fuchsia-cprng", "libc", "rand_core 0.3.1", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1007,18 +1163,33 @@ checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" [[package]] name = "raw-window-handle" -version = "0.3.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + +[[package]] +name = "raw-window-handle" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544" + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "libc", + "bitflags 1.2.1", ] [[package]] name = "redox_syscall" -version = "0.1.57" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.2.1", +] [[package]] name = "regex" @@ -1058,23 +1229,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" [[package]] -name = "rusttype" -version = "0.7.9" +name = "rustix" +version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "310942406a39981bed7e12b09182a221a29e0990f3e7e0c971f131922ed135d5" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ - "rusttype 0.8.3", -] - -[[package]] -name = "rusttype" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f61411055101f7b60ecf1041d87fb74205fb20b0c7a723f07ef39174cf6b4c0" -dependencies = [ - "approx 0.3.2", - "ordered-float", - "stb_truetype", + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1084,7 +1248,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc7c727aded0be18c5b80c1640eae0ac8e396abf6fa8477d96cb37d18ee5ec59" dependencies = [ "ab_glyph_rasterizer", - "owned_ttf_parser", + "owned_ttf_parser 0.6.0", ] [[package]] @@ -1097,78 +1261,108 @@ dependencies = [ ] [[package]] -name = "scopeguard" -version = "1.1.0" +name = "scoped-tls" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "sctk-adwaita" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b2eaf3a5b264a521b988b2e73042e742df700c4f962cde845d1541adb46550" +dependencies = [ + "ab_glyph", + "log", + "memmap2", + "smithay-client-toolkit", + "tiny-skia", +] [[package]] name = "serde" -version = "1.0.125" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.125" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ - "proc-macro2 1.0.26", - "quote 1.0.9", - "syn", + "proc-macro2", + "quote", + "syn 2.0.48", ] [[package]] -name = "shared_library" -version = "0.1.9" +name = "serde_spanned" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ - "lazy_static", - "libc", + "serde", ] [[package]] name = "slab" -version = "0.4.2" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] [[package]] name = "smallvec" -version = "1.6.1" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "smithay-client-toolkit" -version = "0.6.6" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "421c8dc7acf5cb205b88160f8b4cc2c5cfabe210e43b2f80f009f4c1ef910f1d" +checksum = "60e3d9941fa3bacf7c2bf4b065304faa14164151254cd16ce1b1bc8fc381600f" dependencies = [ - "andrew", - "bitflags", - "dlib", - "lazy_static", - "memmap", - "nix", + "bitflags 2.4.1", + "calloop", + "calloop-wayland-source", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix", + "thiserror", + "wayland-backend", "wayland-client", + "wayland-csd-frame", + "wayland-cursor", "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", ] [[package]] -name = "stb_truetype" -version = "0.3.1" +name = "smol_str" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f77b6b07e862c66a9f3e62a07588fee67cd90a9135a2b942409f195507b4fb51" +checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" dependencies = [ - "byteorder", + "serde", ] +[[package]] +name = "strict-num" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" + [[package]] name = "strsim" version = "0.8.0" @@ -1194,9 +1388,9 @@ checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90" dependencies = [ "heck", "proc-macro-error", - "proc-macro2 1.0.26", - "quote 1.0.9", - "syn", + "proc-macro2", + "quote", + "syn 1.0.68", ] [[package]] @@ -1205,9 +1399,20 @@ version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ce15dd3ed8aa2f8eeac4716d6ef5ab58b6b9256db41d7e1a0224c2788e8fd87" dependencies = [ - "proc-macro2 1.0.26", - "quote 1.0.9", - "unicode-xid 0.2.1", + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] @@ -1216,10 +1421,10 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" dependencies = [ - "proc-macro2 1.0.26", - "quote 1.0.9", - "syn", - "unicode-xid 0.2.1", + "proc-macro2", + "quote", + "syn 1.0.68", + "unicode-xid", ] [[package]] @@ -1246,6 +1451,51 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tiny-skia" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6a067b809476893fce6a254cf285850ff69c847e6cfbade6a20b655b6c7e80d" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "log", + "tiny-skia-path", +] + +[[package]] +name = "tiny-skia-path" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de35e8a90052baaaf61f171680ac2f8e925a1e43ea9d2e3a00514772250e541" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + [[package]] name = "tinyvec" version = "1.1.1" @@ -1263,19 +1513,83 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "toml" -version = "0.5.8" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.21.0", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ + "indexmap", "serde", + "serde_spanned", + "toml_datetime", + "winnow", ] +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" + [[package]] name = "ttf-parser" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc" +[[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-normalization" version = "0.1.17" @@ -1297,12 +1611,6 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" - [[package]] name = "unicode-xid" version = "0.2.1" @@ -1317,15 +1625,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wad" @@ -1351,75 +1653,210 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" dependencies = [ "same-file", - "winapi 0.3.9", + "winapi", "winapi-util", ] [[package]] -name = "wayland-client" -version = "0.23.6" +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1080ebe0efabcf12aef2132152f616038f2d7dcbbccf7b2d8c5270fe14bcda" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ - "bitflags", - "calloop", + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.48", + "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.48", + "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-backend" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19152ddd73f45f024ed4534d9ca2594e0ef252c1847695255dae47f34df9fbe4" +dependencies = [ + "cc", "downcast-rs", - "libc", - "mio", "nix", - "wayland-commons", - "wayland-scanner", + "scoped-tls", + "smallvec", "wayland-sys", ] [[package]] -name = "wayland-commons" -version = "0.23.6" +name = "wayland-client" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb66b0d1a27c39bbce712b6372131c6e25149f03ffb0cd017cf8f7de8d66dbdb" +checksum = "1ca7d52347346f5473bf2f56705f360e8440873052e575e55890c4fa57843ed3" dependencies = [ + "bitflags 2.4.1", "nix", - "wayland-sys", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-csd-frame" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.4.1", + "cursor-icon", + "wayland-backend", +] + +[[package]] +name = "wayland-cursor" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44aa20ae986659d6c77d64d808a046996a932aa763913864dc40c359ef7ad5b" +dependencies = [ + "nix", + "wayland-client", + "xcursor", ] [[package]] name = "wayland-protocols" -version = "0.23.6" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cc286643656742777d55dc8e70d144fa4699e426ca8e9d4ef454f4bf15ffcf9" +checksum = "e253d7107ba913923dc253967f35e8561a3c65f914543e46843c88ddd729e21c" dependencies = [ - "bitflags", + "bitflags 2.4.1", + "wayland-backend", "wayland-client", - "wayland-commons", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" +dependencies = [ + "bitflags 2.4.1", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" +dependencies = [ + "bitflags 2.4.1", + "wayland-backend", + "wayland-client", + "wayland-protocols", "wayland-scanner", ] [[package]] name = "wayland-scanner" -version = "0.23.6" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93b02247366f395b9258054f964fe293ddd019c3237afba9be2ccbe9e1651c3d" +checksum = "fb8e28403665c9f9513202b7e1ed71ec56fde5c107816843fb14057910b2c09c" dependencies = [ - "proc-macro2 0.4.30", - "quote 0.6.13", - "xml-rs", + "proc-macro2", + "quick-xml", + "quote", ] [[package]] name = "wayland-sys" -version = "0.23.6" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d94e89a86e6d6d7c7c9b19ebf48a03afaac4af6bc22ae570e9a24124b75358f4" +checksum = "15a0c8eaff5216d07f226cb7a549159267f3467b289d9a2e52fd3ef5aae2b7af" dependencies = [ "dlib", - "lazy_static", + "log", + "once_cell", + "pkg-config", ] [[package]] -name = "winapi" -version = "0.2.8" +name = "web-sys" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] [[package]] name = "winapi" @@ -1431,12 +1868,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -1449,7 +1880,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1458,65 +1889,341 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[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.21.0" +version = "0.29.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65a5c1a5ef76ac31cc97ad29489acdbed2178f3fc12ca00ee6cb11d60adb5a3a" +checksum = "c2376dab13e09c01ad8b679f0dbc7038af4ec43d9a91344338e37bd686481550" dependencies = [ - "android_glue", - "bitflags", - "cocoa", - "core-foundation 0.6.4", - "core-graphics 0.17.3", - "core-video-sys", - "dispatch", - "instant", - "lazy_static", + "ahash", + "android-activity", + "atomic-waker", + "bitflags 2.4.1", + "bytemuck", + "calloop", + "cfg_aliases", + "core-foundation", + "core-graphics", + "cursor-icon", + "icrate", + "js-sys", "libc", "log", - "mio", - "mio-extras", - "objc", - "parking_lot", + "memmap2", + "ndk", + "ndk-sys", + "objc2", + "once_cell", + "orbclient", "percent-encoding", - "raw-window-handle", + "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", + "redox_syscall 0.3.5", + "rustix", + "sctk-adwaita", "smithay-client-toolkit", + "smol_str", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", "wayland-client", - "winapi 0.3.9", + "wayland-protocols", + "wayland-protocols-plasma", + "web-sys", + "web-time", + "windows-sys 0.48.0", "x11-dl", + "x11rb", + "xkbcommon-dl", ] [[package]] -name = "ws2_32-sys" -version = "0.2.1" +name = "winnow" +version = "0.5.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +checksum = "b7520bbdec7211caa7c4e682eb1fbe07abe20cee6756b6e00f537c82c11816aa" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "memchr", ] [[package]] name = "x11-dl" -version = "2.18.5" +version = "2.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf981e3a5b3301209754218f962052d4d9ee97e478f4d26d4a6eced34c1fef8" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" dependencies = [ - "lazy_static", "libc", - "maybe-uninit", + "once_cell", "pkg-config", ] [[package]] -name = "xdg" -version = "2.2.0" +name = "x11rb" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading", + "once_cell", + "rustix", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57" +checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34" + +[[package]] +name = "xcursor" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a0ccd7b4a5345edfcd0c3535718a4e9ff7798ffc536bb5b5a0e26ff84732911" + +[[package]] +name = "xkbcommon-dl" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6924668544c48c0133152e7eec86d644a056ca3d09275eb8d5cdb9855f9d8699" +dependencies = [ + "bitflags 2.4.1", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054a8e68b76250b253f671d1268cb7f1ae089ec35e195b2efb2a4e9a836d0621" [[package]] name = "xml-rs" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" + +[[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.48", +] diff --git a/Cargo.toml b/Cargo.toml index 9001b26..3aceb9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ engine = { path = "engine" } game = { path = "game" } math = { path = "math" } -env_logger = "0.8.3" +env_logger = "0.10.1" structopt = "0.3.21" failure = "0.1.8" @@ -23,5 +23,3 @@ features = ["release_max_level_info"] version = "0.4.8" [workspace] - - diff --git a/engine/Cargo.toml b/engine/Cargo.toml index 56561df..a67d54a 100644 --- a/engine/Cargo.toml +++ b/engine/Cargo.toml @@ -8,13 +8,18 @@ edition = "2018" math = { path = "../math" } engine_derive = { path = "../engine_derive" } -glium-typed-buffer-any = "0.6.0" idcontain = "0.7.6" num-traits = "0.2.14" rusttype = "0.9.2" unicode-normalization = "0.1.17" failure = "0.1.8" failchain = "0.1018.2" +winit = "0.29.9" + +[dependencies.glium-typed-buffer-any] +version = "0.6.0" +git = "https://github.com/hovinen/glium-typed-buffer-any" +branch = "update-dependency" [dependencies.log] features = ["release_max_level_info"] @@ -22,7 +27,7 @@ version = "0.4.14" [dependencies.glium] features = ["glutin"] -version = "0.26" +version = "0.34.0" [dev-dependencies] env_logger = "*" diff --git a/engine/src/context.rs b/engine/src/context.rs index 40782ff..84fa31f 100644 --- a/engine/src/context.rs +++ b/engine/src/context.rs @@ -5,14 +5,14 @@ use super::type_list::{Cons, Nil, Peek, Pluck, PluckInto}; use super::window::Window; use failchain::ResultExt; use failure::{AsFail, Fail}; -use glium::glutin::event_loop::ControlFlow as GlutinControlFlow; use std::{marker::PhantomData, time::Instant}; +use winit::event_loop::ControlFlow as WinitControlFlow; pub trait Context { fn step(&mut self) -> Result<()>; fn destroy(&mut self) -> Result<()>; - fn run(self) -> !; + fn run(self) -> Result<()>; } pub struct ContextBuilder { @@ -162,53 +162,58 @@ where SystemListT::update_list(self.systems_mut()).chain_err(|| ErrorKind::Context("update")) } - fn run(mut self) -> ! { + fn run(mut self) -> Result<()> { let event_loop = { let window: &mut Window = self.systems_mut().peek_mut(); window.take_event_loop().expect("none event loop in window") }; - event_loop.run(move |event, _target, glutin_control_flow| { - if *glutin_control_flow == GlutinControlFlow::Exit { - return; - } - let input: &mut Input = self.systems_mut().peek_mut(); - if !input.handle_event(event) { - return; - } - let result = self.step().and_then(|_| { - let input: &mut Input = self.systems_mut().peek_mut(); - input.reset(); - let control_flow: &mut ControlFlow = self.systems_mut().peek_mut(); - *glutin_control_flow = control_flow - .sleep_until - .take() - .map_or(GlutinControlFlow::Poll, GlutinControlFlow::WaitUntil); - if !control_flow.quit_requested { - return Ok(()); + event_loop + .run(move |event, target| { + if target.exiting() { + return; } - *glutin_control_flow = GlutinControlFlow::Exit; - self.destroy() - }); - - if let Err(error) = result { - log::error!("Fatal error: {}", error); - let mut cause = error.as_fail(); - while let Some(new_cause) = cause.cause() { - cause = new_cause; - log::error!(" caused by: {}", cause); + let input: &mut Input = self.systems_mut().peek_mut(); + if !input.handle_event(event) { + return; } - if std::env::var("RUST_BACKTRACE") - .map(|value| value == "1") - .unwrap_or(false) - { - log::error!("Backtrace:\n{:?}", error.backtrace()); - } else { - log::error!("Run with RUST_BACKTRACE=1 to capture backtrace."); + let result = self.step().and_then(|_| { + let input: &mut Input = self.systems_mut().peek_mut(); + input.reset(); + let control_flow: &mut ControlFlow = self.systems_mut().peek_mut(); + target.set_control_flow( + control_flow + .sleep_until + .take() + .map_or(WinitControlFlow::Poll, WinitControlFlow::WaitUntil), + ); + if !control_flow.quit_requested { + return Ok(()); + } + target.exit(); + self.destroy() + }); + + if let Err(error) = result { + log::error!("Fatal error: {}", error); + let mut cause = error.as_fail(); + while let Some(new_cause) = cause.cause() { + cause = new_cause; + log::error!(" caused by: {}", cause); + } + if std::env::var("RUST_BACKTRACE") + .map(|value| value == "1") + .unwrap_or(false) + { + log::error!("Backtrace:\n{:?}", error.backtrace()); + } else { + log::error!("Run with RUST_BACKTRACE=1 to capture backtrace."); + } + target.exit(); } - *glutin_control_flow = GlutinControlFlow::Exit; - } - }) + }) + .chain_err(|| ErrorKind::Context("Event loop"))?; + Ok(()) } fn destroy(&mut self) -> Result<()> { diff --git a/engine/src/errors.rs b/engine/src/errors.rs index 366dd4d..53f944f 100644 --- a/engine/src/errors.rs +++ b/engine/src/errors.rs @@ -64,18 +64,6 @@ impl ChainErrorKind for ErrorKind { } impl ErrorKind { - pub(crate) fn create_window( - width: u32, - height: u32, - ) -> impl FnOnce(glium::backend::glutin::DisplayCreationError) -> Self { - move |error| { - ErrorKind::CreateWindow(format!( - "Window creation failed with {}x{}: {}", - width, height, error - )) - } - } - pub(crate) fn glium, ErrorT: ConvertGlium>( needed_by: NeededByT, ) -> impl FnOnce(ErrorT) -> Error { @@ -153,6 +141,7 @@ impl ConvertGlium for glium::DrawError { | ProvokingVertexNotSupported | RasterizerDiscardNotSupported | DepthClampNotSupported + | ClipControlNotSupported | BlendingParameterNotSupported => ErrorKind::UnsupportedFeature { needed_by }, NoDepthBuffer @@ -170,6 +159,7 @@ impl ConvertGlium for glium::DrawError { | SubroutineUniformMissing { .. } | SubroutineUniformToValue { .. } | ClipPlaneIndexOutOfBounds { .. } + | InsufficientImageUnits | WrongQueryOperation => panic!("Invalid draw call: {:?}", self), } } diff --git a/engine/src/input.rs b/engine/src/input.rs index 655f918..c795e27 100644 --- a/engine/src/input.rs +++ b/engine/src/input.rs @@ -2,21 +2,23 @@ use super::errors::{Error, Result}; use super::system::System; use super::window::Window; use crate::internal_derive::DependenciesFrom; -use glium::glutin::event::{ - DeviceEvent, ElementState, Event, KeyboardInput, StartCause, VirtualKeyCode, WindowEvent, -}; use math::Vec2f; use num_traits::Zero; use std::vec::Vec; +use winit::{ + event::{DeviceEvent, ElementState, Event, KeyEvent, StartCause, WindowEvent}, + keyboard::{KeyCode, PhysicalKey}, + window::CursorGrabMode, +}; -pub use glium::glutin::event::{MouseButton, VirtualKeyCode as Scancode}; +pub use winit::event::MouseButton; pub type Sensitivity = f32; pub enum Gesture { NoGesture, - KeyHold(VirtualKeyCode), - KeyTrigger(VirtualKeyCode), + KeyHold(KeyCode), + KeyTrigger(KeyCode), ButtonHold(MouseButton), ButtonTrigger(MouseButton), AnyOf(Vec), @@ -50,7 +52,7 @@ impl Input { self.mouse_rel = Vec2f::zero(); } - pub(crate) fn handle_event(&mut self, event: Event<'_, ()>) -> bool { + pub(crate) fn handle_event(&mut self, event: Event<()>) -> bool { match event { Event::NewEvents(StartCause::WaitCancelled { .. }) => {} Event::NewEvents(StartCause::ResumeTimeReached { @@ -59,7 +61,7 @@ impl Input { Event::NewEvents(_) => { self.new_step = true; } - Event::MainEventsCleared => { + Event::AboutToWait => { let new_step = self.new_step; self.new_step = false; return new_step; @@ -73,10 +75,10 @@ impl Input { Event::WindowEvent { event: WindowEvent::KeyboardInput { - input: - KeyboardInput { + event: + KeyEvent { state, - virtual_keycode: Some(virtual_keycode), + physical_key: PhysicalKey::Code(virtual_keycode), .. }, .. @@ -233,19 +235,14 @@ impl<'context> System<'context> for Input { if self.new_mouse_grabbed != self.mouse_grabbed { self.mouse_grabbed = self.new_mouse_grabbed; deps.window - .facade() - .gl_window() .window() - .set_cursor_grab(self.mouse_grabbed) + .set_cursor_grab(if self.mouse_grabbed { + CursorGrabMode::Locked + } else { + CursorGrabMode::None + }) .ok(); - deps.window - .facade() - .gl_window() - .window() - .set_cursor_visible(!self.mouse_grabbed); - } - if self.mouse_grabbed { - let _ = deps.window.facade().gl_window().window(); + deps.window.window().set_cursor_visible(!self.mouse_grabbed); } Ok(()) } @@ -267,6 +264,8 @@ fn mouse_button_to_index(button: MouseButton) -> usize { MouseButton::Left => 1, MouseButton::Middle => 2, MouseButton::Right => 3, - MouseButton::Other(index) => ((index + 4) as usize).min(NUM_MOUSE_BUTTONS - 1), + MouseButton::Back => 4, + MouseButton::Forward => 5, + MouseButton::Other(index) => ((index + 6) as usize).min(NUM_MOUSE_BUTTONS - 1), } } diff --git a/engine/src/lib.rs b/engine/src/lib.rs index 7a65147..247d1cc 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -25,7 +25,7 @@ pub use self::context::{Context, ContextBuilder, ControlFlow}; pub use self::entities::{Entities, Entity, EntityId}; pub use self::errors::{Error, ErrorKind, Result}; pub use self::frame_timers::{FrameTimerId, FrameTimers}; -pub use self::input::{Analog2d, Gesture, Input, MouseButton, Scancode}; +pub use self::input::{Analog2d, Gesture, Input, MouseButton}; pub use self::materials::{MaterialId, MaterialRefMut, Materials}; pub use self::meshes::{Mesh, MeshId, Meshes}; pub use self::pipeline::RenderPipeline; diff --git a/engine/src/platform.rs b/engine/src/platform.rs index a2e9f9a..9a66cad 100644 --- a/engine/src/platform.rs +++ b/engine/src/platform.rs @@ -1,7 +1,5 @@ #[cfg(target_os = "linux")] mod internal { - pub const GL_MAJOR_VERSION: u8 = 3; - pub const GL_MINOR_VERSION: u8 = 1; pub const GLSL_VERSION_STRING: &str = "140"; } diff --git a/engine/src/window.rs b/engine/src/window.rs index b52bb65..e49e3cc 100644 --- a/engine/src/window.rs +++ b/engine/src/window.rs @@ -1,15 +1,11 @@ -use super::errors::{Error, ErrorKind, Result}; -use super::platform; -use super::system::System; -use glium::{ - glutin::{ - dpi::PhysicalSize, event_loop::EventLoop, window::WindowBuilder, Api, ContextBuilder, - GlProfile, GlRequest, - }, - Display, Frame, Surface, -}; +use crate::ErrorKind; -const OPENGL_DEPTH_SIZE: u8 = 24; +use super::errors::{Error, Result}; +use super::system::System; +use glium::backend::glutin::SimpleWindowBuilder; +use glium::glutin::surface::WindowSurface; +use glium::{Display, Frame, Surface}; +use winit::event_loop::EventLoop; pub struct WindowConfig { pub width: u32, @@ -18,7 +14,8 @@ pub struct WindowConfig { } pub struct Window { - display: Display, + display: Display, + window: winit::window::Window, event_loop: Option>, width: u32, height: u32, @@ -43,10 +40,14 @@ impl Window { frame } - pub fn facade(&self) -> &Display { + pub fn facade(&self) -> &Display { &self.display } + pub fn window(&self) -> &winit::window::Window { + &self.window + } + pub(crate) fn take_event_loop(&mut self) -> Option> { self.event_loop.take() } @@ -57,28 +58,16 @@ impl<'context> System<'context> for Window { type Error = Error; fn create(config: &'context WindowConfig) -> Result { - let events = EventLoop::new(); - - let window = WindowBuilder::new() - .with_inner_size(PhysicalSize { - width: config.width, - height: config.height, - }) - .with_title(config.title.clone()); - - let context = ContextBuilder::new() - .with_gl_profile(GlProfile::Core) - .with_gl(GlRequest::Specific( - Api::OpenGl, - (platform::GL_MAJOR_VERSION, platform::GL_MINOR_VERSION), - )) - .with_depth_buffer(OPENGL_DEPTH_SIZE); + let events = EventLoop::new().map_err(|e| ErrorKind::CreateWindow(e.to_string()))?; - let display = Display::new(window, context, &events) - .map_err(ErrorKind::create_window(config.width, config.height))?; + let (window, display) = SimpleWindowBuilder::new() + .with_inner_size(config.width, config.height) + .with_title(&config.title) + .build(&events); Ok(Window { display, + window, event_loop: Some(events), width: config.width, height: config.height, diff --git a/engine_derive/Cargo.toml b/engine_derive/Cargo.toml index 2fd5a45..a1c8270 100644 --- a/engine_derive/Cargo.toml +++ b/engine_derive/Cargo.toml @@ -8,6 +8,6 @@ edition = "2018" proc-macro = true [dependencies] -syn = "1.0.68" +syn = "2.0.48" quote = "1.0.9" proc-macro2 = "1.0.26" diff --git a/game/Cargo.toml b/game/Cargo.toml index ee174cc..1c6aeee 100644 --- a/game/Cargo.toml +++ b/game/Cargo.toml @@ -13,6 +13,7 @@ vec_map = "0.8.2" idcontain = "0.7.6" failure = "0.1.8" failchain = "0.1018.2" +winit = "0.29.9" [dependencies.log] features = ["release_max_level_info"] @@ -20,4 +21,4 @@ version = "0.4.14" [dependencies.glium] features = ["glutin"] -version = "0.26" +version = "0.34.0" diff --git a/game/src/game.rs b/game/src/game.rs index 346db44..69a114e 100644 --- a/game/src/game.rs +++ b/game/src/game.rs @@ -16,7 +16,7 @@ use std::marker::PhantomData; use std::path::PathBuf; pub trait Game { - fn run(self) -> !; + fn run(self) -> Result<()>; fn destroy(&mut self) -> Result<()>; fn num_levels(&self) -> usize; fn load_level(&mut self, level_index: usize) -> Result<()>; @@ -107,8 +107,12 @@ impl Game for GameImpl where ContextT: Context + Peek, { - fn run(mut self) -> ! { - self.context.take().unwrap().run() + fn run(mut self) -> Result<()> { + self.context + .take() + .unwrap() + .run() + .chain_err(|| ErrorKind("during game run".to_owned())) } fn num_levels(&self) -> usize { diff --git a/game/src/hud.rs b/game/src/hud.rs index 284d84f..3e4ec8d 100644 --- a/game/src/hud.rs +++ b/game/src/hud.rs @@ -1,10 +1,10 @@ use super::wad_system::WadSystem; use engine::{ - ControlFlow, DependenciesFrom, Gesture, InfallibleSystem, Input, Scancode, TextId, - TextRenderer, Window, + ControlFlow, DependenciesFrom, Gesture, InfallibleSystem, Input, TextId, TextRenderer, Window, }; use math::prelude::*; use math::Pnt2f; +use winit::keyboard::KeyCode; pub struct Bindings { pub quit: Gesture, @@ -19,18 +19,18 @@ impl Default for Bindings { Bindings { quit: Gesture::AnyOf(vec![ Gesture::QuitTrigger, - Gesture::KeyTrigger(Scancode::Escape), + Gesture::KeyTrigger(KeyCode::Escape), ]), next_level: Gesture::AllOf(vec![ - Gesture::KeyHold(Scancode::LControl), - Gesture::KeyTrigger(Scancode::N), + Gesture::KeyHold(KeyCode::ControlLeft), + Gesture::KeyTrigger(KeyCode::KeyN), ]), previous_level: Gesture::AllOf(vec![ - Gesture::KeyHold(Scancode::LControl), - Gesture::KeyTrigger(Scancode::P), + Gesture::KeyHold(KeyCode::ControlLeft), + Gesture::KeyTrigger(KeyCode::KeyP), ]), - toggle_mouse: Gesture::KeyTrigger(Scancode::Grave), - toggle_help: Gesture::KeyTrigger(Scancode::H), + toggle_mouse: Gesture::KeyTrigger(KeyCode::Backquote), + toggle_help: Gesture::KeyTrigger(KeyCode::KeyH), } } } diff --git a/game/src/player.rs b/game/src/player.rs index ba4a3d2..8eee080 100644 --- a/game/src/player.rs +++ b/game/src/player.rs @@ -1,12 +1,13 @@ use super::level::{Level, PlayerAction}; use engine::{ Analog2d, DependenciesFrom, Entities, EntityId, Gesture, InfallibleSystem, Input, MouseButton, - Projection, Projections, RenderPipeline, Scancode, Tick, Transforms, Window, + Projection, Projections, RenderPipeline, Tick, Transforms, Window, }; use log::error; use math::prelude::*; use math::{vec3, Deg, Euler, Pnt3f, Quat, Rad, Sphere, Trans3, Vec3f}; use std::f32::consts::FRAC_PI_2; +use winit::keyboard::KeyCode; pub struct Bindings { pub movement: Analog2d, @@ -22,19 +23,19 @@ impl Default for Bindings { fn default() -> Bindings { Bindings { movement: Analog2d::Gestures { - x_positive: Gesture::KeyHold(Scancode::D), - x_negative: Gesture::KeyHold(Scancode::A), - y_positive: Gesture::KeyHold(Scancode::S), - y_negative: Gesture::KeyHold(Scancode::W), + x_positive: Gesture::KeyHold(KeyCode::KeyD), + x_negative: Gesture::KeyHold(KeyCode::KeyA), + y_positive: Gesture::KeyHold(KeyCode::KeyS), + y_negative: Gesture::KeyHold(KeyCode::KeyW), step: 1.0, }, look: Analog2d::Sum { analogs: vec![ Analog2d::Gestures { - x_positive: Gesture::KeyHold(Scancode::Right), - x_negative: Gesture::KeyHold(Scancode::Left), - y_positive: Gesture::KeyHold(Scancode::Down), - y_negative: Gesture::KeyHold(Scancode::Up), + x_positive: Gesture::KeyHold(KeyCode::ArrowRight), + x_negative: Gesture::KeyHold(KeyCode::ArrowLeft), + y_positive: Gesture::KeyHold(KeyCode::ArrowDown), + y_negative: Gesture::KeyHold(KeyCode::ArrowUp), step: 0.015, }, Analog2d::Mouse { @@ -42,11 +43,11 @@ impl Default for Bindings { }, ], }, - jump: Gesture::KeyHold(Scancode::Space), - push: Gesture::KeyTrigger(Scancode::E), + jump: Gesture::KeyHold(KeyCode::Space), + push: Gesture::KeyTrigger(KeyCode::KeyE), shoot: Gesture::ButtonTrigger(MouseButton::Left), - fly: Gesture::KeyTrigger(Scancode::F), - clip: Gesture::KeyTrigger(Scancode::C), + fly: Gesture::KeyTrigger(KeyCode::KeyF), + clip: Gesture::KeyTrigger(KeyCode::KeyC), } } } diff --git a/src/main.rs b/src/main.rs index 015a292..07e58fe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -96,7 +96,7 @@ impl App { match self.command { None => { - game::create(&self.into_config())?.run(); + game::create(&self.into_config())?.run()?; } Some(Command::Check) => { let mut game = game::create(&GameConfig { diff --git a/wad/Cargo.toml b/wad/Cargo.toml index 1ae4b42..0bb5918 100644 --- a/wad/Cargo.toml +++ b/wad/Cargo.toml @@ -11,9 +11,9 @@ bincode = "1.3.2" log = "0.4.14" regex = "1.4.5" serde = { version = "1.0.125", features = ["derive"] } -toml = "0.5.8" +toml = "0.8.8" vec_map = "0.8.2" -indexmap = "1.6.2" +indexmap = "2.1.0" failchain = "0.1018.2" failure = "0.1.8" byteorder = "1.3" diff --git a/wad/src/meta.rs b/wad/src/meta.rs index a1e62e8..3b2af34 100644 --- a/wad/src/meta.rs +++ b/wad/src/meta.rs @@ -209,14 +209,14 @@ fn deserialize_regex_from_str<'de, D>(deserializer: D) -> StdResult, { - Regex::new(<&'de str>::deserialize(deserializer)?).map_err(D::Error::custom) + Regex::new(&::deserialize(deserializer)?).map_err(D::Error::custom) } fn deserialize_name_from_str<'de, D>(deserializer: D) -> StdResult where D: Deserializer<'de>, { - WadName::from_str(<&'de str>::deserialize(deserializer)?).map_err(D::Error::custom) + WadName::from_str(&::deserialize(deserializer)?).map_err(D::Error::custom) } fn deserialize_move_speed<'de, D>(deserializer: D) -> StdResult @@ -232,7 +232,7 @@ fn deserialize_name_from_vec_vec_str<'de, D>( where D: Deserializer<'de>, { - let strings = >>::deserialize(deserializer)?; + let strings = >>::deserialize(deserializer)?; strings .iter() .map(|strings| { From 36088c0c63f8fff5f70d90082c5ea9db067bc629 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Wed, 24 Jan 2024 14:30:59 +0100 Subject: [PATCH 02/58] Add WGSL shaders --- assets/shaders/sky.wgsl | 43 +++++++++++++++++++++ assets/shaders/sprite.wgsl | 78 ++++++++++++++++++++++++++++++++++++++ assets/shaders/static.wgsl | 73 +++++++++++++++++++++++++++++++++++ assets/shaders/text.wgsl | 26 +++++++++++++ 4 files changed, 220 insertions(+) create mode 100644 assets/shaders/sky.wgsl create mode 100644 assets/shaders/sprite.wgsl create mode 100644 assets/shaders/static.wgsl create mode 100644 assets/shaders/text.wgsl diff --git a/assets/shaders/sky.wgsl b/assets/shaders/sky.wgsl new file mode 100644 index 0000000..feafc22 --- /dev/null +++ b/assets/shaders/sky.wgsl @@ -0,0 +1,43 @@ +@group(0) @binding(0) var u_projection: mat4x4; +@group(0) @binding(1) var u_sampler: sampler; + +@group(1) @binding(0) var u_texture: texture_2d; +@group(1) @binding(1) var u_palette: texture_2d; +@group(1) @binding(3) var u_tiled_band_size: f32; + +@group(2) @binding(0) var u_modelview: mat4x4; + +struct VertexOutput { + @builtin(position) clip_position: vec4; + @location(0) v_r: vec2; + @location(1) v_p: vec4; +} + +@vertex +fn main_vs(a_pos: vec3) -> VertexOutput { + var out: VertexOutput; + mat4 transform = u_projection * u_modelview; + vec4forward = transform[2]; + out.v_r = vec2(atan(forward.x, forward.z), forward.y / forward.w); + vec4projected_pos = transform * vec4(a_pos, 1); + out.v_p = projected_pos; + out.clip_position = projected_pos; + return out; +} + +@fragment +fn main_fs(in: VertexOutput) -> @location(0) vec4 { + let uv = vec2(in.v_p.x, in.v_p.y) / in.v_p.w * vec2(1, -1); + uv = vec2(uv.x - 4.0 * in.v_r.x / 3.14159265358, uv.y + 1.0 + in.v_r.y); + if uv.y < 0.0 { + uv.y = abs(mod(-uv.y + u_tiled_band_size, + u_tiled_band_size * 2.0) - u_tiled_band_size); + } else if uv.y >= 2.0 { + uv.y = abs(mod(uv.y - 2.0 + u_tiled_band_size, + u_tiled_band_size * 2.0) - u_tiled_band_size); + } else if uv.y >= 1.0 { + uv.y = 1.0 - uv.y; + } + let palette_index = textureSample(u_texture, u_sampler, uv).r; + return vec4(textureSample(u_palette, u_sampler, vec2(palette_index, 0.0)).rgb, 1.0); +} diff --git a/assets/shaders/sprite.wgsl b/assets/shaders/sprite.wgsl new file mode 100644 index 0000000..a3b424f --- /dev/null +++ b/assets/shaders/sprite.wgsl @@ -0,0 +1,78 @@ +@group(0) @binding(0) var u_projection: mat4x4; +@group(0) @binding(1) var u_sampler: sampler; +@group(0) @binding(2) var u_lights: array; +@group(0) @binding(3) var u_atlas_size: vec2; +@group(0) @binding(4) var u_time: f32; + +@group(1) @binding(0) var u_atlas: texture_2d; +@group(1) @binding(1) var u_palette: texture_2d; + +@group(1) @binding(0) var u_atlas: sampler; +@group(1) @binding(1) var u_palette: sampler; + +@group(2) @binding(0) var u_modelview: mat4x4; + +struct VertexInput { + @location(0) a_pos: vec3; + @location(1) a_atlas_uv: vec2; + @location(2) a_tile_uv: vec2; + @location(3) a_tile_size: vec2; + @location(4) a_local_x: f32; + @location(5) a_num_frames: i32; + @location(6) a_light: i32; +} + +struct VertexOutput { + @builtin(position) clip_position: vec3; + @location(0) v_dist: f32; + @location(1) v_tile_uv: vec2; + @location(2) v_atlas_uv: vec2; + @location(3) v_tile_size: vec2; + @location(4) v_light: f32; +} + +const ANIM_FPS: f32 = 8.0 / 35.0; + +@vertex +fn main_vs(in: VertexInput) -> VertexOutput { + var out: VertexOutput; + v_tile_uv = in.a_tile_uv; + if in.a_num_frames == 1 { + out.v_atlas_uv = in.a_atlas_uv; + } else { + let frame_index = u_time / ANIM_FPS; + frame_index = floor(mod(frame_index, f32(in.a_num_frames))); + + let atlas_u = in.a_atlas_uv.x + frame_index * in.a_tile_size.x; + let n_rows_down = ceil((atlas_u + in.a_tile_size.x) / u_atlas_size.x) - 1.0; + atlas_u += mod(u_atlas_size.x - in.a_atlas_uv.x, in.a_tile_size.x) * n_rows_down; + + let atlas_v = in.a_atlas_uv.y + n_rows_down * in.a_tile_size.y; + out.v_atlas_uv = vec2(atlas_u, atlas_v); + } + out.v_tile_size = in.a_tile_size; + + vec3right = vec3(u_modelview[0][0], u_modelview[1][0], u_modelview[2][0]); + vec3pos = in.a_pos + right * in.a_local_x; + vec4projected_pos = u_projection * (u_modelview * vec4(pos, 1.0)); + out.v_light = u_lights[in.a_light]; + out.v_dist = projected_pos.w; + out.clip_position = projected_pos; + return out; +} + +const DIST_SCALE: f32 = 1.0; +const LIGHT_SCALE: f32 = 2.0; + +@fragment +fn main_fs(in: VertexOutput) -> @location(0) vec4 { + let uv = mod(in.v_tile_uv, in.v_tile_size) + in.v_atlas_uv; + let palette_index = textureSample(u_atlas, u_sampler, uv / u_atlas_size).rg; + if palette_index.g > .5 { // Transparent pixel. + discard; + } else { + float dist_term = min(1.0, 1.0 - DIST_SCALE / (in.v_dist + DIST_SCALE)); + float light = min(in.v_light, in.v_light * LIGHT_SCALE - dist_term); + return vec4(textureSample(u_palette, u_sampler, vec2(palette_index.r, 1.0 - light)).rgb, 1.0); + } +} diff --git a/assets/shaders/static.wgsl b/assets/shaders/static.wgsl new file mode 100644 index 0000000..7db7312 --- /dev/null +++ b/assets/shaders/static.wgsl @@ -0,0 +1,73 @@ +@group(0) @binding(0) var u_projection: mat4x4; +@group(0) @binding(1) var u_sampler: sampler; +@group(0) @binding(2) var u_lights: array; +@group(0) @binding(3) var u_atlas_size: vec2; +@group(0) @binding(4) var u_time: f32; + +@group(1) @binding(0) var u_atlas: texture_2d; +@group(1) @binding(1) var u_palette: texture_2d; + +@group(2) @binding(0) var u_modelview: mat4x4; + +struct VertexInput { + @location(0) a_pos: vec3; + @location(1) a_atlas_uv: vec2; + @location(2) a_tile_uv: vec2; + @location(3) a_tile_size: vec2; + @location(4) a_scroll_rate: f32; + @location(5) a_row_height: f32; + @location(6) a_num_frames: i32; + @location(7) a_light: i32; +} + +struct VertexOutput { + @builtin(position) clip_position: vec3; + @location(0) v_dist: f32; + @location(1) v_tile_uv: vec2; + @location(2) v_atlas_uv: vec2; + @location(3) v_tile_size: vec2; + @location(4) v_light: f32; +} + +const ANIM_FPS: f32 = 8.0 / 35.0; + +@vertex +fn main_vs(in: VertexInput) -> VertexOutput { + var out: VertexOutput; + out.v_tile_uv = in.a_tile_uv + vec2(u_time * in.a_scroll_rate, 0.0); + if in.a_num_frames == 1 { + out.v_atlas_uv = in.a_atlas_uv; + } else { + let frame_index = u_time / ANIM_FPS; + frame_index = floor(mod(frame_index, f32(in.a_num_frames))); + + let atlas_u = in.a_atlas_uv.x + frame_index * in.a_tile_size.x; + let n_rows_down = ceil((atlas_u + in.a_tile_size.x) / u_atlas_size.x) - 1.0; + atlas_u += mod(u_atlas_size.x - in.a_atlas_uv.x, in.a_tile_size.x) * n_rows_down; + + let atlas_v = in.a_atlas_uv.y + n_rows_down * in.a_row_height; + out.v_atlas_uv = vec2(atlas_u, atlas_v); + } + out.v_tile_size = in.a_tile_size; + let projected_pos = u_projection * u_modelview * vec4(in.a_pos, 1); + out.v_dist = projected_pos.w; + out.v_light = u_lights[in.a_light]; + out.clip_position = projected_pos; + return out; +} + +const DIST_SCALE: f32 = 0.9; +const LIGHT_SCALE: f32 = 2.0; + +@fragment +fn main_fs(in: VertexOutput) -> @location(0) vec4 { + let uv = mod(v_tile_uv, v_tile_size) + v_atlas_uv; + let palette_index = textureSample(u_atlas, u_sampler, uv / u_atlas_size).rg; + if palette_index.g > .5 { // Transparent pixel. + discard; + } else { + float dist_term = min(1.0, 1.0 - DIST_SCALE / (v_dist + DIST_SCALE)); + float light = v_light * LIGHT_SCALE - dist_term; + return vec4(textureSample(u_palette, u_sampler, vec2(palette_index.r, 1.0 - light)).rgb, 1.0); + } +} diff --git a/assets/shaders/text.wgsl b/assets/shaders/text.wgsl new file mode 100644 index 0000000..431fb2e --- /dev/null +++ b/assets/shaders/text.wgsl @@ -0,0 +1,26 @@ +@group(0) @binding(0) var u_tex: texture_2d; +@group(0) @binding(1) var u_sampler: sampler; + +struct VertexInput { + @location(0) a_pos: vec2; + @location(1) a_uv: vec2; +} + +struct VertexOutput { + @location(0) v_uv: vec2; + @builtin(position) clip_position: vec4; +} + +@vertex +fn main_vs() -> VertexOutput { + var out: VertexOutput; + out.v_uv = a_uv; + out.clip_position = vec4(a_pos, 0.0, 1.0); + return out; +} + +@fragment +fn main_fs(in: VertexOutput) -> @location(0) vec4 { + let tex_color = textureSample(u_tex, u_sampler, in.v_uv); + return vec4(tex_color.g, tex_color.g, tex_color.g, tex_color.r); +} From 459e11b054e83dbee3d1f65ddfbb19121c14e6c8 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Wed, 24 Jan 2024 14:32:07 +0100 Subject: [PATCH 03/58] Add WGPU and related crate dependencies --- Cargo.lock | 947 ++++++++++++++++++++++++++++++++++++++++++++-- engine/Cargo.toml | 11 +- game/Cargo.toml | 11 +- 3 files changed, 938 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 66a2179..8babb95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,6 +55,12 @@ 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.5.1" @@ -82,6 +88,15 @@ 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 = "ansi_term" version = "0.11.0" @@ -91,6 +106,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "anyhow" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" + [[package]] name = "approx" version = "0.4.0" @@ -118,6 +139,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" +[[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 = "atomic-waker" version = "1.1.2" @@ -137,9 +167,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" @@ -150,7 +180,7 @@ dependencies = [ "addr2line", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.4.4", "object", "rustc-demangle", ] @@ -165,6 +195,27 @@ dependencies = [ "serde", ] +[[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 = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.2.1" @@ -177,6 +228,12 @@ 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.2.0" @@ -207,6 +264,20 @@ 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.48", +] [[package]] name = "byteorder" @@ -316,6 +387,53 @@ dependencies = [ "bitflags 1.2.1", ] +[[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]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "com" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6" +dependencies = [ + "com_macros", +] + +[[package]] +name = "com_macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5" +dependencies = [ + "com_macros_support", + "proc-macro2", + "syn 1.0.68", +] + +[[package]] +name = "com_macros_support" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.68", +] + [[package]] name = "combine" version = "4.6.6" @@ -375,6 +493,34 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.18" @@ -384,12 +530,29 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "cursor-icon" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" +[[package]] +name = "d3d12" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e3d747f100290a1ca24b752186f61f6637e1deffe3bf6320de6fcb29510a307" +dependencies = [ + "bitflags 2.4.1", + "libloading 0.8.1", + "winapi", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -402,7 +565,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading", + "libloading 0.8.1", ] [[package]] @@ -411,22 +574,37 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + [[package]] name = "engine" version = "0.1.0" dependencies = [ + "anyhow", + "bytemuck", + "cgmath", "engine_derive", "env_logger", "failchain", "failure", + "futures", "glium", "glium-typed-buffer-any", "idcontain", + "image", + "lock_api", "log", "math", "num-traits", + "pollster", "rusttype", + "tobj", "unicode-normalization", + "wgpu", "winit", ] @@ -468,6 +646,22 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "exr" +version = "1.71.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "832a761f35ab3e6664babfbdc6cef35a4860e816ec3916dcfd0882954e98a8a8" +dependencies = [ + "bit_field", + "flume", + "half", + "lebe", + "miniz_oxide 0.7.1", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "failchain" version = "0.1018.2" @@ -499,6 +693,34 @@ dependencies = [ "synstructure", ] +[[package]] +name = "fdeflate" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide 0.7.1", +] + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "spin", +] + [[package]] name = "fnv" version = "1.0.7" @@ -538,19 +760,117 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "game" version = "0.1.0" dependencies = [ + "anyhow", + "bytemuck", + "cgmath", "engine", "failchain", "failure", + "futures", "glium", "idcontain", + "image", + "lock_api", "log", "math", + "pollster", + "tobj", "vec_map", "wad", + "wgpu", "winit", ] @@ -575,6 +895,16 @@ dependencies = [ "wasi", ] +[[package]] +name = "gif" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "gimli" version = "0.23.0" @@ -620,6 +950,18 @@ dependencies = [ "smallvec", ] +[[package]] +name = "glow" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "glutin" version = "0.31.2" @@ -635,7 +977,7 @@ dependencies = [ "glutin_glx_sys", "glutin_wgl_sys", "icrate", - "libloading", + "libloading 0.8.1", "objc2", "once_cell", "raw-window-handle 0.5.2", @@ -685,11 +1027,91 @@ 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.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f56f6318968d03c18e1bcf4857ff88c61157e9da8e47c5f29055d60e1228884" +dependencies = [ + "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 = "half" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" +dependencies = [ + "crunchy", +] + [[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.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" +dependencies = [ + "bitflags 2.4.1", + "com", + "libc", + "libloading 0.8.1", + "thiserror", + "widestring", + "winapi", +] [[package]] name = "heck" @@ -715,6 +1137,12 @@ 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" @@ -741,6 +1169,24 @@ dependencies = [ "rand", ] +[[package]] +name = "image" +version = "0.24.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "034bbe799d1909622a74d1193aa50147769440040ff36cb2baa947609b0a4e23" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-traits", + "png", + "qoi", + "tiff", +] + [[package]] name = "indexmap" version = "2.1.0" @@ -793,15 +1239,35 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" +dependencies = [ + "rayon", +] + [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" 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" @@ -814,11 +1280,27 @@ 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" +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" @@ -847,6 +1329,16 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.14" @@ -856,6 +1348,15 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + [[package]] name = "math" version = "0.1.0" @@ -897,6 +1398,21 @@ 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", + "log", + "objc", + "paste", +] + [[package]] name = "miniz_oxide" version = "0.4.4" @@ -907,6 +1423,36 @@ dependencies = [ "autocfg", ] +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "naga" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8878eb410fc90853da3908aebfe61d73d26d4437ef850b70050461f939509899" +dependencies = [ + "bit-set", + "bitflags 2.4.1", + "codespan-reporting", + "hexf-parse", + "indexmap", + "log", + "num-traits", + "rustc-hash", + "spirv", + "termcolor", + "thiserror", + "unicode-xid", +] + [[package]] name = "ndk" version = "0.8.0" @@ -980,6 +1526,16 @@ dependencies = [ "syn 2.0.48", ] +[[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.3.2" @@ -1002,6 +1558,15 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" +[[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.23.0" @@ -1041,6 +1606,35 @@ dependencies = [ "ttf-parser 0.20.0", ] +[[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.1.0" @@ -1053,12 +1647,31 @@ version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[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.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f6c3c3e617595665b8ea2ff95a86066be38fb121ff920a9c0eb282abcd1da5a" +dependencies = [ + "bitflags 1.2.1", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide 0.7.1", +] + [[package]] name = "polling" version = "3.3.1" @@ -1073,6 +1686,18 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "pollster" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" + +[[package]] +name = "presser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" + [[package]] name = "proc-macro-crate" version = "2.0.0" @@ -1115,6 +1740,21 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "profiling" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d135ede8821cf6376eb7a64148901e1690b788c11ae94dc297ae917dbc91dc0e" + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + [[package]] name = "quick-xml" version = "0.30.0" @@ -1161,6 +1801,12 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" +[[package]] +name = "range-alloc" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab" + [[package]] name = "raw-window-handle" version = "0.5.2" @@ -1173,6 +1819,26 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544" +[[package]] +name = "rayon" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -1208,6 +1874,12 @@ version = "0.6.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" +[[package]] +name = "renderdoc-sys" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216080ab382b992234dda86873c18d4c48358f5cfcb70fd693d7f6f2131b628b" + [[package]] name = "rs_doom" version = "0.0.9" @@ -1228,6 +1900,12 @@ version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" +[[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" @@ -1266,6 +1944,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "sctk-adwaita" version = "0.8.1" @@ -1308,6 +1992,12 @@ dependencies = [ "serde", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "slab" version = "0.4.9" @@ -1317,6 +2007,15 @@ dependencies = [ "autocfg", ] +[[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" @@ -1357,6 +2056,30 @@ dependencies = [ "serde", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spirv" +version = "0.3.0+sdk-1.3.268.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" +dependencies = [ + "bitflags 2.4.1", +] + +[[package]] +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" @@ -1435,9 +2158,9 @@ checksum = "36ae8932fcfea38b7d3883ae2ab357b0d57a02caaa18ebb4f5ece08beaec4aa0" [[package]] name = "termcolor" -version = "1.1.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -1471,6 +2194,17 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "tiny-skia" version = "0.11.3" @@ -1511,6 +2245,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +[[package]] +name = "tobj" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7ca3ec0405b0f2f95e0dbcced28882190dc79b0dac63ff82533d256d770223" +dependencies = [ + "ahash", +] + [[package]] name = "toml" version = "0.8.8" @@ -1613,9 +2356,9 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "vec_map" @@ -1665,9 +2408,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1675,9 +2418,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", @@ -1690,9 +2433,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.39" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" dependencies = [ "cfg-if", "js-sys", @@ -1702,9 +2445,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1712,9 +2455,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", @@ -1725,9 +2468,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "wayland-backend" @@ -1840,9 +2583,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" dependencies = [ "js-sys", "wasm-bindgen", @@ -1858,6 +2601,124 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + +[[package]] +name = "wgpu" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfe9a310dcf2e6b85f00c46059aaeaf4184caa8e29a1ecd4b7a704c3482332d" +dependencies = [ + "arrayvec", + "cfg-if", + "cfg_aliases", + "js-sys", + "log", + "naga", + "parking_lot", + "profiling", + "raw-window-handle 0.6.0", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b15e451d4060ada0d99a64df44e4d590213496da7c4f245572d51071e8e30ed" +dependencies = [ + "arrayvec", + "bit-vec", + "bitflags 2.4.1", + "cfg_aliases", + "codespan-reporting", + "indexmap", + "log", + "naga", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle 0.6.0", + "rustc-hash", + "smallvec", + "thiserror", + "web-sys", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bb47856236bfafc0bc591a925eb036ac19cd987624a447ff353e7a7e7e6f72" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash", + "bit-set", + "bitflags 2.4.1", + "block", + "cfg_aliases", + "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 0.6.0", + "renderdoc-sys", + "rustc-hash", + "smallvec", + "thiserror", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "winapi", +] + +[[package]] +name = "wgpu-types" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "895fcbeb772bfb049eb80b2d6e47f6c9af235284e9703c96fc0218a42ffd5af2" +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" @@ -1889,6 +2750,25 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -2089,9 +2969,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winit" -version = "0.29.9" +version = "0.29.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2376dab13e09c01ad8b679f0dbc7038af4ec43d9a91344338e37bd686481550" +checksum = "4c824f11941eeae66ec71111cc2674373c772f482b58939bb4066b642aa2ffcf" dependencies = [ "ahash", "android-activity", @@ -2165,7 +3045,7 @@ dependencies = [ "as-raw-xcb-connection", "gethostname", "libc", - "libloading", + "libloading 0.8.1", "once_cell", "rustix", "x11rb-protocol", @@ -2227,3 +3107,12 @@ dependencies = [ "quote", "syn 2.0.48", ] + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] diff --git a/engine/Cargo.toml b/engine/Cargo.toml index a67d54a..74e36bd 100644 --- a/engine/Cargo.toml +++ b/engine/Cargo.toml @@ -14,7 +14,16 @@ rusttype = "0.9.2" unicode-normalization = "0.1.17" failure = "0.1.8" failchain = "0.1018.2" -winit = "0.29.9" +winit = "0.29.10" +wgpu = "0.19.0" +bytemuck = { version = "1.14.0", features = ["derive"] } +futures = "0.3.30" +tobj = "4.0.0" +image = "0.24.8" +anyhow = "1.0.79" +cgmath = "0.18.0" +pollster = "0.3.0" +lock_api = "0.4.11" [dependencies.glium-typed-buffer-any] version = "0.6.0" diff --git a/game/Cargo.toml b/game/Cargo.toml index 1c6aeee..a4d034b 100644 --- a/game/Cargo.toml +++ b/game/Cargo.toml @@ -13,7 +13,16 @@ vec_map = "0.8.2" idcontain = "0.7.6" failure = "0.1.8" failchain = "0.1018.2" -winit = "0.29.9" +winit = "0.29.10" +wgpu = "0.19.0" +bytemuck = { version = "1.14.0", features = ["derive"] } +futures = "0.3.30" +tobj = "4.0.0" +image = "0.24.8" +anyhow = "1.0.79" +cgmath = "0.18.0" +pollster = "0.3.0" +lock_api = "0.4.11" [dependencies.log] features = ["release_max_level_info"] From 49f1771831ef62545f60739ca1fefbe592d927cf Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Wed, 24 Jan 2024 16:00:41 +0100 Subject: [PATCH 04/58] Construct WGPU objects in Window system --- engine/src/window.rs | 60 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/engine/src/window.rs b/engine/src/window.rs index e49e3cc..3bdf234 100644 --- a/engine/src/window.rs +++ b/engine/src/window.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use crate::ErrorKind; use super::errors::{Error, Result}; @@ -14,8 +16,11 @@ pub struct WindowConfig { } pub struct Window { + device: wgpu::Device, + queue: wgpu::Queue, + surface: wgpu::Surface<'static>, display: Display, - window: winit::window::Window, + window: Arc, event_loop: Option>, width: u32, height: u32, @@ -65,7 +70,28 @@ impl<'context> System<'context> for Window { .with_title(&config.title) .build(&events); + let window = Arc::new(window); + let instance = create_instance(); + let surface = instance + .create_surface(window.clone()) + .map_err(|_| ErrorKind::Context("Could not create surface"))?; + let (device, adapter, queue) = pollster::block_on(create_device(instance, &surface)) + .map_err(|_| ErrorKind::Context("Could not create WGPU device"))?; + let configuration = surface + .get_default_config( + &adapter, + window.inner_size().width, + window.inner_size().height, + ) + .ok_or(ErrorKind::Context( + "Could not get default surface configuration", + ))?; + surface.configure(&device, &configuration); + Ok(Window { + device, + queue, + surface, display, window, event_loop: Some(events), @@ -78,3 +104,35 @@ impl<'context> System<'context> for Window { "window" } } + +fn create_instance() -> wgpu::Instance { + wgpu::Instance::new(wgpu::InstanceDescriptor::default()) +} + +async fn create_device( + instance: wgpu::Instance, + surface: &wgpu::Surface<'static>, +) -> Result<(wgpu::Device, wgpu::Adapter, wgpu::Queue)> { + let adapter = instance + .request_adapter(&wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::default(), + compatible_surface: Some(surface), + force_fallback_adapter: false, + }) + .await + .unwrap(); + + let (device, queue) = adapter + .request_device( + &wgpu::DeviceDescriptor { + label: None, + required_features: wgpu::Features::empty(), + required_limits: wgpu::Limits::default(), + }, + None, + ) + .await + .unwrap(); + + Ok((device, adapter, queue)) +} From a5cc642584d7b75bc5d086f1f255f7e8fc0a048f Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Wed, 24 Jan 2024 16:10:24 +0100 Subject: [PATCH 05/58] Add rendering boilerplate --- engine/src/renderer.rs | 9 +++++++++ engine/src/window.rs | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 1cfc30b..14524b5 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -97,6 +97,12 @@ impl<'context> System<'context> for Renderer { // Render all the models in turn. let mut frame = deps.window.draw(); + let surface_texture = deps.window.surface_texture()?; + let view = surface_texture.texture.create_view(&Default::default()); + let encoder = deps + .window + .device() + .create_command_encoder(&Default::default()); for (index, &Model { mesh, material }) in pipe.models.access().iter().enumerate() { // For each model we need to assemble three things to render it: transform, mesh and // material. We get the entity id and query the corresponding systems for it. @@ -171,6 +177,9 @@ impl<'context> System<'context> for Renderer { pipe.models.remove_by_index(index); } self.removed.clear(); + + deps.window.queue().submit([encoder.finish()]); + surface_texture.present(); Ok(()) } } diff --git a/engine/src/window.rs b/engine/src/window.rs index 3bdf234..83befbe 100644 --- a/engine/src/window.rs +++ b/engine/src/window.rs @@ -4,6 +4,7 @@ use crate::ErrorKind; use super::errors::{Error, Result}; use super::system::System; +use failchain::BoxedError; use glium::backend::glutin::SimpleWindowBuilder; use glium::glutin::surface::WindowSurface; use glium::{Display, Frame, Surface}; @@ -45,6 +46,20 @@ impl Window { frame } + pub fn device(&self) -> &wgpu::Device { + &self.device + } + + pub fn queue(&self) -> &wgpu::Queue { + &self.queue + } + + pub fn surface_texture(&self) -> Result { + self.surface + .get_current_texture() + .map_err(|_| BoxedError::from(ErrorKind::Context("Could not get current texture"))) + } + pub fn facade(&self) -> &Display { &self.display } From e4bcbd76e35394d1349d4739417fb9e95b747345 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Wed, 24 Jan 2024 16:58:20 +0100 Subject: [PATCH 06/58] Add render pass and render attachments --- engine/src/renderer.rs | 179 +++++++++++++++++++++++++++-------------- engine/src/window.rs | 14 ++++ 2 files changed, 133 insertions(+), 60 deletions(-) diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 14524b5..0ee5b84 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -34,6 +34,10 @@ pub struct Dependencies<'context> { pub struct Renderer { draw_parameters: DrawParameters<'static>, removed: Vec, + texture: wgpu::Texture, + view: wgpu::TextureView, + depth_texture: wgpu::Texture, + depth_view: wgpu::TextureView, } impl<'context> System<'context> for Renderer { @@ -44,7 +48,35 @@ impl<'context> System<'context> for Renderer { "renderer" } - fn create(_deps: Dependencies) -> Result { + fn create(deps: Dependencies) -> Result { + let texture = deps + .window + .device() + .create_texture(&wgpu::TextureDescriptor { + label: Some("Intermediate attachment"), + size: deps.window.size(), + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: deps.window.texture_format(), + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + view_formats: &[], + }); + let view = texture.create_view(&Default::default()); + let depth_texture = deps + .window + .device() + .create_texture(&wgpu::TextureDescriptor { + label: Some("Depth atachment"), + size: deps.window.size(), + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Depth32Float, + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + view_formats: &[], + }); + let depth_view = depth_texture.create_view(&Default::default()); Ok(Renderer { draw_parameters: DrawParameters { depth: Depth { @@ -56,6 +88,10 @@ impl<'context> System<'context> for Renderer { ..DrawParameters::default() }, removed: Vec::with_capacity(32), + texture, + view, + depth_texture, + depth_view, }) } @@ -99,46 +135,69 @@ impl<'context> System<'context> for Renderer { let mut frame = deps.window.draw(); let surface_texture = deps.window.surface_texture()?; let view = surface_texture.texture.create_view(&Default::default()); - let encoder = deps + let mut encoder = deps .window .device() .create_command_encoder(&Default::default()); - for (index, &Model { mesh, material }) in pipe.models.access().iter().enumerate() { - // For each model we need to assemble three things to render it: transform, mesh and - // material. We get the entity id and query the corresponding systems for it. - let entity = pipe - .models - .index_to_id(index) - .expect("bad index enumerating models: mesh"); - - // If the mesh is missing, the entity was (probably) removed. So we add it to the - // removed stack and continue. - let mesh = if let Some(mesh) = deps.meshes.get(mesh) { - mesh - } else { - info!( - "Mesh missing {:?} in model for entity {:?}, removing.", - mesh, entity - ); - self.removed.push(index); - continue; - }; - - // If the model has a transform, then multiply it with the view transform to get the - // modelview matrix. If there is no transform, model is assumed to be in world space, so - // modelview = view. - *deps - .uniforms - .get_mat4_mut(pipe.modelview) - .expect("modelview uniform missing") = - if let Some(model_transform) = deps.transforms.get_absolute(entity) { - Mat4::from(view_transform.concat(model_transform)) + { + let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: &self.view, + resolve_target: Some(&view), + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color::BLACK), + store: wgpu::StoreOp::Store, + }, + })], + depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment { + view: &self.depth_view, + depth_ops: Some(wgpu::Operations { + load: wgpu::LoadOp::Clear(1.0), + store: wgpu::StoreOp::Store, + }), + stencil_ops: None, + }), + timestamp_writes: None, + occlusion_query_set: None, + }); + for (index, &Model { mesh, material }) in pipe.models.access().iter().enumerate() { + // For each model we need to assemble three things to render it: transform, mesh and + // material. We get the entity id and query the corresponding systems for it. + let entity = pipe + .models + .index_to_id(index) + .expect("bad index enumerating models: mesh"); + + // If the mesh is missing, the entity was (probably) removed. So we add it to the + // removed stack and continue. + let mesh = if let Some(mesh) = deps.meshes.get(mesh) { + mesh } else { - view_matrix + info!( + "Mesh missing {:?} in model for entity {:?}, removing.", + mesh, entity + ); + self.removed.push(index); + continue; }; - let material = - if let Some(material) = deps.materials.get(deps.shaders, deps.uniforms, material) { + // If the model has a transform, then multiply it with the view transform to get the + // modelview matrix. If there is no transform, model is assumed to be in world space, so + // modelview = view. + *deps + .uniforms + .get_mat4_mut(pipe.modelview) + .expect("modelview uniform missing") = + if let Some(model_transform) = deps.transforms.get_absolute(entity) { + Mat4::from(view_transform.concat(model_transform)) + } else { + view_matrix + }; + + let material = if let Some(material) = + deps.materials.get(deps.shaders, deps.uniforms, material) + { material } else { // If there is a mesh but no material, the model is badly set up. This is an @@ -151,33 +210,33 @@ impl<'context> System<'context> for Renderer { continue; }; + frame + .draw( + &mesh, + &mesh, + material.shader(), + &material, + &self.draw_parameters, + ) + .map_err(ErrorKind::glium("renderer"))?; + } + + // Render text. TODO(cristicbz): text should render itself :( + deps.text + .render(&mut frame) + .chain_err(|| ErrorKind::System("render bypass", TextRenderer::debug_name()))?; + + // TODO(cristicbz): Re-architect a little bit to support rebuilding the context. frame - .draw( - &mesh, - &mesh, - material.shader(), - &material, - &self.draw_parameters, - ) - .map_err(ErrorKind::glium("renderer"))?; - } - - // Render text. TODO(cristicbz): text should render itself :( - deps.text - .render(&mut frame) - .chain_err(|| ErrorKind::System("render bypass", TextRenderer::debug_name()))?; - - // TODO(cristicbz): Re-architect a little bit to support rebuilding the context. - frame - .finish() - .expect("Cannot handle context loss currently :("); - - // Remove any missing models. - for &index in self.removed.iter().rev() { - pipe.models.remove_by_index(index); + .finish() + .expect("Cannot handle context loss currently :("); + + // Remove any missing models. + for &index in self.removed.iter().rev() { + pipe.models.remove_by_index(index); + } + self.removed.clear(); } - self.removed.clear(); - deps.window.queue().submit([encoder.finish()]); surface_texture.present(); Ok(()) diff --git a/engine/src/window.rs b/engine/src/window.rs index 83befbe..013f50b 100644 --- a/engine/src/window.rs +++ b/engine/src/window.rs @@ -20,6 +20,7 @@ pub struct Window { device: wgpu::Device, queue: wgpu::Queue, surface: wgpu::Surface<'static>, + texture_format: wgpu::TextureFormat, display: Display, window: Arc, event_loop: Option>, @@ -54,6 +55,18 @@ impl Window { &self.queue } + pub fn size(&self) -> wgpu::Extent3d { + wgpu::Extent3d { + width: self.width, + height: self.height, + depth_or_array_layers: 1, + } + } + + pub fn texture_format(&self) -> wgpu::TextureFormat { + self.texture_format + } + pub fn surface_texture(&self) -> Result { self.surface .get_current_texture() @@ -108,6 +121,7 @@ impl<'context> System<'context> for Window { queue, surface, display, + texture_format: configuration.format, window, event_loop: Some(events), width: config.width, From 159c850bdb98cea6e76f09cff688e31c0d58faac Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Wed, 24 Jan 2024 22:30:11 +0100 Subject: [PATCH 07/58] Implement MeshRef for WGPU --- engine/src/materials.rs | 16 ++++++ engine/src/meshes.rs | 109 +++++++++++++++++++--------------------- engine/src/renderer.rs | 56 ++++++++------------- game/src/level.rs | 32 ++++++------ game/src/vertex.rs | 12 +++-- 5 files changed, 116 insertions(+), 109 deletions(-) diff --git a/engine/src/materials.rs b/engine/src/materials.rs index 98628de..6e6b190 100644 --- a/engine/src/materials.rs +++ b/engine/src/materials.rs @@ -172,6 +172,22 @@ impl<'a> MaterialRef<'a> { pub fn shader(&self) -> &Program { self.shader } + + pub(crate) fn pipeline(&self) -> &'a wgpu::RenderPipeline { + todo!() + } + + pub(crate) fn global_bind_group(&self) -> &'a wgpu::BindGroup { + todo!() + } + + pub(crate) fn material_bind_group(&self) -> &'a wgpu::BindGroup { + todo!() + } + + pub(crate) fn model_bind_group(&self) -> &'a wgpu::BindGroup { + todo!() + } } impl<'material> GliumUniforms for MaterialRef<'material> { diff --git a/engine/src/meshes.rs b/engine/src/meshes.rs index d2b3734..e7c4761 100644 --- a/engine/src/meshes.rs +++ b/engine/src/meshes.rs @@ -1,13 +1,10 @@ use super::entities::{Entities, Entity, EntityId}; -use super::errors::{ErrorKind, Result}; +use super::errors::Result; use super::system::InfallibleSystem; -use super::window::Window; -pub use glium::index::IndexBuffer; -use glium::index::{IndicesSource, PrimitiveType}; -use glium::vertex::{Vertex, VertexBuffer, VerticesSource}; -pub use glium_typed_buffer_any::TypedVertexBufferAny; +use bytemuck::Pod; use idcontain::IdMapVec; use log::{debug, error}; +use wgpu::util::DeviceExt; #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Copy, Clone)] pub struct MeshId(EntityId); @@ -19,7 +16,6 @@ pub struct Meshes { impl Meshes { pub fn add<'a>( &'a mut self, - window: &'a Window, entities: &'a mut Entities, parent: EntityId, name: &'static str, @@ -27,7 +23,6 @@ impl Meshes { MeshAdder { context: MeshAdderContext { meshes: self, - window, entities, parent, name, @@ -85,29 +80,26 @@ impl Meshes { } pub struct MeshRefMut<'a> { - pub vertices: Option<&'a mut TypedVertexBufferAny>, - pub indices: Option<&'a mut IndexBuffer>, + pub vertices: Option<&'a mut wgpu::Buffer>, + pub indices: Option<&'a mut wgpu::Buffer>, } pub struct MeshRef<'a> { - vertices: &'a TypedVertexBufferAny, - indices: Option<&'a IndexBuffer>, + vertices: &'a wgpu::Buffer, + indices: Option<&'a wgpu::Buffer>, } -impl<'a, 'b: 'a> From<&'a MeshRef<'b>> for IndicesSource<'a> { - fn from(mesh: &'a MeshRef<'b>) -> Self { - mesh.indices.map_or( - IndicesSource::NoIndices { - primitives: PrimitiveType::TrianglesList, - }, - |indices| indices.into(), - ) +impl<'a> MeshRef<'a> { + pub(crate) fn vertex_buffer(&self) -> wgpu::BufferSlice<'a> { + self.vertices.slice(..) + } + + pub(crate) fn index_buffer(&self) -> wgpu::BufferSlice<'a> { + self.indices.expect("index buffer not present").slice(..) } -} -impl<'a, 'b: 'a> From<&'a MeshRef<'b>> for VerticesSource<'a> { - fn from(mesh: &'a MeshRef<'b>) -> Self { - mesh.vertices.into() + pub(crate) fn index_count(&self) -> u32 { + self.indices.expect("index buffer not present").size() as u32 / 4 } } @@ -118,24 +110,26 @@ pub struct MeshAdder<'a, VertexDataT, IndexDataT> { indices: IndexDataT, } -pub struct OwnedVertexData(TypedVertexBufferAny); +pub struct OwnedVertexData(wgpu::Buffer); pub struct SharedVertexData(MeshId); -pub struct IndexData(IndexBuffer); +pub struct IndexData(wgpu::Buffer); impl<'a, IndexDataT> MeshAdder<'a, (), IndexDataT> { pub fn immutable( self, vertices: &[VertexT], + device: &wgpu::Device, ) -> Result> where - VertexT: Vertex + Send + 'static, + VertexT: Pod + Send + 'static, { + let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice(vertices), + usage: wgpu::BufferUsages::VERTEX, + }); Ok(MeshAdder { - vertices: OwnedVertexData( - VertexBuffer::immutable(self.context.window.facade(), vertices) - .map_err(ErrorKind::glium(self.context.name))? - .into(), - ), + vertices: OwnedVertexData(buffer), indices: self.indices, context: self.context, }) @@ -144,16 +138,18 @@ impl<'a, IndexDataT> MeshAdder<'a, (), IndexDataT> { pub fn persistent( self, vertices: &[VertexT], + device: &wgpu::Device, ) -> Result> where - VertexT: Vertex + Send + 'static, + VertexT: Pod + Send + 'static, { + let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice(vertices), + usage: wgpu::BufferUsages::VERTEX, + }); Ok(MeshAdder { - vertices: OwnedVertexData( - VertexBuffer::persistent(self.context.window.facade(), vertices) - .map_err(ErrorKind::glium(self.context.name))? - .into(), - ), + vertices: OwnedVertexData(buffer), indices: self.indices, context: self.context, }) @@ -185,16 +181,15 @@ impl<'a, VertexDataT> MeshAdder<'a, VertexDataT, ()> { pub fn immutable_indices( self, indices: &[u32], + device: &wgpu::Device, ) -> Result> { + let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice(indices), + usage: wgpu::BufferUsages::INDEX, + }); Ok(MeshAdder { - indices: IndexData( - IndexBuffer::persistent( - self.context.window.facade(), - PrimitiveType::TrianglesList, - indices, - ) - .map_err(ErrorKind::glium(self.context.name))?, - ), + indices: IndexData(buffer), vertices: self.vertices, context: self.context, }) @@ -203,16 +198,15 @@ impl<'a, VertexDataT> MeshAdder<'a, VertexDataT, ()> { pub fn persistent_indices( self, indices: &[u32], + device: &wgpu::Device, ) -> Result> { + let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice(indices), + usage: wgpu::BufferUsages::INDEX, + }); Ok(MeshAdder { - indices: IndexData( - IndexBuffer::persistent( - self.context.window.facade(), - PrimitiveType::TrianglesList, - indices, - ) - .map_err(ErrorKind::glium(self.context.name))?, - ), + indices: IndexData(buffer), vertices: self.vertices, context: self.context, }) @@ -286,18 +280,17 @@ impl<'context> InfallibleSystem<'context> for Meshes { #[cfg_attr(feature = "cargo-clippy", allow(clippy::large_enum_variant))] enum InternalMeshData { Owned { - vertices: TypedVertexBufferAny, - indices: Option>, + vertices: wgpu::Buffer, + indices: Option, }, Inherit { vertices_from: MeshId, - indices: IndexBuffer, + indices: wgpu::Buffer, }, } struct MeshAdderContext<'a> { meshes: &'a mut Meshes, - window: &'a Window, entities: &'a mut Entities, parent: EntityId, name: &'static str, diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 0ee5b84..738feeb 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -12,7 +12,6 @@ use super::uniforms::Uniforms; use super::window::Window; use crate::internal_derive::DependenciesFrom; use failchain::ResultExt; -use glium::{BackfaceCullingMode, Depth, DepthTest, DrawParameters, Surface}; use log::{error, info}; use math::prelude::*; use math::Mat4; @@ -32,11 +31,10 @@ pub struct Dependencies<'context> { } pub struct Renderer { - draw_parameters: DrawParameters<'static>, removed: Vec, - texture: wgpu::Texture, + _texture: wgpu::Texture, view: wgpu::TextureView, - depth_texture: wgpu::Texture, + _depth_texture: wgpu::Texture, depth_view: wgpu::TextureView, } @@ -78,19 +76,10 @@ impl<'context> System<'context> for Renderer { }); let depth_view = depth_texture.create_view(&Default::default()); Ok(Renderer { - draw_parameters: DrawParameters { - depth: Depth { - test: DepthTest::IfLess, - write: true, - ..Depth::default() - }, - backface_culling: BackfaceCullingMode::CullClockwise, - ..DrawParameters::default() - }, removed: Vec::with_capacity(32), - texture, + _texture: texture, view, - depth_texture, + _depth_texture: depth_texture, depth_view, }) } @@ -120,7 +109,7 @@ impl<'context> System<'context> for Renderer { pipe.camera = None; return Ok(()); }; - let view_matrix = view_transform.into(); + // let view_matrix: Mat4 = view_transform.into(); // Set projection. *deps @@ -185,15 +174,16 @@ impl<'context> System<'context> for Renderer { // If the model has a transform, then multiply it with the view transform to get the // modelview matrix. If there is no transform, model is assumed to be in world space, so // modelview = view. - *deps - .uniforms - .get_mat4_mut(pipe.modelview) - .expect("modelview uniform missing") = - if let Some(model_transform) = deps.transforms.get_absolute(entity) { - Mat4::from(view_transform.concat(model_transform)) - } else { - view_matrix - }; + // TODO: Writing to uniforms can only be done by submitting a write buffer command, and needs to be done in advance of rendering. + // *deps + // .uniforms + // .get_mat4_mut(pipe.modelview) + // .expect("modelview uniform missing") = + // if let Some(model_transform) = deps.transforms.get_absolute(entity) { + // Mat4::from(view_transform.concat(model_transform)) + // } else { + // view_matrix + // }; let material = if let Some(material) = deps.materials.get(deps.shaders, deps.uniforms, material) @@ -210,15 +200,13 @@ impl<'context> System<'context> for Renderer { continue; }; - frame - .draw( - &mesh, - &mesh, - material.shader(), - &material, - &self.draw_parameters, - ) - .map_err(ErrorKind::glium("renderer"))?; + render_pass.set_pipeline(material.pipeline()); + render_pass.set_bind_group(0, material.global_bind_group(), &[]); + render_pass.set_bind_group(1, material.material_bind_group(), &[]); + render_pass.set_bind_group(2, material.model_bind_group(), &[]); + render_pass.set_vertex_buffer(0, mesh.vertex_buffer()); + render_pass.set_index_buffer(mesh.index_buffer(), wgpu::IndexFormat::Uint32); + render_pass.draw_indexed(0..mesh.index_count(), 0, 0..1); } // Render text. TODO(cristicbz): text should render itself :( diff --git a/game/src/level.rs b/game/src/level.rs index cce4e51..8618d80 100644 --- a/game/src/level.rs +++ b/game/src/level.rs @@ -424,20 +424,20 @@ impl<'a> Builder<'a> { info!("Creating static meshes and models..."); let global_static_mesh = deps .meshes - .add(deps.window, deps.entities, root, "global_world_static_mesh") - .immutable(&builder.static_vertices)? + .add(deps.entities, root, "global_world_static_mesh") + .immutable(&builder.static_vertices, deps.window.device())? .build_unindexed()?; let global_sky_mesh = deps .meshes - .add(deps.window, deps.entities, root, "global_world_sky_mesh") - .immutable(&builder.sky_vertices)? + .add(deps.entities, root, "global_world_sky_mesh") + .immutable(&builder.sky_vertices, deps.window.device())? .build_unindexed()?; let global_decor_mesh = deps .meshes - .add(deps.window, deps.entities, root, "global_world_decor_mesh") - .immutable(&builder.decor_vertices)? + .add(deps.entities, root, "global_world_decor_mesh") + .immutable(&builder.decor_vertices, deps.window.device())? .build_unindexed()?; for (id, indices) in &builder.object_indices { @@ -446,9 +446,9 @@ impl<'a> Builder<'a> { let entity = deps.entities.add(object, "flats")?; let mesh = deps .meshes - .add(deps.window, deps.entities, entity, "object_flats_mesh") + .add(deps.entities, entity, "object_flats_mesh") .shared(global_static_mesh) - .immutable_indices(&indices.flat)? + .immutable_indices(&indices.flat, deps.window.device())? .build()?; deps.transforms.attach_identity(entity); deps.render @@ -459,9 +459,9 @@ impl<'a> Builder<'a> { let entity = deps.entities.add(object, "walls")?; let mesh = deps .meshes - .add(deps.window, deps.entities, entity, "object_walls_mesh") + .add(deps.entities, entity, "object_walls_mesh") .shared(global_static_mesh) - .immutable_indices(&indices.wall)? + .immutable_indices(&indices.wall, deps.window.device())? .build()?; deps.transforms.attach_identity(entity); deps.render @@ -472,9 +472,9 @@ impl<'a> Builder<'a> { let entity = deps.entities.add(object, "decor")?; let mesh = deps .meshes - .add(deps.window, deps.entities, entity, "object_decor_mesh") + .add(deps.entities, entity, "object_decor_mesh") .shared(global_decor_mesh) - .immutable_indices(&indices.decor)? + .immutable_indices(&indices.decor, deps.window.device())? .build()?; deps.transforms.attach_identity(entity); deps.render @@ -485,9 +485,9 @@ impl<'a> Builder<'a> { let entity = deps.entities.add(object, "sky")?; let mesh = deps .meshes - .add(deps.window, deps.entities, entity, "object_sky_mesh") + .add(deps.entities, entity, "object_sky_mesh") .shared(global_sky_mesh) - .immutable_indices(&indices.sky)? + .immutable_indices(&indices.sky, deps.window.device())? .build()?; deps.transforms.attach_identity(entity); deps.render @@ -530,6 +530,7 @@ impl<'a> Builder<'a> { a_num_frames: bounds.num_frames as u8, a_row_height: bounds.row_height as f32, a_light: light_info, + ..Default::default() }); self } @@ -544,6 +545,7 @@ impl<'a> Builder<'a> { a_num_frames: bounds.num_frames as u8, a_row_height: bounds.row_height as f32, a_light: light_info, + ..Default::default() }); self } @@ -551,6 +553,7 @@ impl<'a> Builder<'a> { fn sky_vertex(&mut self, xz: Pnt2f, y: f32) -> &mut Self { self.sky_vertices.push(SkyVertex { a_pos: [xz[0], y, xz[1]], + ..Default::default() }); self } @@ -572,6 +575,7 @@ impl<'a> Builder<'a> { a_tile_size: [bounds.size[0], bounds.size[1]], a_num_frames: 1, a_light: light_info, + ..Default::default() }); self } diff --git a/game/src/vertex.rs b/game/src/vertex.rs index 5f1c12a..41e1ff8 100644 --- a/game/src/vertex.rs +++ b/game/src/vertex.rs @@ -1,11 +1,13 @@ #![cfg_attr(feature = "cargo-clippy", allow(clippy::forget_copy))] +use bytemuck::{Pod, Zeroable}; use glium::implement_vertex; #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Pod, Zeroable, Default)] pub struct StaticVertex { pub a_pos: [f32; 3], + pub _padding_1: f32, pub a_atlas_uv: [f32; 2], pub a_tile_uv: [f32; 2], pub a_tile_size: [f32; 2], @@ -13,6 +15,7 @@ pub struct StaticVertex { pub a_row_height: f32, pub a_num_frames: u8, pub a_light: u8, + pub _padding_2: u16, } implement_vertex! { @@ -28,15 +31,17 @@ implement_vertex! { } #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Pod, Zeroable, Default)] pub struct SpriteVertex { pub a_pos: [f32; 3], + pub _padding_1: f32, pub a_atlas_uv: [f32; 2], pub a_tile_uv: [f32; 2], pub a_tile_size: [f32; 2], pub a_local_x: f32, pub a_num_frames: u8, pub a_light: u8, + pub _padding_2: u16, } implement_vertex! { @@ -51,9 +56,10 @@ implement_vertex! { } #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Pod, Zeroable, Default)] pub struct SkyVertex { pub a_pos: [f32; 3], + pub _padding_1: f32, } implement_vertex! { From 9e6002b60d2b8f27a738f96001d1dffa6b44a2f1 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Wed, 24 Jan 2024 22:32:42 +0100 Subject: [PATCH 08/58] Remove unused dependency --- Cargo.lock | 10 ---------- engine/Cargo.toml | 5 ----- 2 files changed, 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8babb95..801b9b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -593,7 +593,6 @@ dependencies = [ "failure", "futures", "glium", - "glium-typed-buffer-any", "idcontain", "image", "lock_api", @@ -941,15 +940,6 @@ dependencies = [ "winit", ] -[[package]] -name = "glium-typed-buffer-any" -version = "0.6.0" -source = "git+https://github.com/hovinen/glium-typed-buffer-any?branch=update-dependency#7345beb3904df211d699ee05875934cc7ac20b55" -dependencies = [ - "glium", - "smallvec", -] - [[package]] name = "glow" version = "0.13.1" diff --git a/engine/Cargo.toml b/engine/Cargo.toml index 74e36bd..534e3c7 100644 --- a/engine/Cargo.toml +++ b/engine/Cargo.toml @@ -25,11 +25,6 @@ cgmath = "0.18.0" pollster = "0.3.0" lock_api = "0.4.11" -[dependencies.glium-typed-buffer-any] -version = "0.6.0" -git = "https://github.com/hovinen/glium-typed-buffer-any" -branch = "update-dependency" - [dependencies.log] features = ["release_max_level_info"] version = "0.4.14" From 71255343e2c442566ea8042c4bb62b560e3c8c4f Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Thu, 25 Jan 2024 15:02:03 +0100 Subject: [PATCH 09/58] Add vertex descriptors --- engine/src/lib.rs | 2 +- engine/src/materials.rs | 46 ++++++------- engine/src/renderer.rs | 2 +- engine/src/shaders.rs | 78 +++++++++++++++++++++- game/src/game_shaders.rs | 16 +++-- game/src/level.rs | 10 +-- game/src/vertex.rs | 135 +++++++++++++++++++++++++++++++++++++-- 7 files changed, 244 insertions(+), 45 deletions(-) diff --git a/engine/src/lib.rs b/engine/src/lib.rs index 247d1cc..7c54c28 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -31,7 +31,7 @@ pub use self::meshes::{Mesh, MeshId, Meshes}; pub use self::pipeline::RenderPipeline; pub use self::projections::{Projection, Projections}; pub use self::renderer::Renderer; -pub use self::shaders::{ShaderConfig, ShaderId, Shaders}; +pub use self::shaders::{ShaderConfig, ShaderId, ShaderVertex, Shaders}; pub use self::system::{InfallibleSystem, System}; pub use self::text::{Text, TextId, TextRenderer}; pub use self::tick::{Config as TickConfig, Tick, TickIndex}; diff --git a/engine/src/materials.rs b/engine/src/materials.rs index 6e6b190..d571cca 100644 --- a/engine/src/materials.rs +++ b/engine/src/materials.rs @@ -3,7 +3,6 @@ use super::errors::Result; use super::shaders::{ShaderId, Shaders}; use super::system::InfallibleSystem; use super::uniforms::{UniformId, Uniforms}; -use glium::uniforms::{UniformValue, Uniforms as GliumUniforms}; use glium::Program; use idcontain::IdMapVec; use log::{debug, error}; @@ -73,6 +72,14 @@ impl Materials { return None; }; + let Some(pipeline) = shaders.get_pipeline(material.shader) else { + error!( + "Missing pipeline {:?} for material {:?}", + material.shader, material_id + ); + return None; + }; + let mut uniform_values = [None; MAX_UNIFORMS]; for (value, &uniform) in (&mut uniform_values[..]) .iter_mut() @@ -93,9 +100,16 @@ impl Materials { } } + let global_bind_group = todo!(); + let material_bind_group = todo!(); + let model_bind_group = todo!(); + Some(MaterialRef { shader, - uniform_values, + pipeline, + global_bind_group, + material_bind_group, + model_bind_group, }) } } @@ -132,7 +146,10 @@ impl<'a> MaterialRefMut<'a> { pub struct MaterialRef<'a> { shader: &'a Program, - uniform_values: [Option<(&'static str, UniformValue<'a>)>; MAX_UNIFORMS], + pipeline: &'a wgpu::RenderPipeline, + global_bind_group: &'a wgpu::BindGroup, + material_bind_group: &'a wgpu::BindGroup, + model_bind_group: &'a wgpu::BindGroup, } impl<'context> InfallibleSystem<'context> for Materials { @@ -174,34 +191,19 @@ impl<'a> MaterialRef<'a> { } pub(crate) fn pipeline(&self) -> &'a wgpu::RenderPipeline { - todo!() + &self.pipeline } pub(crate) fn global_bind_group(&self) -> &'a wgpu::BindGroup { - todo!() + &self.global_bind_group } pub(crate) fn material_bind_group(&self) -> &'a wgpu::BindGroup { - todo!() + &self.material_bind_group } pub(crate) fn model_bind_group(&self) -> &'a wgpu::BindGroup { - todo!() - } -} - -impl<'material> GliumUniforms for MaterialRef<'material> { - fn visit_values<'a, F>(&'a self, mut set_uniform: F) - where - F: FnMut(&str, UniformValue<'a>), - { - for uniform in &self.uniform_values[..] { - if let Some((name, value)) = *uniform { - set_uniform(name, value); - } else { - break; - } - } + &self.model_bind_group } } diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 738feeb..2c0711f 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -14,7 +14,6 @@ use crate::internal_derive::DependenciesFrom; use failchain::ResultExt; use log::{error, info}; use math::prelude::*; -use math::Mat4; #[derive(DependenciesFrom)] pub struct Dependencies<'context> { @@ -112,6 +111,7 @@ impl<'context> System<'context> for Renderer { // let view_matrix: Mat4 = view_transform.into(); // Set projection. + // TODO: This needs to be put in a buffer and copied to the GPU. *deps .uniforms .get_mat4_mut(pipe.projection) diff --git a/engine/src/shaders.rs b/engine/src/shaders.rs index c83968a..c966bdd 100644 --- a/engine/src/shaders.rs +++ b/engine/src/shaders.rs @@ -27,7 +27,7 @@ pub struct Shaders { } impl Shaders { - pub fn add( + pub fn add( &mut self, window: &Window, entities: &mut Entities, @@ -38,6 +38,9 @@ impl Shaders { let mut fragment_path = self.root.clone(); fragment_path.push(asset_path); + let wgsl_path = fragment_path.clone(); + fragment_path.set_extension("wgsl"); + let mut vertex_path = fragment_path.clone(); fragment_path.set_extension("frag"); vertex_path.set_extension("vert"); @@ -69,9 +72,69 @@ impl Shaders { }, ) .map_err(ErrorKind::glium(name))?; + + let shader_module = window + .device() + .create_shader_module(wgpu::ShaderModuleDescriptor { + label: Some(name), + source: wgpu::ShaderSource::Wgsl(wgsl_path.to_string_lossy().into()), + }); + + let pipeline_layout = + window + .device() + .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some(name), + bind_group_layouts: &[], + push_constant_ranges: &[], + }); + + let pipeline = window + .device() + .create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some(name), + layout: Some(&pipeline_layout), + vertex: wgpu::VertexState { + module: &shader_module, + entry_point: "main_vs", + buffers: &[VertexT::desc()], + }, + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleList, + strip_index_format: None, + front_face: wgpu::FrontFace::Ccw, + cull_mode: Some(wgpu::Face::Back), + unclipped_depth: false, + polygon_mode: wgpu::PolygonMode::Fill, + conservative: false, + }, + depth_stencil: Some(wgpu::DepthStencilState { + format: wgpu::TextureFormat::Depth32Float, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::Less, + stencil: wgpu::StencilState::default(), + bias: wgpu::DepthBiasState::default(), + }), + multisample: wgpu::MultisampleState { + count: 1, + mask: !0, + alpha_to_coverage_enabled: false, + }, + fragment: Some(wgpu::FragmentState { + module: &shader_module, + entry_point: "main_fs", + targets: &[Some(wgpu::ColorTargetState { + format: window.texture_format(), + blend: Some(wgpu::BlendState::REPLACE), + write_mask: wgpu::ColorWrites::all(), + })], + }), + multiview: None, + }); + debug!("Shader {:?} loaded successfully", name); let id = entities.add(parent, name)?; - self.map.insert(id, Shader { program }); + self.map.insert(id, Shader { program, pipeline }); debug!("Added shader {:?} {:?} as child of {:?}.", name, id, parent); Ok(ShaderId(id)) } @@ -79,10 +142,17 @@ impl Shaders { pub fn get(&self, shader_id: ShaderId) -> Option<&Program> { self.map.get(shader_id.0).map(|shader| &shader.program) } + + pub(crate) fn get_pipeline(&self, shader_id: ShaderId) -> Option<&wgpu::RenderPipeline> { + self.map + .get(shader_id.0) + .map(|shader: &Shader| &shader.pipeline) + } } pub struct Shader { program: Program, + pipeline: wgpu::RenderPipeline, } #[derive(DependenciesFrom)] @@ -128,3 +198,7 @@ impl<'context> InfallibleSystem<'context> for Shaders { fn read_utf8_file(path: &Path, into: &mut String) -> IoResult<()> { File::open(path)?.read_to_string(into).map(|_| ()) } + +pub trait ShaderVertex { + fn desc<'a>() -> wgpu::VertexBufferLayout<'a>; +} diff --git a/game/src/game_shaders.rs b/game/src/game_shaders.rs index 93f6719..995fc49 100644 --- a/game/src/game_shaders.rs +++ b/game/src/game_shaders.rs @@ -1,9 +1,11 @@ +use crate::vertex::{SkyVertex, SpriteVertex, StaticVertex}; + use super::wad_system::WadSystem; use engine::{ BufferTextureId, BufferTextureType, ClientFormat, DependenciesFrom, Entities, EntityId, Error, FloatUniformId, MagnifySamplerFilter, MaterialId, Materials, MinifySamplerFilter, - RenderPipeline, Result, SamplerBehavior, SamplerWrapFunction, ShaderId, Shaders, System, - Texture2dId, Tick, Uniforms, Window, + RenderPipeline, Result, SamplerBehavior, SamplerWrapFunction, ShaderId, ShaderVertex, Shaders, + System, Texture2dId, Tick, Uniforms, Window, }; use log::{error, info}; use math::Vec2; @@ -158,9 +160,9 @@ impl<'context> Dependencies<'context> { BufferTextureType::Float, )?; - let static_shader = self.load_shader(parent, "static_shader", "static")?; - let sky_shader = self.load_shader(parent, "sky_shader", "sky")?; - let sprite_shader = self.load_shader(parent, "sprite_shader", "sprite")?; + let static_shader = self.load_shader::(parent, "static_shader", "static")?; + let sky_shader = self.load_shader::(parent, "sky_shader", "sky")?; + let sprite_shader = self.load_shader::(parent, "sprite_shader", "sprite")?; Ok(Globals { time, @@ -452,14 +454,14 @@ impl<'context> Dependencies<'context> { }) } - fn load_shader( + fn load_shader( &mut self, parent: EntityId, name: &'static str, asset: &'static str, ) -> Result { self.shaders - .add(self.window, self.entities, parent, name, asset) + .add::(self.window, self.entities, parent, name, asset) } } diff --git a/game/src/level.rs b/game/src/level.rs index 8618d80..3e1779f 100644 --- a/game/src/level.rs +++ b/game/src/level.rs @@ -527,9 +527,9 @@ impl<'a> Builder<'a> { a_tile_uv: [tile_u, tile_v], a_tile_size: [bounds.size[0], bounds.size[1]], a_scroll_rate: scroll_rate, - a_num_frames: bounds.num_frames as u8, + a_num_frames: bounds.num_frames as u32, a_row_height: bounds.row_height as f32, - a_light: light_info, + a_light: light_info as u32, ..Default::default() }); self @@ -542,9 +542,9 @@ impl<'a> Builder<'a> { a_tile_uv: [-xz[0] * 100.0, -xz[1] * 100.0], a_tile_size: [bounds.size[0], bounds.size[1]], a_scroll_rate: 0.0, - a_num_frames: bounds.num_frames as u8, + a_num_frames: bounds.num_frames as u32, a_row_height: bounds.row_height as f32, - a_light: light_info, + a_light: light_info as u32, ..Default::default() }); self @@ -574,7 +574,7 @@ impl<'a> Builder<'a> { a_tile_uv: [tile_u, tile_v], a_tile_size: [bounds.size[0], bounds.size[1]], a_num_frames: 1, - a_light: light_info, + a_light: light_info as u32, ..Default::default() }); self diff --git a/game/src/vertex.rs b/game/src/vertex.rs index 41e1ff8..accc427 100644 --- a/game/src/vertex.rs +++ b/game/src/vertex.rs @@ -1,7 +1,10 @@ #![cfg_attr(feature = "cargo-clippy", allow(clippy::forget_copy))] -use bytemuck::{Pod, Zeroable}; +use bytemuck::{offset_of, Pod, Zeroable}; +use engine::ShaderVertex; use glium::implement_vertex; +use std::sync::OnceLock; +use wgpu::VertexAttribute; #[repr(C)] #[derive(Copy, Clone, Pod, Zeroable, Default)] @@ -13,9 +16,62 @@ pub struct StaticVertex { pub a_tile_size: [f32; 2], pub a_scroll_rate: f32, pub a_row_height: f32, - pub a_num_frames: u8, - pub a_light: u8, - pub _padding_2: u16, + pub a_num_frames: u32, + pub a_light: u32, +} + +impl ShaderVertex for StaticVertex { + fn desc<'a>() -> wgpu::VertexBufferLayout<'a> { + static ATTRIBUTES: OnceLock> = OnceLock::new(); + wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &ATTRIBUTES.get_or_init(|| { + vec![ + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x3, + offset: offset_of!(StaticVertex, a_pos) as u64, + shader_location: 0, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32, + offset: offset_of!(StaticVertex, a_atlas_uv) as u64, + shader_location: 1, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x2, + offset: offset_of!(StaticVertex, a_tile_uv) as u64, + shader_location: 2, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x2, + offset: offset_of!(StaticVertex, a_tile_size) as u64, + shader_location: 3, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x2, + offset: offset_of!(StaticVertex, a_scroll_rate) as u64, + shader_location: 4, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32, + offset: offset_of!(StaticVertex, a_row_height) as u64, + shader_location: 5, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Uint32, + offset: offset_of!(StaticVertex, a_num_frames) as u64, + shader_location: 6, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Uint32, + offset: offset_of!(StaticVertex, a_light) as u64, + shader_location: 7, + }, + ] + }), + } + } } implement_vertex! { @@ -39,9 +95,57 @@ pub struct SpriteVertex { pub a_tile_uv: [f32; 2], pub a_tile_size: [f32; 2], pub a_local_x: f32, - pub a_num_frames: u8, - pub a_light: u8, - pub _padding_2: u16, + pub a_num_frames: u32, + pub a_light: u32, +} + +impl ShaderVertex for SpriteVertex { + fn desc<'a>() -> wgpu::VertexBufferLayout<'a> { + static ATTRIBUTES: OnceLock> = OnceLock::new(); + wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &ATTRIBUTES.get_or_init(|| { + vec![ + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x3, + offset: offset_of!(SpriteVertex, a_pos) as u64, + shader_location: 0, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x2, + offset: offset_of!(SpriteVertex, a_atlas_uv) as u64, + shader_location: 1, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x2, + offset: offset_of!(SpriteVertex, a_tile_uv) as u64, + shader_location: 2, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x2, + offset: offset_of!(SpriteVertex, a_tile_size) as u64, + shader_location: 3, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x2, + offset: offset_of!(SpriteVertex, a_local_x) as u64, + shader_location: 4, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Uint32, + offset: offset_of!(SpriteVertex, a_num_frames) as u64, + shader_location: 5, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Uint32, + offset: offset_of!(SpriteVertex, a_light) as u64, + shader_location: 6, + }, + ] + }), + } + } } implement_vertex! { @@ -62,6 +166,23 @@ pub struct SkyVertex { pub _padding_1: f32, } +impl ShaderVertex for SkyVertex { + fn desc<'a>() -> wgpu::VertexBufferLayout<'a> { + static ATTRIBUTES: OnceLock> = OnceLock::new(); + wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &ATTRIBUTES.get_or_init(|| { + vec![wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x3, + offset: offset_of!(SkyVertex, a_pos) as u64, + shader_location: 0, + }] + }), + } + } +} + implement_vertex! { SkyVertex, a_pos, From 44f169be4a1feee5cd110459bc79524a2a07f83b Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Thu, 25 Jan 2024 15:32:49 +0100 Subject: [PATCH 10/58] Add bind group layouts --- assets/shaders/sky.wgsl | 2 +- assets/shaders/sprite.wgsl | 3 - engine/src/shaders.rs | 124 ++++++++++++++++++++++++++++++++++++- 3 files changed, 124 insertions(+), 5 deletions(-) diff --git a/assets/shaders/sky.wgsl b/assets/shaders/sky.wgsl index feafc22..11edf9f 100644 --- a/assets/shaders/sky.wgsl +++ b/assets/shaders/sky.wgsl @@ -3,7 +3,7 @@ @group(1) @binding(0) var u_texture: texture_2d; @group(1) @binding(1) var u_palette: texture_2d; -@group(1) @binding(3) var u_tiled_band_size: f32; +@group(1) @binding(2) var u_tiled_band_size: f32; @group(2) @binding(0) var u_modelview: mat4x4; diff --git a/assets/shaders/sprite.wgsl b/assets/shaders/sprite.wgsl index a3b424f..6438c1e 100644 --- a/assets/shaders/sprite.wgsl +++ b/assets/shaders/sprite.wgsl @@ -7,9 +7,6 @@ @group(1) @binding(0) var u_atlas: texture_2d; @group(1) @binding(1) var u_palette: texture_2d; -@group(1) @binding(0) var u_atlas: sampler; -@group(1) @binding(1) var u_palette: sampler; - @group(2) @binding(0) var u_modelview: mat4x4; struct VertexInput { diff --git a/engine/src/shaders.rs b/engine/src/shaders.rs index c966bdd..8c96cab 100644 --- a/engine/src/shaders.rs +++ b/engine/src/shaders.rs @@ -9,9 +9,11 @@ use failchain::ResultExt; use glium::program::{Program, ProgramCreationInput}; use idcontain::IdMapVec; use log::{debug, error}; +use math::{Mat4, Vec2}; use std::fs::File; use std::io::Read; use std::io::Result as IoResult; +use std::num::{NonZeroU32, NonZeroU64}; use std::path::{Path, PathBuf}; #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Copy, Clone)] @@ -24,6 +26,9 @@ pub struct ShaderConfig { pub struct Shaders { map: IdMapVec, root: PathBuf, + global_bind_group_layout: wgpu::BindGroupLayout, + material_bind_group_layout: wgpu::BindGroupLayout, + model_bind_group_layout: wgpu::BindGroupLayout, } impl Shaders { @@ -85,7 +90,11 @@ impl Shaders { .device() .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some(name), - bind_group_layouts: &[], + bind_group_layouts: &[ + &self.global_bind_group_layout, + &self.material_bind_group_layout, + &self.model_bind_group_layout, + ], push_constant_ranges: &[], }); @@ -159,6 +168,7 @@ pub struct Shader { pub struct Dependencies<'context> { config: &'context ShaderConfig, entities: &'context Entities, + window: &'context Window, } impl<'context> InfallibleSystem<'context> for Shaders { @@ -169,9 +179,121 @@ impl<'context> InfallibleSystem<'context> for Shaders { } fn create(deps: Dependencies) -> Self { + let global_bind_group_layout = deps.window.device().create_bind_group_layout( + &wgpu::BindGroupLayoutDescriptor { + label: Some("global_bind_group_layout"), + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::VERTEX, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: NonZeroU64::new(std::mem::size_of::() as u64), + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Comparison), + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 2, + visibility: wgpu::ShaderStages::VERTEX, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: NonZeroU64::new(std::mem::size_of::() as u64), + }, + count: NonZeroU32::new(256), + }, + wgpu::BindGroupLayoutEntry { + binding: 3, + visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: NonZeroU64::new( + std::mem::size_of::>() as u64 + ), + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 4, + visibility: wgpu::ShaderStages::VERTEX, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: NonZeroU64::new(std::mem::size_of::() as u64), + }, + count: None, + }, + ], + }, + ); + let material_bind_group_layout = deps.window.device().create_bind_group_layout( + &wgpu::BindGroupLayoutDescriptor { + label: Some("material_bind_group_layout"), + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Texture { + sample_type: wgpu::TextureSampleType::Float { filterable: true }, + view_dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Texture { + sample_type: wgpu::TextureSampleType::Float { filterable: true }, + view_dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 2, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: NonZeroU64::new(std::mem::size_of::() as u64), + }, + count: None, + }, + ], + }, + ); + let model_bind_group_layout = + deps.window + .device() + .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("model_bind_group_layout"), + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::VERTEX, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: NonZeroU64::new(std::mem::size_of::() as u64), + }, + count: None, + }], + }); + Shaders { map: IdMapVec::with_capacity(32), root: deps.config.root_path.clone(), + global_bind_group_layout, + material_bind_group_layout, + model_bind_group_layout, } } From 87229aaef10e2182594ae2b5aefaf013f626da77 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Fri, 26 Jan 2024 11:58:23 +0100 Subject: [PATCH 11/58] Set up global bind group --- engine/src/renderer.rs | 33 ++++++++++++++++++++++++++++++++- engine/src/shaders.rs | 4 ++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 2c0711f..e06c923 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -35,6 +35,7 @@ pub struct Renderer { view: wgpu::TextureView, _depth_texture: wgpu::Texture, depth_view: wgpu::TextureView, + global_bind_group: wgpu::BindGroup, } impl<'context> System<'context> for Renderer { @@ -74,12 +75,42 @@ impl<'context> System<'context> for Renderer { view_formats: &[], }); let depth_view = depth_texture.create_view(&Default::default()); + let global_bind_group = + deps.window + .device() + .create_bind_group(&wgpu::BindGroupDescriptor { + label: Some("Global bind group"), + layout: deps.shaders.global_bind_group_layout(), + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: todo!(), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: todo!(), + }, + wgpu::BindGroupEntry { + binding: 2, + resource: todo!(), + }, + wgpu::BindGroupEntry { + binding: 3, + resource: todo!(), + }, + wgpu::BindGroupEntry { + binding: 4, + resource: todo!(), + }, + ], + }); Ok(Renderer { removed: Vec::with_capacity(32), _texture: texture, view, _depth_texture: depth_texture, depth_view, + global_bind_group, }) } @@ -150,6 +181,7 @@ impl<'context> System<'context> for Renderer { timestamp_writes: None, occlusion_query_set: None, }); + render_pass.set_bind_group(0, &self.global_bind_group, &[]); for (index, &Model { mesh, material }) in pipe.models.access().iter().enumerate() { // For each model we need to assemble three things to render it: transform, mesh and // material. We get the entity id and query the corresponding systems for it. @@ -201,7 +233,6 @@ impl<'context> System<'context> for Renderer { }; render_pass.set_pipeline(material.pipeline()); - render_pass.set_bind_group(0, material.global_bind_group(), &[]); render_pass.set_bind_group(1, material.material_bind_group(), &[]); render_pass.set_bind_group(2, material.model_bind_group(), &[]); render_pass.set_vertex_buffer(0, mesh.vertex_buffer()); diff --git a/engine/src/shaders.rs b/engine/src/shaders.rs index 8c96cab..d9f5254 100644 --- a/engine/src/shaders.rs +++ b/engine/src/shaders.rs @@ -157,6 +157,10 @@ impl Shaders { .get(shader_id.0) .map(|shader: &Shader| &shader.pipeline) } + + pub(crate) fn global_bind_group_layout(&self) -> &wgpu::BindGroupLayout { + &self.global_bind_group_layout + } } pub struct Shader { From ca1df4200cd63e4b2ab97eff548577e53cde0e5b Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Fri, 26 Jan 2024 11:59:11 +0100 Subject: [PATCH 12/58] Move palette to global bind group --- assets/shaders/sky.wgsl | 2 +- assets/shaders/sprite.wgsl | 6 ++--- assets/shaders/static.wgsl | 6 ++--- engine/src/materials.rs | 48 ++++++++++++++++++++++++-------------- engine/src/renderer.rs | 4 +++- engine/src/shaders.rs | 32 ++++++++++++++----------- game/src/game_shaders.rs | 15 +++++++++++- 7 files changed, 73 insertions(+), 40 deletions(-) diff --git a/assets/shaders/sky.wgsl b/assets/shaders/sky.wgsl index 11edf9f..fa5598c 100644 --- a/assets/shaders/sky.wgsl +++ b/assets/shaders/sky.wgsl @@ -1,8 +1,8 @@ @group(0) @binding(0) var u_projection: mat4x4; @group(0) @binding(1) var u_sampler: sampler; +@group(0) @binding(4) var u_palette: texture_2d; @group(1) @binding(0) var u_texture: texture_2d; -@group(1) @binding(1) var u_palette: texture_2d; @group(1) @binding(2) var u_tiled_band_size: f32; @group(2) @binding(0) var u_modelview: mat4x4; diff --git a/assets/shaders/sprite.wgsl b/assets/shaders/sprite.wgsl index 6438c1e..50376a1 100644 --- a/assets/shaders/sprite.wgsl +++ b/assets/shaders/sprite.wgsl @@ -1,11 +1,11 @@ @group(0) @binding(0) var u_projection: mat4x4; @group(0) @binding(1) var u_sampler: sampler; @group(0) @binding(2) var u_lights: array; -@group(0) @binding(3) var u_atlas_size: vec2; -@group(0) @binding(4) var u_time: f32; +@group(0) @binding(3) var u_time: f32; +@group(0) @binding(4) var u_palette: texture_2d; @group(1) @binding(0) var u_atlas: texture_2d; -@group(1) @binding(1) var u_palette: texture_2d; +@group(1) @binding(1) var u_atlas_size: vec2; @group(2) @binding(0) var u_modelview: mat4x4; diff --git a/assets/shaders/static.wgsl b/assets/shaders/static.wgsl index 7db7312..692eaea 100644 --- a/assets/shaders/static.wgsl +++ b/assets/shaders/static.wgsl @@ -1,11 +1,11 @@ @group(0) @binding(0) var u_projection: mat4x4; @group(0) @binding(1) var u_sampler: sampler; @group(0) @binding(2) var u_lights: array; -@group(0) @binding(3) var u_atlas_size: vec2; -@group(0) @binding(4) var u_time: f32; +@group(0) @binding(3) var u_time: f32; +@group(0) @binding(4) var u_palette: texture_2d; @group(1) @binding(0) var u_atlas: texture_2d; -@group(1) @binding(1) var u_palette: texture_2d; +@group(1) @binding(1) var u_atlas_size: vec2; @group(2) @binding(0) var u_modelview: mat4x4; diff --git a/engine/src/materials.rs b/engine/src/materials.rs index d571cca..ecd3aa9 100644 --- a/engine/src/materials.rs +++ b/engine/src/materials.rs @@ -1,3 +1,5 @@ +use crate::Window; + use super::entities::{Entities, Entity, EntityId}; use super::errors::Result; use super::shaders::{ShaderId, Shaders}; @@ -28,16 +30,43 @@ impl Materials { pub fn add<'a>( &'a mut self, entities: &mut Entities, + shaders: &Shaders, + window: &Window, parent: EntityId, shader: ShaderId, name: &'static str, ) -> Result> { + let bind_group = window + .device() + .create_bind_group(&wgpu::BindGroupDescriptor { + label: Some(name), + layout: &shaders.material_bind_group_layout(), + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(&atlas_view), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::Buffer( + atlas_size_buffer.as_entire_binding(), + ), + }, + wgpu::BindGroupEntry { + binding: 3, + resource: wgpu::BindingResource::Buffer( + tiled_band_size_buffer.as_entire_binding(), + ), + }, + ], + }); let id = entities.add(parent, name)?; self.map.insert( id, Material { shader, uniforms: [None; MAX_UNIFORMS], + bind_group, }, ); debug!( @@ -100,16 +129,10 @@ impl Materials { } } - let global_bind_group = todo!(); - let material_bind_group = todo!(); - let model_bind_group = todo!(); - Some(MaterialRef { shader, pipeline, - global_bind_group, - material_bind_group, - model_bind_group, + material_bind_group: &material.bind_group, }) } } @@ -147,9 +170,7 @@ impl<'a> MaterialRefMut<'a> { pub struct MaterialRef<'a> { shader: &'a Program, pipeline: &'a wgpu::RenderPipeline, - global_bind_group: &'a wgpu::BindGroup, material_bind_group: &'a wgpu::BindGroup, - model_bind_group: &'a wgpu::BindGroup, } impl<'context> InfallibleSystem<'context> for Materials { @@ -194,20 +215,13 @@ impl<'a> MaterialRef<'a> { &self.pipeline } - pub(crate) fn global_bind_group(&self) -> &'a wgpu::BindGroup { - &self.global_bind_group - } - pub(crate) fn material_bind_group(&self) -> &'a wgpu::BindGroup { &self.material_bind_group } - - pub(crate) fn model_bind_group(&self) -> &'a wgpu::BindGroup { - &self.model_bind_group - } } struct Material { shader: ShaderId, uniforms: [Option<(&'static str, UniformId)>; MAX_UNIFORMS], + bind_group: wgpu::BindGroup, } diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index e06c923..8970573 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -232,9 +232,11 @@ impl<'context> System<'context> for Renderer { continue; }; + let model_bind_group = todo!(); + render_pass.set_pipeline(material.pipeline()); render_pass.set_bind_group(1, material.material_bind_group(), &[]); - render_pass.set_bind_group(2, material.model_bind_group(), &[]); + render_pass.set_bind_group(2, &model_bind_group, &[]); render_pass.set_vertex_buffer(0, mesh.vertex_buffer()); render_pass.set_index_buffer(mesh.index_buffer(), wgpu::IndexFormat::Uint32); render_pass.draw_indexed(0..mesh.index_count(), 0, 0..1); diff --git a/engine/src/shaders.rs b/engine/src/shaders.rs index d9f5254..906544d 100644 --- a/engine/src/shaders.rs +++ b/engine/src/shaders.rs @@ -161,6 +161,10 @@ impl Shaders { pub(crate) fn global_bind_group_layout(&self) -> &wgpu::BindGroupLayout { &self.global_bind_group_layout } + + pub(crate) fn material_bind_group_layout(&self) -> &wgpu::BindGroupLayout { + &self.material_bind_group_layout + } } pub struct Shader { @@ -215,23 +219,21 @@ impl<'context> InfallibleSystem<'context> for Shaders { }, wgpu::BindGroupLayoutEntry { binding: 3, - visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT, + visibility: wgpu::ShaderStages::VERTEX, ty: wgpu::BindingType::Buffer { ty: wgpu::BufferBindingType::Uniform, has_dynamic_offset: false, - min_binding_size: NonZeroU64::new( - std::mem::size_of::>() as u64 - ), + min_binding_size: NonZeroU64::new(std::mem::size_of::() as u64), }, count: None, }, wgpu::BindGroupLayoutEntry { binding: 4, - visibility: wgpu::ShaderStages::VERTEX, - ty: wgpu::BindingType::Buffer { - ty: wgpu::BufferBindingType::Uniform, - has_dynamic_offset: false, - min_binding_size: NonZeroU64::new(std::mem::size_of::() as u64), + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Texture { + sample_type: wgpu::TextureSampleType::Float { filterable: true }, + view_dimension: wgpu::TextureViewDimension::D2, + multisampled: false, }, count: None, }, @@ -254,11 +256,13 @@ impl<'context> InfallibleSystem<'context> for Shaders { }, wgpu::BindGroupLayoutEntry { binding: 1, - visibility: wgpu::ShaderStages::FRAGMENT, - ty: wgpu::BindingType::Texture { - sample_type: wgpu::TextureSampleType::Float { filterable: true }, - view_dimension: wgpu::TextureViewDimension::D2, - multisampled: false, + visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: NonZeroU64::new( + std::mem::size_of::>() as u64 + ), }, count: None, }, diff --git a/game/src/game_shaders.rs b/game/src/game_shaders.rs index 995fc49..8720841 100644 --- a/game/src/game_shaders.rs +++ b/game/src/game_shaders.rs @@ -183,6 +183,8 @@ impl<'context> Dependencies<'context> { .materials .add( self.entities, + self.shaders, + self.window, parent, globals.static_shader, "flats_material", @@ -208,6 +210,8 @@ impl<'context> Dependencies<'context> { .materials .add( self.entities, + self.shaders, + self.window, parent, globals.static_shader, "walls_material", @@ -231,7 +235,14 @@ impl<'context> Dependencies<'context> { let sky_uniforms = self.load_sky_uniforms(parent)?; let sky_material = self .materials - .add(self.entities, parent, globals.sky_shader, "sky_material")? + .add( + self.entities, + self.shaders, + self.window, + parent, + globals.sky_shader, + "sky_material", + )? .add_uniform("u_modelview", modelview) .add_uniform("u_projection", projection) .add_uniform("u_palette", globals.palette) @@ -244,6 +255,8 @@ impl<'context> Dependencies<'context> { .materials .add( self.entities, + self.shaders, + self.window, parent, globals.sprite_shader, "decor_material", From abd6cd88a2be0d4399e0a120b8c407abc8d1637b Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Fri, 26 Jan 2024 15:17:37 +0100 Subject: [PATCH 13/58] Implement material bind group --- engine/src/materials.rs | 104 ++++++++++++++++++++++++++------------- engine/src/renderer.rs | 2 +- engine/src/uniforms.rs | 36 +++++++++----- game/src/game_shaders.rs | 84 ++++++++----------------------- 4 files changed, 115 insertions(+), 111 deletions(-) diff --git a/engine/src/materials.rs b/engine/src/materials.rs index ecd3aa9..97a4647 100644 --- a/engine/src/materials.rs +++ b/engine/src/materials.rs @@ -1,5 +1,3 @@ -use crate::Window; - use super::entities::{Entities, Entity, EntityId}; use super::errors::Result; use super::shaders::{ShaderId, Shaders}; @@ -8,6 +6,7 @@ use super::uniforms::{UniformId, Uniforms}; use glium::Program; use idcontain::IdMapVec; use log::{debug, error}; +use wgpu::util::DeviceExt; pub const MAX_UNIFORMS: usize = 64; @@ -30,43 +29,17 @@ impl Materials { pub fn add<'a>( &'a mut self, entities: &mut Entities, - shaders: &Shaders, - window: &Window, parent: EntityId, shader: ShaderId, name: &'static str, ) -> Result> { - let bind_group = window - .device() - .create_bind_group(&wgpu::BindGroupDescriptor { - label: Some(name), - layout: &shaders.material_bind_group_layout(), - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::TextureView(&atlas_view), - }, - wgpu::BindGroupEntry { - binding: 1, - resource: wgpu::BindingResource::Buffer( - atlas_size_buffer.as_entire_binding(), - ), - }, - wgpu::BindGroupEntry { - binding: 3, - resource: wgpu::BindingResource::Buffer( - tiled_band_size_buffer.as_entire_binding(), - ), - }, - ], - }); let id = entities.add(parent, name)?; self.map.insert( id, Material { shader, uniforms: [None; MAX_UNIFORMS], - bind_group, + bind_group: None, }, ); debug!( @@ -132,7 +105,10 @@ impl Materials { Some(MaterialRef { shader, pipeline, - material_bind_group: &material.bind_group, + bind_group: material + .bind_group + .as_ref() + .expect("Bind group must be present when rendering"), }) } } @@ -162,6 +138,66 @@ impl<'a> MaterialRefMut<'a> { ); } + pub fn with_atlas( + &mut self, + atlas: &wgpu::Texture, + device: &wgpu::Device, + shaders: &Shaders, + ) -> &mut Self { + let atlas_view = atlas.create_view(&Default::default()); + let atlas_size = [atlas.width() as f32, atlas.height() as f32]; + let atlas_size_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice(&atlas_size), + usage: wgpu::BufferUsages::UNIFORM, + }); + self.material.bind_group = Some(device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &shaders.material_bind_group_layout(), + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(&atlas_view), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: atlas_size_buffer.as_entire_binding(), + }, + ], + })); + self + } + + pub fn with_sky_texture( + &mut self, + texture: &wgpu::Texture, + tiled_band_size: f32, + device: &wgpu::Device, + shaders: &Shaders, + ) -> &mut Self { + let texture_view = texture.create_view(&Default::default()); + let tiled_band_size_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice(&[tiled_band_size]), + usage: wgpu::BufferUsages::UNIFORM, + }); + self.material.bind_group = Some(device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: &shaders.material_bind_group_layout(), + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(&texture_view), + }, + wgpu::BindGroupEntry { + binding: 3, + resource: tiled_band_size_buffer.as_entire_binding(), + }, + ], + })); + self + } + pub fn id(&self) -> MaterialId { self.id } @@ -170,7 +206,7 @@ impl<'a> MaterialRefMut<'a> { pub struct MaterialRef<'a> { shader: &'a Program, pipeline: &'a wgpu::RenderPipeline, - material_bind_group: &'a wgpu::BindGroup, + bind_group: &'a wgpu::BindGroup, } impl<'context> InfallibleSystem<'context> for Materials { @@ -215,13 +251,13 @@ impl<'a> MaterialRef<'a> { &self.pipeline } - pub(crate) fn material_bind_group(&self) -> &'a wgpu::BindGroup { - &self.material_bind_group + pub(crate) fn bind_group(&self) -> &'a wgpu::BindGroup { + &self.bind_group } } struct Material { shader: ShaderId, uniforms: [Option<(&'static str, UniformId)>; MAX_UNIFORMS], - bind_group: wgpu::BindGroup, + bind_group: Option, } diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 8970573..5e8ff5a 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -235,7 +235,7 @@ impl<'context> System<'context> for Renderer { let model_bind_group = todo!(); render_pass.set_pipeline(material.pipeline()); - render_pass.set_bind_group(1, material.material_bind_group(), &[]); + render_pass.set_bind_group(1, material.bind_group(), &[]); render_pass.set_bind_group(2, &model_bind_group, &[]); render_pass.set_vertex_buffer(0, mesh.vertex_buffer()); render_pass.set_index_buffer(mesh.index_buffer(), wgpu::IndexFormat::Uint32); diff --git a/engine/src/uniforms.rs b/engine/src/uniforms.rs index 91abdf4..6d3b802 100644 --- a/engine/src/uniforms.rs +++ b/engine/src/uniforms.rs @@ -2,6 +2,7 @@ use super::entities::{Entities, Entity, EntityId}; use super::errors::{ErrorKind, Result}; use super::system::InfallibleSystem; use super::window::Window; +use bytemuck::Pod; use failchain::bail; use glium::buffer::Content as BufferContent; use glium::texture::buffer_texture::{BufferTexture, BufferTextureType}; @@ -12,6 +13,7 @@ use log::{debug, error}; use math::{Mat4, Vec2, Vec2f}; use std::borrow::Cow; use std::marker::PhantomData; +use wgpu::util::DeviceExt; #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Copy, Clone)] pub struct Texture2dId(EntityId); @@ -143,7 +145,7 @@ impl Uniforms { self.vec2fs.get_mut(id.0) } - pub fn add_texture_2d<'a, PixelT: PixelValue>( + pub fn add_texture_2d<'a, PixelT: Pod>( &mut self, window: &Window, entities: &mut Entities, @@ -151,9 +153,9 @@ impl Uniforms { name: &'static str, pixels: &'a [PixelT], size: Vec2, - format: ClientFormat, + format: wgpu::TextureFormat, sampler: Option, - ) -> Result { + ) -> Result { debug!( "Creating texture {:?}: pixels={}, size={:?}, format={:?}, sampler={:?}", name, @@ -162,24 +164,32 @@ impl Uniforms { format, sampler, ); - let gl = GliumTexture2d::new( - window.facade(), - RawImage2d { - data: Cow::Borrowed(pixels), - width: size[0] as u32, - height: size[1] as u32, + let texture = window.device().create_texture_with_data( + window.queue(), + &wgpu::TextureDescriptor { + label: Some(name), + size: wgpu::Extent3d { + width: size[0] as u32, + height: size[1] as u32, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, format, + usage: wgpu::TextureUsages::TEXTURE_BINDING, + view_formats: &[], }, - ) - .map_err(ErrorKind::glium(name))?; + wgpu::util::TextureDataOrder::LayerMajor, + bytemuck::cast_slice(pixels), + ); debug!("Texture {:?} created successfully", name); let id = entities.add(parent, name)?; - self.texture2ds.insert(id, Texture2d { gl, sampler }); debug!( "Added texture {:?} {:?} as child of {:?}.", name, id, parent ); - Ok(Texture2dId(id)) + Ok(texture) } pub fn get_texture_2d_mut(&mut self, texture_id: Texture2dId) -> Option { diff --git a/game/src/game_shaders.rs b/game/src/game_shaders.rs index 8720841..7d766b9 100644 --- a/game/src/game_shaders.rs +++ b/game/src/game_shaders.rs @@ -2,10 +2,10 @@ use crate::vertex::{SkyVertex, SpriteVertex, StaticVertex}; use super::wad_system::WadSystem; use engine::{ - BufferTextureId, BufferTextureType, ClientFormat, DependenciesFrom, Entities, EntityId, Error, + BufferTextureId, BufferTextureType, DependenciesFrom, Entities, EntityId, Error, FloatUniformId, MagnifySamplerFilter, MaterialId, Materials, MinifySamplerFilter, RenderPipeline, Result, SamplerBehavior, SamplerWrapFunction, ShaderId, ShaderVertex, Shaders, - System, Texture2dId, Tick, Uniforms, Window, + System, Tick, Uniforms, Window, }; use log::{error, info}; use math::Vec2; @@ -115,14 +115,14 @@ pub struct GameShaders { struct Globals { time: FloatUniformId, lights_buffer_texture: BufferTextureId, - palette: Texture2dId, + palette: wgpu::Texture, static_shader: ShaderId, sky_shader: ShaderId, sprite_shader: ShaderId, } impl<'context> Dependencies<'context> { - fn load_palette(&mut self, parent: EntityId) -> Result { + fn load_palette(&mut self, parent: EntityId) -> Result { let palette = self.wad.textures.build_palette_texture(0, 0, 32); self.uniforms.add_texture_2d( self.window, @@ -131,7 +131,7 @@ impl<'context> Dependencies<'context> { "palette", &palette.pixels, Vec2::new(COLORMAP_SIZE, palette.pixels.len() / PALETTE_SIZE), - ClientFormat::U8U8U8, + wgpu::TextureFormat::Rgba8Unorm, Some(SamplerBehavior { wrap_function: ( SamplerWrapFunction::Clamp, @@ -183,26 +183,15 @@ impl<'context> Dependencies<'context> { .materials .add( self.entities, - self.shaders, - self.window, parent, globals.static_shader, "flats_material", )? + .with_atlas(&flats_atlas.texture, self.window.device(), self.shaders) .add_uniform("u_modelview", modelview) .add_uniform("u_projection", projection) .add_uniform("u_time", globals.time) .add_uniform("u_lights", globals.lights_buffer_texture) - .add_uniform("u_palette", globals.palette) - .add_uniform("u_atlas", flats_atlas.texture) - .add_uniform( - "u_atlas_size", - self.uniforms.add_texture2d_size( - self.entities, - "flats_atlas_size_uniform", - flats_atlas.texture, - )?, - ) .id(); let walls_atlas = self.load_walls_atlas(parent)?; @@ -210,44 +199,29 @@ impl<'context> Dependencies<'context> { .materials .add( self.entities, - self.shaders, - self.window, parent, globals.static_shader, "walls_material", )? + .with_atlas(&walls_atlas.texture, self.window.device(), self.shaders) .add_uniform("u_modelview", modelview) .add_uniform("u_projection", projection) .add_uniform("u_time", globals.time) .add_uniform("u_lights", globals.lights_buffer_texture) - .add_uniform("u_palette", globals.palette) - .add_uniform("u_atlas", walls_atlas.texture) - .add_uniform( - "u_atlas_size", - self.uniforms.add_texture2d_size( - self.entities, - "walls_atlas_size_uniform", - walls_atlas.texture, - )?, - ) .id(); let sky_uniforms = self.load_sky_uniforms(parent)?; let sky_material = self .materials - .add( - self.entities, + .add(self.entities, parent, globals.sky_shader, "sky_material")? + .with_sky_texture( + &sky_uniforms.texture, + sky_uniforms.tiled_band_size, + self.window.device(), self.shaders, - self.window, - parent, - globals.sky_shader, - "sky_material", - )? + ) .add_uniform("u_modelview", modelview) .add_uniform("u_projection", projection) - .add_uniform("u_palette", globals.palette) - .add_uniform("u_texture", sky_uniforms.texture) - .add_uniform("u_tiled_band_size", sky_uniforms.tiled_band_size) .id(); let decor_atlas = self.load_decor_atlas(parent)?; @@ -255,26 +229,15 @@ impl<'context> Dependencies<'context> { .materials .add( self.entities, - self.shaders, - self.window, parent, globals.sprite_shader, "decor_material", )? + .with_atlas(&decor_atlas.texture, self.window.device(), self.shaders) .add_uniform("u_modelview", modelview) .add_uniform("u_projection", projection) .add_uniform("u_time", globals.time) .add_uniform("u_lights", globals.lights_buffer_texture) - .add_uniform("u_palette", globals.palette) - .add_uniform("u_atlas", decor_atlas.texture) - .add_uniform( - "u_atlas_size", - self.uniforms.add_texture2d_size( - self.entities, - "decor_atlas_size_uniform", - decor_atlas.texture, - )?, - ) .id(); Ok(LevelMaterials { @@ -392,12 +355,7 @@ impl<'context> Dependencies<'context> { "sky_texture", TextureSpec::TextureName(texture_name), )?, - tiled_band_size: self.uniforms.add_float( - self.entities, - parent, - "sky_tiled_band_size_uniform", - tiled_band_size, - )?, + tiled_band_size, }) } @@ -406,7 +364,7 @@ impl<'context> Dependencies<'context> { parent: EntityId, name: &'static str, texture_spec: TextureSpec, - ) -> Result { + ) -> Result { let sampler = Some(SamplerBehavior { wrap_function: ( SamplerWrapFunction::Repeat, @@ -451,7 +409,7 @@ impl<'context> Dependencies<'context> { name, pixels, size, - ClientFormat::U8U8, + wgpu::TextureFormat::Rgba8Unorm, sampler, )?, ImageRef::Opaque { pixels, size } => self.uniforms.add_texture_2d( @@ -461,7 +419,7 @@ impl<'context> Dependencies<'context> { name, pixels, size, - ClientFormat::U8, + wgpu::TextureFormat::Rgba8Unorm, sampler, )?, }) @@ -479,12 +437,12 @@ impl<'context> Dependencies<'context> { } struct SkyUniforms { - tiled_band_size: FloatUniformId, - texture: Texture2dId, + tiled_band_size: f32, + texture: wgpu::Texture, } struct Atlas { - texture: Texture2dId, + texture: wgpu::Texture, bounds: BoundsLookup, } From 91d12dfdff01522129b9490620e35a4c3cc24102 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Fri, 26 Jan 2024 15:19:22 +0100 Subject: [PATCH 14/58] Remove sampler from material texture --- assets/shaders/sky.wgsl | 1 + assets/shaders/sprite.wgsl | 1 + assets/shaders/static.wgsl | 1 + engine/src/uniforms.rs | 4 +--- game/src/game_shaders.rs | 25 +------------------------ 5 files changed, 5 insertions(+), 27 deletions(-) diff --git a/assets/shaders/sky.wgsl b/assets/shaders/sky.wgsl index fa5598c..c18198f 100644 --- a/assets/shaders/sky.wgsl +++ b/assets/shaders/sky.wgsl @@ -1,4 +1,5 @@ @group(0) @binding(0) var u_projection: mat4x4; +// TODO: There should be a separate sampler for the palette, using clamp semantics rather than repeat @group(0) @binding(1) var u_sampler: sampler; @group(0) @binding(4) var u_palette: texture_2d; diff --git a/assets/shaders/sprite.wgsl b/assets/shaders/sprite.wgsl index 50376a1..bedb884 100644 --- a/assets/shaders/sprite.wgsl +++ b/assets/shaders/sprite.wgsl @@ -1,4 +1,5 @@ @group(0) @binding(0) var u_projection: mat4x4; +// TODO: There should be a separate sampler for the palette, using clamp semantics rather than repeat @group(0) @binding(1) var u_sampler: sampler; @group(0) @binding(2) var u_lights: array; @group(0) @binding(3) var u_time: f32; diff --git a/assets/shaders/static.wgsl b/assets/shaders/static.wgsl index 692eaea..5896bb3 100644 --- a/assets/shaders/static.wgsl +++ b/assets/shaders/static.wgsl @@ -1,4 +1,5 @@ @group(0) @binding(0) var u_projection: mat4x4; +// TODO: There should be a separate sampler for the palette, using clamp semantics rather than repeat @group(0) @binding(1) var u_sampler: sampler; @group(0) @binding(2) var u_lights: array; @group(0) @binding(3) var u_time: f32; diff --git a/engine/src/uniforms.rs b/engine/src/uniforms.rs index 6d3b802..ee0f83f 100644 --- a/engine/src/uniforms.rs +++ b/engine/src/uniforms.rs @@ -154,15 +154,13 @@ impl Uniforms { pixels: &'a [PixelT], size: Vec2, format: wgpu::TextureFormat, - sampler: Option, ) -> Result { debug!( - "Creating texture {:?}: pixels={}, size={:?}, format={:?}, sampler={:?}", + "Creating texture {:?}: pixels={}, size={:?}, format={:?}", name, pixels.len(), size, format, - sampler, ); let texture = window.device().create_texture_with_data( window.queue(), diff --git a/game/src/game_shaders.rs b/game/src/game_shaders.rs index 7d766b9..f21871a 100644 --- a/game/src/game_shaders.rs +++ b/game/src/game_shaders.rs @@ -3,8 +3,7 @@ use crate::vertex::{SkyVertex, SpriteVertex, StaticVertex}; use super::wad_system::WadSystem; use engine::{ BufferTextureId, BufferTextureType, DependenciesFrom, Entities, EntityId, Error, - FloatUniformId, MagnifySamplerFilter, MaterialId, Materials, MinifySamplerFilter, - RenderPipeline, Result, SamplerBehavior, SamplerWrapFunction, ShaderId, ShaderVertex, Shaders, + FloatUniformId, MaterialId, Materials, RenderPipeline, Result, ShaderId, ShaderVertex, Shaders, System, Tick, Uniforms, Window, }; use log::{error, info}; @@ -132,16 +131,6 @@ impl<'context> Dependencies<'context> { &palette.pixels, Vec2::new(COLORMAP_SIZE, palette.pixels.len() / PALETTE_SIZE), wgpu::TextureFormat::Rgba8Unorm, - Some(SamplerBehavior { - wrap_function: ( - SamplerWrapFunction::Clamp, - SamplerWrapFunction::Clamp, - SamplerWrapFunction::Clamp, - ), - minify_filter: MinifySamplerFilter::Nearest, - magnify_filter: MagnifySamplerFilter::Nearest, - ..SamplerBehavior::default() - }), ) } @@ -365,16 +354,6 @@ impl<'context> Dependencies<'context> { name: &'static str, texture_spec: TextureSpec, ) -> Result { - let sampler = Some(SamplerBehavior { - wrap_function: ( - SamplerWrapFunction::Repeat, - SamplerWrapFunction::Repeat, - SamplerWrapFunction::Repeat, - ), - minify_filter: MinifySamplerFilter::Nearest, - magnify_filter: MagnifySamplerFilter::Nearest, - ..SamplerBehavior::default() - }); let dummy_texture; let image_ref = match texture_spec { TextureSpec::TextureName(texture_name) => { @@ -410,7 +389,6 @@ impl<'context> Dependencies<'context> { pixels, size, wgpu::TextureFormat::Rgba8Unorm, - sampler, )?, ImageRef::Opaque { pixels, size } => self.uniforms.add_texture_2d( self.window, @@ -420,7 +398,6 @@ impl<'context> Dependencies<'context> { pixels, size, wgpu::TextureFormat::Rgba8Unorm, - sampler, )?, }) } From 8373e43cd2ac28cd65d15ce7fa19b0f3c12d0da8 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Fri, 26 Jan 2024 17:03:01 +0100 Subject: [PATCH 15/58] Set up global bind group in Uniforms --- engine/src/renderer.rs | 33 +-------------- engine/src/uniforms.rs | 91 +++++++++++++++++++++++++++++++++------- game/src/game_shaders.rs | 24 +++++------ game/src/level.rs | 9 ++-- 4 files changed, 92 insertions(+), 65 deletions(-) diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 5e8ff5a..8c21fc5 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -35,7 +35,6 @@ pub struct Renderer { view: wgpu::TextureView, _depth_texture: wgpu::Texture, depth_view: wgpu::TextureView, - global_bind_group: wgpu::BindGroup, } impl<'context> System<'context> for Renderer { @@ -75,42 +74,12 @@ impl<'context> System<'context> for Renderer { view_formats: &[], }); let depth_view = depth_texture.create_view(&Default::default()); - let global_bind_group = - deps.window - .device() - .create_bind_group(&wgpu::BindGroupDescriptor { - label: Some("Global bind group"), - layout: deps.shaders.global_bind_group_layout(), - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: todo!(), - }, - wgpu::BindGroupEntry { - binding: 1, - resource: todo!(), - }, - wgpu::BindGroupEntry { - binding: 2, - resource: todo!(), - }, - wgpu::BindGroupEntry { - binding: 3, - resource: todo!(), - }, - wgpu::BindGroupEntry { - binding: 4, - resource: todo!(), - }, - ], - }); Ok(Renderer { removed: Vec::with_capacity(32), _texture: texture, view, _depth_texture: depth_texture, depth_view, - global_bind_group, }) } @@ -181,7 +150,7 @@ impl<'context> System<'context> for Renderer { timestamp_writes: None, occlusion_query_set: None, }); - render_pass.set_bind_group(0, &self.global_bind_group, &[]); + render_pass.set_bind_group(0, deps.uniforms.global_bind_group(), &[]); for (index, &Model { mesh, material }) in pipe.models.access().iter().enumerate() { // For each model we need to assemble three things to render it: transform, mesh and // material. We get the entity id and query the corresponding systems for it. diff --git a/engine/src/uniforms.rs b/engine/src/uniforms.rs index ee0f83f..c1cf72e 100644 --- a/engine/src/uniforms.rs +++ b/engine/src/uniforms.rs @@ -1,3 +1,5 @@ +use crate::Shaders; + use super::entities::{Entities, Entity, EntityId}; use super::errors::{ErrorKind, Result}; use super::system::InfallibleSystem; @@ -12,6 +14,7 @@ use idcontain::IdMapVec; use log::{debug, error}; use math::{Mat4, Vec2, Vec2f}; use std::borrow::Cow; +use std::default; use std::marker::PhantomData; use wgpu::util::DeviceExt; @@ -53,6 +56,7 @@ pub struct Uniforms { buffer_textures_u8: IdMapVec>, mat4s: IdMapVec, vec2fs: IdMapVec, + global_bind_group: Option, } impl Uniforms { @@ -65,6 +69,7 @@ impl Uniforms { ref mut buffer_textures_u8, ref mut mat4s, ref mut vec2fs, + global_bind_group: _, } = *self; for &entity in entities.last_removed() { if texture2ds.remove(entity).is_some() { @@ -200,7 +205,7 @@ impl Uniforms { } // TODO(cristicbz): Make u8 a type param. - pub fn add_persistent_buffer_texture_u8( + pub fn add_persistent_buffer_u8( &mut self, window: &Window, entities: &mut Entities, @@ -208,34 +213,33 @@ impl Uniforms { name: &'static str, size: usize, texture_type: BufferTextureType, - ) -> Result> { + ) -> Result { debug!( - "Creating persistent buffer_texture {:?}, size={:?}, type={:?}", + "Creating persistent buffer {:?}, size={:?}, type={:?}", name, size, texture_type ); - let texture = BufferTexture::empty_persistent(window.facade(), size, texture_type) - .map_err(ErrorKind::glium(name))?; + let buffer = window.device().create_buffer(&wgpu::BufferDescriptor { + label: Some(name), + size: size as u64, + usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }); debug!("Buffer texture {:?} created successfully", name); let id = entities.add(parent, name)?; - self.buffer_textures_u8.insert(id, texture); debug!( - "Added persistent buffer_texture {:?} {:?} as child of {:?}.", + "Added persistent buffer {:?} {:?} as child of {:?}.", name, id, parent ); - Ok(BufferTextureId { - id, - _phantom: PhantomData, - }) + Ok(buffer) } - pub fn map_buffer_texture_u8(&mut self, id: BufferTextureId, writer: F) + pub fn map_buffer_u8(&mut self, buffer: &wgpu::Buffer, writer: F, queue: &wgpu::Queue) where F: FnOnce(&mut [u8]), { - // TODO(cristicbz): Handle missing. - if let Some(buffer) = self.buffer_textures_u8.get_mut(id.id) { - writer(&mut *buffer.map()); - } + let mut data = vec![0u8; buffer.size() as usize]; + writer(&mut data); + queue.write_buffer(buffer, 0, &data); } pub fn add_texture2d_size( @@ -292,6 +296,59 @@ impl Uniforms { .map(AsUniformValue::as_uniform_value), } } + + pub fn set_globals( + &mut self, + device: &wgpu::Device, + shaders: &Shaders, + lights_buffer: &wgpu::Buffer, + palette: &wgpu::Texture, + ) { + // TODO: Create a second sampler for the palette, using clamp address mode. + let sampler = device.create_sampler(&wgpu::SamplerDescriptor { + label: Some("Texture sampler"), + address_mode_u: wgpu::AddressMode::Repeat, + address_mode_v: wgpu::AddressMode::Repeat, + address_mode_w: wgpu::AddressMode::Repeat, + mag_filter: wgpu::FilterMode::Linear, + min_filter: wgpu::FilterMode::Nearest, + mipmap_filter: wgpu::FilterMode::Nearest, + ..Default::default() + }); + let palette_view = palette.create_view(&Default::default()); + self.global_bind_group = Some(device.create_bind_group(&wgpu::BindGroupDescriptor { + label: Some("Global bind group"), + layout: shaders.global_bind_group_layout(), + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: todo!(), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::Sampler(&sampler), + }, + wgpu::BindGroupEntry { + binding: 2, + resource: lights_buffer.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 3, + resource: todo!(), + }, + wgpu::BindGroupEntry { + binding: 4, + resource: wgpu::BindingResource::TextureView(&palette_view), + }, + ], + })) + } + + pub(crate) fn global_bind_group(&self) -> &wgpu::BindGroup { + self.global_bind_group + .as_ref() + .expect("Global bind group must be set to render") + } } pub struct Texture2dRefMut<'uniforms> { @@ -350,6 +407,7 @@ impl<'context> InfallibleSystem<'context> for Uniforms { buffer_textures_u8: IdMapVec::with_capacity(32), mat4s: IdMapVec::with_capacity(32), vec2fs: IdMapVec::with_capacity(32), + global_bind_group: None, } } @@ -362,6 +420,7 @@ impl<'context> InfallibleSystem<'context> for Uniforms { ref mut buffer_textures_u8, ref mut mat4s, ref mut vec2fs, + global_bind_group: _, } = *self; for &entity in entities.last_removed() { if texture2ds.remove(entity).is_some() { diff --git a/game/src/game_shaders.rs b/game/src/game_shaders.rs index f21871a..ac67b8c 100644 --- a/game/src/game_shaders.rs +++ b/game/src/game_shaders.rs @@ -2,9 +2,9 @@ use crate::vertex::{SkyVertex, SpriteVertex, StaticVertex}; use super::wad_system::WadSystem; use engine::{ - BufferTextureId, BufferTextureType, DependenciesFrom, Entities, EntityId, Error, - FloatUniformId, MaterialId, Materials, RenderPipeline, Result, ShaderId, ShaderVertex, Shaders, - System, Tick, Uniforms, Window, + BufferTextureType, DependenciesFrom, Entities, EntityId, Error, FloatUniformId, MaterialId, + Materials, RenderPipeline, Result, ShaderId, ShaderVertex, Shaders, System, Tick, Uniforms, + Window, }; use log::{error, info}; use math::Vec2; @@ -30,8 +30,8 @@ impl GameShaders { self.globals.time } - pub fn lights_buffer_texture(&self) -> BufferTextureId { - self.globals.lights_buffer_texture + pub fn lights_buffer(&self) -> &wgpu::Buffer { + &self.globals.lights_buffer } pub fn level_materials(&self) -> &LevelMaterials { @@ -113,8 +113,7 @@ pub struct GameShaders { struct Globals { time: FloatUniformId, - lights_buffer_texture: BufferTextureId, - palette: wgpu::Texture, + lights_buffer: wgpu::Buffer, static_shader: ShaderId, sky_shader: ShaderId, sprite_shader: ShaderId, @@ -140,7 +139,7 @@ impl<'context> Dependencies<'context> { let time = self .uniforms .add_float(self.entities, parent, "time_uniform", 0.0)?; - let lights_buffer_texture = self.uniforms.add_persistent_buffer_texture_u8( + let lights_buffer = self.uniforms.add_persistent_buffer_u8( self.window, self.entities, parent, @@ -153,10 +152,12 @@ impl<'context> Dependencies<'context> { let sky_shader = self.load_shader::(parent, "sky_shader", "sky")?; let sprite_shader = self.load_shader::(parent, "sprite_shader", "sprite")?; + self.uniforms + .set_globals(self.window.device(), self.shaders, &lights_buffer, &palette); + Ok(Globals { time, - lights_buffer_texture, - palette, + lights_buffer, static_shader, sky_shader, sprite_shader, @@ -180,7 +181,6 @@ impl<'context> Dependencies<'context> { .add_uniform("u_modelview", modelview) .add_uniform("u_projection", projection) .add_uniform("u_time", globals.time) - .add_uniform("u_lights", globals.lights_buffer_texture) .id(); let walls_atlas = self.load_walls_atlas(parent)?; @@ -196,7 +196,6 @@ impl<'context> Dependencies<'context> { .add_uniform("u_modelview", modelview) .add_uniform("u_projection", projection) .add_uniform("u_time", globals.time) - .add_uniform("u_lights", globals.lights_buffer_texture) .id(); let sky_uniforms = self.load_sky_uniforms(parent)?; @@ -226,7 +225,6 @@ impl<'context> Dependencies<'context> { .add_uniform("u_modelview", modelview) .add_uniform("u_projection", projection) .add_uniform("u_time", globals.time) - .add_uniform("u_lights", globals.lights_buffer_texture) .id(); Ok(LevelMaterials { diff --git a/game/src/level.rs b/game/src/level.rs index 3e1779f..d29f8ef 100644 --- a/game/src/level.rs +++ b/game/src/level.rs @@ -259,10 +259,11 @@ impl<'context> System<'context> for Level { .get_float_mut(deps.game_shaders.time()) .expect("missing time"); let light_infos = &mut self.lights; - deps.uniforms - .map_buffer_texture_u8(deps.game_shaders.lights_buffer_texture(), |buffer| { - light_infos.fill_buffer_at(time, buffer) - }); + deps.uniforms.map_buffer_u8( + deps.game_shaders.lights_buffer(), + |buffer| light_infos.fill_buffer_at(time, buffer), + deps.window.queue(), + ); Ok(()) } From a4f437e817bc4a483e25d8fe497574ae5af0ac27 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Fri, 26 Jan 2024 18:56:35 +0100 Subject: [PATCH 16/58] Set up bindings for viewproj matrix --- assets/shaders/sky.wgsl | 6 ++-- assets/shaders/sprite.wgsl | 10 +++--- assets/shaders/static.wgsl | 6 ++-- engine/src/renderer.rs | 24 +++++++-------- engine/src/shaders.rs | 36 ++++++++++++++++------ engine/src/uniforms.rs | 63 +++++++++++++++++++++++++++++++------- 6 files changed, 101 insertions(+), 44 deletions(-) diff --git a/assets/shaders/sky.wgsl b/assets/shaders/sky.wgsl index c18198f..37d1f11 100644 --- a/assets/shaders/sky.wgsl +++ b/assets/shaders/sky.wgsl @@ -1,4 +1,4 @@ -@group(0) @binding(0) var u_projection: mat4x4; +@group(0) @binding(0) var u_viewproj: mat4x4; // TODO: There should be a separate sampler for the palette, using clamp semantics rather than repeat @group(0) @binding(1) var u_sampler: sampler; @group(0) @binding(4) var u_palette: texture_2d; @@ -6,7 +6,7 @@ @group(1) @binding(0) var u_texture: texture_2d; @group(1) @binding(2) var u_tiled_band_size: f32; -@group(2) @binding(0) var u_modelview: mat4x4; +@group(2) @binding(0) var u_model: mat4x4; struct VertexOutput { @builtin(position) clip_position: vec4; @@ -17,7 +17,7 @@ struct VertexOutput { @vertex fn main_vs(a_pos: vec3) -> VertexOutput { var out: VertexOutput; - mat4 transform = u_projection * u_modelview; + mat4 transform = u_viewproj * u_model; vec4forward = transform[2]; out.v_r = vec2(atan(forward.x, forward.z), forward.y / forward.w); vec4projected_pos = transform * vec4(a_pos, 1); diff --git a/assets/shaders/sprite.wgsl b/assets/shaders/sprite.wgsl index bedb884..032d9ff 100644 --- a/assets/shaders/sprite.wgsl +++ b/assets/shaders/sprite.wgsl @@ -1,4 +1,4 @@ -@group(0) @binding(0) var u_projection: mat4x4; +@group(0) @binding(0) var u_viewproj: mat4x4; // TODO: There should be a separate sampler for the palette, using clamp semantics rather than repeat @group(0) @binding(1) var u_sampler: sampler; @group(0) @binding(2) var u_lights: array; @@ -8,7 +8,8 @@ @group(1) @binding(0) var u_atlas: texture_2d; @group(1) @binding(1) var u_atlas_size: vec2; -@group(2) @binding(0) var u_modelview: mat4x4; +@group(2) @binding(0) var u_model: mat4x4; +@group(2) @binding(1) var u_right: vec3; struct VertexInput { @location(0) a_pos: vec3; @@ -50,9 +51,8 @@ fn main_vs(in: VertexInput) -> VertexOutput { } out.v_tile_size = in.a_tile_size; - vec3right = vec3(u_modelview[0][0], u_modelview[1][0], u_modelview[2][0]); - vec3pos = in.a_pos + right * in.a_local_x; - vec4projected_pos = u_projection * (u_modelview * vec4(pos, 1.0)); + let pos = in.a_pos + u_right * in.a_local_x; + let projected_pos = u_viewproj * (u_model * vec4(pos, 1.0)); out.v_light = u_lights[in.a_light]; out.v_dist = projected_pos.w; out.clip_position = projected_pos; diff --git a/assets/shaders/static.wgsl b/assets/shaders/static.wgsl index 5896bb3..fd429d6 100644 --- a/assets/shaders/static.wgsl +++ b/assets/shaders/static.wgsl @@ -1,4 +1,4 @@ -@group(0) @binding(0) var u_projection: mat4x4; +@group(0) @binding(0) var u_viewproj: mat4x4; // TODO: There should be a separate sampler for the palette, using clamp semantics rather than repeat @group(0) @binding(1) var u_sampler: sampler; @group(0) @binding(2) var u_lights: array; @@ -8,7 +8,7 @@ @group(1) @binding(0) var u_atlas: texture_2d; @group(1) @binding(1) var u_atlas_size: vec2; -@group(2) @binding(0) var u_modelview: mat4x4; +@group(2) @binding(0) var u_model: mat4x4; struct VertexInput { @location(0) a_pos: vec3; @@ -50,7 +50,7 @@ fn main_vs(in: VertexInput) -> VertexOutput { out.v_atlas_uv = vec2(atlas_u, atlas_v); } out.v_tile_size = in.a_tile_size; - let projected_pos = u_projection * u_modelview * vec4(in.a_pos, 1); + let projected_pos = u_viewproj * u_model * vec4(in.a_pos, 1); out.v_dist = projected_pos.w; out.v_light = u_lights[in.a_light]; out.clip_position = projected_pos; diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 8c21fc5..bc90293 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -13,7 +13,7 @@ use super::window::Window; use crate::internal_derive::DependenciesFrom; use failchain::ResultExt; use log::{error, info}; -use math::prelude::*; +use math::{prelude::*, Mat4}; #[derive(DependenciesFrom)] pub struct Dependencies<'context> { @@ -108,17 +108,17 @@ impl<'context> System<'context> for Renderer { pipe.camera = None; return Ok(()); }; - // let view_matrix: Mat4 = view_transform.into(); - - // Set projection. - // TODO: This needs to be put in a buffer and copied to the GPU. - *deps - .uniforms - .get_mat4_mut(pipe.projection) - .expect("projection uniform missing") = *deps - .projections - .get_matrix(camera_id) - .expect("camera projection missing"); + let view_matrix: Mat4 = view_transform.into(); + + // Set view-projection. + deps.uniforms.update_projection( + *deps + .projections + .get_matrix(camera_id) + .expect("camera projection missing") + * view_matrix, + deps.window.queue(), + ); // Render all the models in turn. let mut frame = deps.window.draw(); diff --git a/engine/src/shaders.rs b/engine/src/shaders.rs index 906544d..8376c2a 100644 --- a/engine/src/shaders.rs +++ b/engine/src/shaders.rs @@ -9,7 +9,7 @@ use failchain::ResultExt; use glium::program::{Program, ProgramCreationInput}; use idcontain::IdMapVec; use log::{debug, error}; -use math::{Mat4, Vec2}; +use math::{Mat4, Vec2, Vec3}; use std::fs::File; use std::io::Read; use std::io::Result as IoResult; @@ -284,16 +284,32 @@ impl<'context> InfallibleSystem<'context> for Shaders { .device() .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { label: Some("model_bind_group_layout"), - entries: &[wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStages::VERTEX, - ty: wgpu::BindingType::Buffer { - ty: wgpu::BufferBindingType::Uniform, - has_dynamic_offset: false, - min_binding_size: NonZeroU64::new(std::mem::size_of::() as u64), + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::VERTEX, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: NonZeroU64::new( + std::mem::size_of::() as u64 + ), + }, + count: None, }, - count: None, - }], + wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::VERTEX, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: NonZeroU64::new( + std::mem::size_of::>() as u64 + ), + }, + count: None, + }, + ], }); Shaders { diff --git a/engine/src/uniforms.rs b/engine/src/uniforms.rs index c1cf72e..5a9e97c 100644 --- a/engine/src/uniforms.rs +++ b/engine/src/uniforms.rs @@ -4,7 +4,9 @@ use super::entities::{Entities, Entity, EntityId}; use super::errors::{ErrorKind, Result}; use super::system::InfallibleSystem; use super::window::Window; +use crate::internal_derive::DependenciesFrom; use bytemuck::Pod; +use cgmath::SquareMatrix; use failchain::bail; use glium::buffer::Content as BufferContent; use glium::texture::buffer_texture::{BufferTexture, BufferTextureType}; @@ -14,7 +16,6 @@ use idcontain::IdMapVec; use log::{debug, error}; use math::{Mat4, Vec2, Vec2f}; use std::borrow::Cow; -use std::default; use std::marker::PhantomData; use wgpu::util::DeviceExt; @@ -57,6 +58,8 @@ pub struct Uniforms { mat4s: IdMapVec, vec2fs: IdMapVec, global_bind_group: Option, + projection_buffer: wgpu::Buffer, + time_buffer: wgpu::Buffer, } impl Uniforms { @@ -70,6 +73,8 @@ impl Uniforms { ref mut mat4s, ref mut vec2fs, global_bind_group: _, + projection_buffer: _, + time_buffer: _, } = *self; for &entity in entities.last_removed() { if texture2ds.remove(entity).is_some() { @@ -322,7 +327,7 @@ impl Uniforms { entries: &[ wgpu::BindGroupEntry { binding: 0, - resource: todo!(), + resource: self.projection_buffer.as_entire_binding(), }, wgpu::BindGroupEntry { binding: 1, @@ -334,7 +339,7 @@ impl Uniforms { }, wgpu::BindGroupEntry { binding: 3, - resource: todo!(), + resource: self.time_buffer.as_entire_binding(), }, wgpu::BindGroupEntry { binding: 4, @@ -349,6 +354,15 @@ impl Uniforms { .as_ref() .expect("Global bind group must be set to render") } + + pub(crate) fn update_projection(&self, projection: Mat4, queue: &wgpu::Queue) { + let projection: [[f32; 4]; 4] = projection.into(); + queue.write_buffer( + &self.projection_buffer, + 0, + bytemuck::cast_slice(&projection), + ); + } } pub struct Texture2dRefMut<'uniforms> { @@ -393,14 +407,37 @@ impl<'uniforms> Texture2dRefMut<'uniforms> { } } +#[derive(DependenciesFrom)] +pub struct Dependencies<'context> { + window: &'context Window, + entities: &'context Entities, +} + impl<'context> InfallibleSystem<'context> for Uniforms { - type Dependencies = &'context Entities; + type Dependencies = Dependencies<'context>; fn debug_name() -> &'static str { "uniforms" } - fn create(_deps: &Entities) -> Self { + fn create(deps: Dependencies<'context>) -> Self { + let projection: [[f32; 4]; 4] = Mat4::identity().into(); + let projection_buffer = + deps.window + .device() + .create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Projection buffer"), + contents: bytemuck::cast_slice(&projection), + usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, + }); + let time_buffer = + deps.window + .device() + .create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Time buffer"), + contents: bytemuck::cast_slice(&[0.0f32]), + usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, + }); Uniforms { texture2ds: IdMapVec::with_capacity(32), floats: IdMapVec::with_capacity(32), @@ -408,10 +445,12 @@ impl<'context> InfallibleSystem<'context> for Uniforms { mat4s: IdMapVec::with_capacity(32), vec2fs: IdMapVec::with_capacity(32), global_bind_group: None, + projection_buffer, + time_buffer, } } - fn update(&mut self, entities: &Entities) { + fn update(&mut self, deps: Dependencies<'context>) { // Explicitly destructure all fields since the for-loop needs to be changed when adding a // new map. let Uniforms { @@ -421,8 +460,10 @@ impl<'context> InfallibleSystem<'context> for Uniforms { ref mut mat4s, ref mut vec2fs, global_bind_group: _, + projection_buffer: _, + time_buffer: _, } = *self; - for &entity in entities.last_removed() { + for &entity in deps.entities.last_removed() { if texture2ds.remove(entity).is_some() { debug!("Removed uniform {:?}.", entity); } @@ -441,12 +482,12 @@ impl<'context> InfallibleSystem<'context> for Uniforms { } } - fn teardown(&mut self, entities: &Entities) { - self.update(entities); + fn teardown(&mut self, deps: Dependencies<'context>) { + self.update(deps.entities); } - fn destroy(mut self, entities: &Entities) { - self.update(entities); + fn destroy(mut self, deps: Dependencies<'context>) { + self.update(deps.entities); if !self.texture2ds.is_empty() { error!( "Uniforms leaked, {} instances.", From 35c7b2bf88ad3d4976d8caa6fb8e98509cb37b1e Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Fri, 26 Jan 2024 19:33:09 +0100 Subject: [PATCH 17/58] Add bind group to mesh --- engine/src/meshes.rs | 13 +++++++++++++ engine/src/renderer.rs | 18 ++---------------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/engine/src/meshes.rs b/engine/src/meshes.rs index e7c4761..069e07a 100644 --- a/engine/src/meshes.rs +++ b/engine/src/meshes.rs @@ -37,13 +37,16 @@ impl Meshes { InternalMeshData::Owned { ref vertices, ref indices, + ref bind_group, } => MeshRef { vertices, indices: indices.as_ref(), + bind_group, }, InternalMeshData::Inherit { vertices_from, ref indices, + ref bind_group, } => MeshRef { vertices: match self .map @@ -55,6 +58,7 @@ impl Meshes { _ => panic!("unowned mesh in stored vertices_from"), }, indices: Some(indices), + bind_group, }, }) } @@ -64,6 +68,7 @@ impl Meshes { InternalMeshData::Owned { ref mut vertices, ref mut indices, + bind_group: _, } => MeshRefMut { vertices: Some(vertices), indices: indices.as_mut(), @@ -71,6 +76,7 @@ impl Meshes { InternalMeshData::Inherit { vertices_from: _vertices_from, ref mut indices, + bind_group: _, } => MeshRefMut { vertices: None, indices: Some(indices), @@ -87,6 +93,7 @@ pub struct MeshRefMut<'a> { pub struct MeshRef<'a> { vertices: &'a wgpu::Buffer, indices: Option<&'a wgpu::Buffer>, + bind_group: &'a wgpu::BindGroup, } impl<'a> MeshRef<'a> { @@ -101,6 +108,10 @@ impl<'a> MeshRef<'a> { pub(crate) fn index_count(&self) -> u32 { self.indices.expect("index buffer not present").size() as u32 / 4 } + + pub(crate) fn bind_group(&self) -> &wgpu::BindGroup { + self.bind_group + } } #[must_use] @@ -282,10 +293,12 @@ enum InternalMeshData { Owned { vertices: wgpu::Buffer, indices: Option, + bind_group: wgpu::BindGroup, }, Inherit { vertices_from: MeshId, indices: wgpu::Buffer, + bind_group: wgpu::BindGroup, }, } diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index bc90293..79e6a1a 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -172,19 +172,7 @@ impl<'context> System<'context> for Renderer { continue; }; - // If the model has a transform, then multiply it with the view transform to get the - // modelview matrix. If there is no transform, model is assumed to be in world space, so - // modelview = view. - // TODO: Writing to uniforms can only be done by submitting a write buffer command, and needs to be done in advance of rendering. - // *deps - // .uniforms - // .get_mat4_mut(pipe.modelview) - // .expect("modelview uniform missing") = - // if let Some(model_transform) = deps.transforms.get_absolute(entity) { - // Mat4::from(view_transform.concat(model_transform)) - // } else { - // view_matrix - // }; + // TODO: Set u_right on the mesh let material = if let Some(material) = deps.materials.get(deps.shaders, deps.uniforms, material) @@ -201,11 +189,9 @@ impl<'context> System<'context> for Renderer { continue; }; - let model_bind_group = todo!(); - render_pass.set_pipeline(material.pipeline()); render_pass.set_bind_group(1, material.bind_group(), &[]); - render_pass.set_bind_group(2, &model_bind_group, &[]); + render_pass.set_bind_group(2, mesh.bind_group(), &[]); render_pass.set_vertex_buffer(0, mesh.vertex_buffer()); render_pass.set_index_buffer(mesh.index_buffer(), wgpu::IndexFormat::Uint32); render_pass.draw_indexed(0..mesh.index_count(), 0, 0..1); From d83fe853ad07d203dd3926a365b51312549b0706 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Fri, 26 Jan 2024 19:48:58 +0100 Subject: [PATCH 18/58] Set up model bind group --- engine/src/meshes.rs | 61 +++++++++++++++++++++++++++++++++++++++++-- engine/src/shaders.rs | 4 +++ game/src/level.rs | 27 ++++++++++--------- 3 files changed, 77 insertions(+), 15 deletions(-) diff --git a/engine/src/meshes.rs b/engine/src/meshes.rs index 069e07a..22bacfc 100644 --- a/engine/src/meshes.rs +++ b/engine/src/meshes.rs @@ -1,9 +1,13 @@ +use crate::Shaders; + use super::entities::{Entities, Entity, EntityId}; use super::errors::Result; use super::system::InfallibleSystem; use bytemuck::Pod; +use cgmath::SquareMatrix; use idcontain::IdMapVec; use log::{debug, error}; +use math::Mat4; use wgpu::util::DeviceExt; #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Copy, Clone)] @@ -29,6 +33,7 @@ impl Meshes { }, vertices: (), indices: (), + bind_group: None, } } @@ -109,7 +114,7 @@ impl<'a> MeshRef<'a> { self.indices.expect("index buffer not present").size() as u32 / 4 } - pub(crate) fn bind_group(&self) -> &wgpu::BindGroup { + pub(crate) fn bind_group(&self) -> &'a wgpu::BindGroup { self.bind_group } } @@ -119,6 +124,7 @@ pub struct MeshAdder<'a, VertexDataT, IndexDataT> { context: MeshAdderContext<'a>, vertices: VertexDataT, indices: IndexDataT, + bind_group: Option, } pub struct OwnedVertexData(wgpu::Buffer); @@ -130,6 +136,7 @@ impl<'a, IndexDataT> MeshAdder<'a, (), IndexDataT> { self, vertices: &[VertexT], device: &wgpu::Device, + shaders: &Shaders, ) -> Result> where VertexT: Pod + Send + 'static, @@ -139,10 +146,12 @@ impl<'a, IndexDataT> MeshAdder<'a, (), IndexDataT> { contents: bytemuck::cast_slice(vertices), usage: wgpu::BufferUsages::VERTEX, }); + let bind_group = create_bind_group(device, shaders); Ok(MeshAdder { vertices: OwnedVertexData(buffer), indices: self.indices, context: self.context, + bind_group: Some(bind_group), }) } @@ -150,6 +159,7 @@ impl<'a, IndexDataT> MeshAdder<'a, (), IndexDataT> { self, vertices: &[VertexT], device: &wgpu::Device, + shaders: &Shaders, ) -> Result> where VertexT: Pod + Send + 'static, @@ -159,14 +169,21 @@ impl<'a, IndexDataT> MeshAdder<'a, (), IndexDataT> { contents: bytemuck::cast_slice(vertices), usage: wgpu::BufferUsages::VERTEX, }); + let bind_group = create_bind_group(device, shaders); Ok(MeshAdder { vertices: OwnedVertexData(buffer), indices: self.indices, context: self.context, + bind_group: Some(bind_group), }) } - pub fn shared(self, vertices_from: MeshId) -> MeshAdder<'a, SharedVertexData, IndexDataT> { + pub fn shared( + self, + vertices_from: MeshId, + device: &wgpu::Device, + shaders: &Shaders, + ) -> MeshAdder<'a, SharedVertexData, IndexDataT> { // TODO(cristicbz): If parent comes from a different `Meshes` object, the assertion that // the parent is in the map is in incorrect. let mut owner = vertices_from; @@ -180,10 +197,12 @@ impl<'a, IndexDataT> MeshAdder<'a, (), IndexDataT> { { owner = vertices_from; } + let bind_group = create_bind_group(device, shaders); MeshAdder { vertices: SharedVertexData(owner), indices: self.indices, context: self.context, + bind_group: Some(bind_group), } } } @@ -193,16 +212,19 @@ impl<'a, VertexDataT> MeshAdder<'a, VertexDataT, ()> { self, indices: &[u32], device: &wgpu::Device, + shaders: &Shaders, ) -> Result> { let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: None, contents: bytemuck::cast_slice(indices), usage: wgpu::BufferUsages::INDEX, }); + let bind_group = create_bind_group(device, shaders); Ok(MeshAdder { indices: IndexData(buffer), vertices: self.vertices, context: self.context, + bind_group: Some(bind_group), }) } @@ -210,16 +232,19 @@ impl<'a, VertexDataT> MeshAdder<'a, VertexDataT, ()> { self, indices: &[u32], device: &wgpu::Device, + shaders: &Shaders, ) -> Result> { let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: None, contents: bytemuck::cast_slice(indices), usage: wgpu::BufferUsages::INDEX, }); + let bind_group = create_bind_group(device, shaders); Ok(MeshAdder { indices: IndexData(buffer), vertices: self.vertices, context: self.context, + bind_group: Some(bind_group), }) } } @@ -229,6 +254,7 @@ impl<'a> MeshAdder<'a, OwnedVertexData, ()> { self.context.add(InternalMeshData::Owned { vertices: self.vertices.0, indices: None, + bind_group: self.bind_group.expect("missing bind group"), }) } } @@ -238,6 +264,7 @@ impl<'a> MeshAdder<'a, SharedVertexData, IndexData> { self.context.add(InternalMeshData::Inherit { vertices_from: self.vertices.0, indices: self.indices.0, + bind_group: self.bind_group.expect("missing bind group"), }) } } @@ -247,10 +274,40 @@ impl<'a> MeshAdder<'a, OwnedVertexData, IndexData> { self.context.add(InternalMeshData::Owned { vertices: self.vertices.0, indices: Some(self.indices.0), + bind_group: self.bind_group.expect("missing bind group"), }) } } +fn create_bind_group(device: &wgpu::Device, shaders: &Shaders) -> wgpu::BindGroup { + let model_transform: [[f32; 4]; 4] = Mat4::identity().into(); + let model_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice(&model_transform), + usage: wgpu::BufferUsages::UNIFORM, + }); + let right_vector = [1.0f32, 0.0, 0.0]; + let right_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice(&right_vector), + usage: wgpu::BufferUsages::UNIFORM, + }); + device.create_bind_group(&wgpu::BindGroupDescriptor { + label: None, + layout: shaders.model_bind_group_layout(), + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: model_buffer.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: right_buffer.as_entire_binding(), + }, + ], + }) +} + pub struct Mesh { data: InternalMeshData, } diff --git a/engine/src/shaders.rs b/engine/src/shaders.rs index 8376c2a..eeffb3a 100644 --- a/engine/src/shaders.rs +++ b/engine/src/shaders.rs @@ -165,6 +165,10 @@ impl Shaders { pub(crate) fn material_bind_group_layout(&self) -> &wgpu::BindGroupLayout { &self.material_bind_group_layout } + + pub(crate) fn model_bind_group_layout(&self) -> &wgpu::BindGroupLayout { + &self.model_bind_group_layout + } } pub struct Shader { diff --git a/game/src/level.rs b/game/src/level.rs index d29f8ef..ab3a77b 100644 --- a/game/src/level.rs +++ b/game/src/level.rs @@ -4,8 +4,8 @@ use super::vertex::{SkyVertex, SpriteVertex, StaticVertex}; use super::wad_system::WadSystem; use super::world::{World, WorldBuilder}; use engine::{ - DependenciesFrom, Entities, EntityId, Error, Meshes, RenderPipeline, Result, System, Tick, - Transforms, Uniforms, Window, + DependenciesFrom, Entities, EntityId, Error, Meshes, RenderPipeline, Result, Shaders, System, + Tick, Transforms, Uniforms, Window, }; use log::{debug, error, info, warn}; use math::prelude::*; @@ -43,6 +43,7 @@ pub struct Dependencies<'context> { wad: &'context mut WadSystem, tick: &'context Tick, transforms: &'context mut Transforms, + shaders: &'context Shaders, game_shaders: &'context GameShaders, } @@ -426,19 +427,19 @@ impl<'a> Builder<'a> { let global_static_mesh = deps .meshes .add(deps.entities, root, "global_world_static_mesh") - .immutable(&builder.static_vertices, deps.window.device())? + .immutable(&builder.static_vertices, deps.window.device(), deps.shaders)? .build_unindexed()?; let global_sky_mesh = deps .meshes .add(deps.entities, root, "global_world_sky_mesh") - .immutable(&builder.sky_vertices, deps.window.device())? + .immutable(&builder.sky_vertices, deps.window.device(), deps.shaders)? .build_unindexed()?; let global_decor_mesh = deps .meshes .add(deps.entities, root, "global_world_decor_mesh") - .immutable(&builder.decor_vertices, deps.window.device())? + .immutable(&builder.decor_vertices, deps.window.device(), deps.shaders)? .build_unindexed()?; for (id, indices) in &builder.object_indices { @@ -448,8 +449,8 @@ impl<'a> Builder<'a> { let mesh = deps .meshes .add(deps.entities, entity, "object_flats_mesh") - .shared(global_static_mesh) - .immutable_indices(&indices.flat, deps.window.device())? + .shared(global_static_mesh, deps.window.device(), deps.shaders) + .immutable_indices(&indices.flat, deps.window.device(), deps.shaders)? .build()?; deps.transforms.attach_identity(entity); deps.render @@ -461,8 +462,8 @@ impl<'a> Builder<'a> { let mesh = deps .meshes .add(deps.entities, entity, "object_walls_mesh") - .shared(global_static_mesh) - .immutable_indices(&indices.wall, deps.window.device())? + .shared(global_static_mesh, deps.window.device(), deps.shaders) + .immutable_indices(&indices.wall, deps.window.device(), deps.shaders)? .build()?; deps.transforms.attach_identity(entity); deps.render @@ -474,8 +475,8 @@ impl<'a> Builder<'a> { let mesh = deps .meshes .add(deps.entities, entity, "object_decor_mesh") - .shared(global_decor_mesh) - .immutable_indices(&indices.decor, deps.window.device())? + .shared(global_decor_mesh, deps.window.device(), deps.shaders) + .immutable_indices(&indices.decor, deps.window.device(), deps.shaders)? .build()?; deps.transforms.attach_identity(entity); deps.render @@ -487,8 +488,8 @@ impl<'a> Builder<'a> { let mesh = deps .meshes .add(deps.entities, entity, "object_sky_mesh") - .shared(global_sky_mesh) - .immutable_indices(&indices.sky, deps.window.device())? + .shared(global_sky_mesh, deps.window.device(), deps.shaders) + .immutable_indices(&indices.sky, deps.window.device(), deps.shaders)? .build()?; deps.transforms.attach_identity(entity); deps.render From 313efd1d390a547ed47c4b4a35325be169971aea Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Fri, 26 Jan 2024 21:09:55 +0100 Subject: [PATCH 19/58] Use WGPU textures in texture object --- engine/src/uniforms.rs | 75 +++++++++++++----------------------------- 1 file changed, 22 insertions(+), 53 deletions(-) diff --git a/engine/src/uniforms.rs b/engine/src/uniforms.rs index 5a9e97c..b94eb72 100644 --- a/engine/src/uniforms.rs +++ b/engine/src/uniforms.rs @@ -1,21 +1,18 @@ use crate::Shaders; use super::entities::{Entities, Entity, EntityId}; -use super::errors::{ErrorKind, Result}; +use super::errors::Result; use super::system::InfallibleSystem; use super::window::Window; use crate::internal_derive::DependenciesFrom; use bytemuck::Pod; use cgmath::SquareMatrix; -use failchain::bail; use glium::buffer::Content as BufferContent; use glium::texture::buffer_texture::{BufferTexture, BufferTextureType}; -use glium::texture::{ClientFormat, PixelValue, RawImage2d, Texture2d as GliumTexture2d}; -use glium::uniforms::{AsUniformValue, SamplerBehavior, UniformValue}; +use glium::uniforms::{AsUniformValue, UniformValue}; use idcontain::IdMapVec; use log::{debug, error}; use math::{Mat4, Vec2, Vec2f}; -use std::borrow::Cow; use std::marker::PhantomData; use wgpu::util::DeviceExt; @@ -247,38 +244,10 @@ impl Uniforms { queue.write_buffer(buffer, 0, &data); } - pub fn add_texture2d_size( - &mut self, - entities: &mut Entities, - name: &'static str, - texture: Texture2dId, - ) -> Result { - let size = self.texture2ds.get(texture.0).map(|texture| { - let texture = &texture.gl; - Vec2::new( - texture.get_width() as f32, - texture.get_height().unwrap_or(1) as f32, - ) - }); - let size = if let Some(size) = size { - size - } else { - bail!(ErrorKind::NoSuchComponent { - context: "adding size uniform for texture", - needed_by: Some(name), - id: texture.0.cast(), - }); - }; - self.add_vec2f(entities, texture.0, name, size) - } - #[inline] pub fn get_value(&self, id: UniformId) -> Option { match id { - UniformId::Texture2d(id) => self - .texture2ds - .get(id.0) - .map(|texture| UniformValue::Texture2d(&texture.gl, texture.sampler)), + UniformId::Texture2d(_) => unimplemented!(), UniformId::Float(id) => self .floats .get(id.0) @@ -371,36 +340,37 @@ pub struct Texture2dRefMut<'uniforms> { } impl<'uniforms> Texture2dRefMut<'uniforms> { - pub fn get_sampler_mut(&mut self) -> &mut Option { - &mut self.texture.sampler - } - - pub fn replace_pixels<'pixels, PixelT: PixelValue>( + pub fn replace_pixels<'pixels, PixelT: Pod>( &mut self, window: &Window, pixels: &'pixels [PixelT], size: Vec2, - format: ClientFormat, - sampler: Option, ) -> Result<()> { debug!( - "Replacing texture {:?}: pixels={}, size={:?}, format={:?}, sampler={:?}", + "Replacing texture {:?}: pixels={}, size={:?}", self.texture_id, pixels.len(), size, - format, - sampler, ); - self.texture.gl = GliumTexture2d::new( - window.facade(), - RawImage2d { - data: Cow::Borrowed(pixels), + window.queue().write_texture( + wgpu::ImageCopyTexture { + texture: &self.texture.texture, + mip_level: 1, + origin: wgpu::Origin3d::ZERO, + aspect: wgpu::TextureAspect::All, + }, + bytemuck::cast_slice(pixels), + wgpu::ImageDataLayout { + offset: 0, + bytes_per_row: Some((size[0] * std::mem::size_of::()) as u32), + rows_per_image: Some(size[1] as u32), + }, + wgpu::Extent3d { width: size[0] as u32, height: size[1] as u32, - format, + depth_or_array_layers: 1, }, - ) - .map_err(ErrorKind::glium("texture2d.replace_pixels"))?; + ); debug!("Replaced texture {:?} successfully.", self.texture_id,); Ok(()) @@ -517,8 +487,7 @@ impl<'context> InfallibleSystem<'context> for Uniforms { } struct Texture2d { - gl: GliumTexture2d, - sampler: Option, + texture: wgpu::Texture, } impl From for UniformId { From 9247631d1ab64460a39fba966a7f086f3577875b Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Fri, 26 Jan 2024 21:11:53 +0100 Subject: [PATCH 20/58] Eliminate Glium-based rendering --- engine/src/errors.rs | 8 -------- engine/src/materials.rs | 16 ---------------- engine/src/renderer.rs | 18 ++++++------------ engine/src/shaders.rs | 24 +----------------------- engine/src/text.rs | 27 ++++----------------------- engine/src/window.rs | 28 ++++++++-------------------- 6 files changed, 19 insertions(+), 102 deletions(-) diff --git a/engine/src/errors.rs b/engine/src/errors.rs index 53f944f..61c1356 100644 --- a/engine/src/errors.rs +++ b/engine/src/errors.rs @@ -63,14 +63,6 @@ impl ChainErrorKind for ErrorKind { type Error = Error; } -impl ErrorKind { - pub(crate) fn glium, ErrorT: ConvertGlium>( - needed_by: NeededByT, - ) -> impl FnOnce(ErrorT) -> Error { - move |error| error.convert_glium(needed_by.into()).into() - } -} - pub(crate) trait ConvertGlium: Fail + Sized { fn convert_glium(self, needed_by: String) -> ErrorKind; } diff --git a/engine/src/materials.rs b/engine/src/materials.rs index 97a4647..6411c95 100644 --- a/engine/src/materials.rs +++ b/engine/src/materials.rs @@ -3,7 +3,6 @@ use super::errors::Result; use super::shaders::{ShaderId, Shaders}; use super::system::InfallibleSystem; use super::uniforms::{UniformId, Uniforms}; -use glium::Program; use idcontain::IdMapVec; use log::{debug, error}; use wgpu::util::DeviceExt; @@ -64,15 +63,6 @@ impl Materials { material_id: MaterialId, ) -> Option> { let material = self.map.get(material_id.0)?; - let shader = if let Some(shader) = shaders.get(material.shader) { - shader - } else { - error!( - "Missing shader {:?} for material {:?}", - material.shader, material_id - ); - return None; - }; let Some(pipeline) = shaders.get_pipeline(material.shader) else { error!( @@ -103,7 +93,6 @@ impl Materials { } Some(MaterialRef { - shader, pipeline, bind_group: material .bind_group @@ -204,7 +193,6 @@ impl<'a> MaterialRefMut<'a> { } pub struct MaterialRef<'a> { - shader: &'a Program, pipeline: &'a wgpu::RenderPipeline, bind_group: &'a wgpu::BindGroup, } @@ -243,10 +231,6 @@ impl<'context> InfallibleSystem<'context> for Materials { } impl<'a> MaterialRef<'a> { - pub fn shader(&self) -> &Program { - self.shader - } - pub(crate) fn pipeline(&self) -> &'a wgpu::RenderPipeline { &self.pipeline } diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 79e6a1a..be7a0de 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -1,4 +1,4 @@ -use super::errors::{Error, ErrorKind, Result}; +use super::errors::{Error, Result}; use super::materials::Materials; use super::meshes::Meshes; use super::pipeline::{Model, RenderPipeline}; @@ -11,7 +11,6 @@ use super::transforms::Transforms; use super::uniforms::Uniforms; use super::window::Window; use crate::internal_derive::DependenciesFrom; -use failchain::ResultExt; use log::{error, info}; use math::{prelude::*, Mat4}; @@ -21,7 +20,7 @@ pub struct Dependencies<'context> { meshes: &'context Meshes, materials: &'context Materials, shaders: &'context Shaders, - text: &'context TextRenderer, + _text: &'context TextRenderer, window: &'context Window, transforms: &'context Transforms, projections: &'context Projections, @@ -121,7 +120,6 @@ impl<'context> System<'context> for Renderer { ); // Render all the models in turn. - let mut frame = deps.window.draw(); let surface_texture = deps.window.surface_texture()?; let view = surface_texture.texture.create_view(&Default::default()); let mut encoder = deps @@ -198,14 +196,10 @@ impl<'context> System<'context> for Renderer { } // Render text. TODO(cristicbz): text should render itself :( - deps.text - .render(&mut frame) - .chain_err(|| ErrorKind::System("render bypass", TextRenderer::debug_name()))?; - - // TODO(cristicbz): Re-architect a little bit to support rebuilding the context. - frame - .finish() - .expect("Cannot handle context loss currently :("); + // TODO + // deps.text + // .render(&mut frame) + // .chain_err(|| ErrorKind::System("render bypass", TextRenderer::debug_name()))?; // Remove any missing models. for &index in self.removed.iter().rev() { diff --git a/engine/src/shaders.rs b/engine/src/shaders.rs index eeffb3a..66a742b 100644 --- a/engine/src/shaders.rs +++ b/engine/src/shaders.rs @@ -6,7 +6,6 @@ use super::window::Window; use crate::internal_derive::DependenciesFrom; use failchain::ResultExt; -use glium::program::{Program, ProgramCreationInput}; use idcontain::IdMapVec; use log::{debug, error}; use math::{Mat4, Vec2, Vec3}; @@ -62,22 +61,6 @@ impl Shaders { read_utf8_file(&vertex_path, &mut vertex_source) .chain_err(|| ErrorKind::ResourceIo("vertex shader", name))?; - let program = Program::new( - window.facade(), - ProgramCreationInput::SourceCode { - vertex_shader: &vertex_source, - tessellation_control_shader: None, - tessellation_evaluation_shader: None, - geometry_shader: None, - fragment_shader: &fragment_source, - transform_feedback_varyings: None, - // TODO(cristicbz): More configurable things! SRGB should not be hard coded. - outputs_srgb: true, - uses_point_size: false, - }, - ) - .map_err(ErrorKind::glium(name))?; - let shader_module = window .device() .create_shader_module(wgpu::ShaderModuleDescriptor { @@ -143,15 +126,11 @@ impl Shaders { debug!("Shader {:?} loaded successfully", name); let id = entities.add(parent, name)?; - self.map.insert(id, Shader { program, pipeline }); + self.map.insert(id, Shader { pipeline }); debug!("Added shader {:?} {:?} as child of {:?}.", name, id, parent); Ok(ShaderId(id)) } - pub fn get(&self, shader_id: ShaderId) -> Option<&Program> { - self.map.get(shader_id.0).map(|shader| &shader.program) - } - pub(crate) fn get_pipeline(&self, shader_id: ShaderId) -> Option<&wgpu::RenderPipeline> { self.map .get(shader_id.0) @@ -172,7 +151,6 @@ impl Shaders { } pub struct Shader { - program: Program, pipeline: wgpu::RenderPipeline, } diff --git a/engine/src/text.rs b/engine/src/text.rs index 3d94386..76b995d 100644 --- a/engine/src/text.rs +++ b/engine/src/text.rs @@ -5,7 +5,7 @@ use super::window::Window; use failchain::{ChainErrorKind, ResultExt, UnboxedError}; use failure::Fail; use glium::index::{NoIndices, PrimitiveType}; -use glium::texture::{ClientFormat, RawImage2d, Texture2d}; +use glium::texture::Texture2d; use glium::{ implement_vertex, uniform, Blend, DrawParameters, Frame, Program, Surface, VertexBuffer, }; @@ -13,7 +13,6 @@ use idcontain::{Id, IdSlab}; use log::{debug, error}; use math::Pnt2f; use rusttype::{self, Font, GlyphId, Point as FontPoint, PositionedGlyph, Scale}; -use std::borrow::Cow; use std::fs::File; use std::io::Read; use std::ops::{Index, IndexMut}; @@ -49,32 +48,14 @@ impl TextRenderer { pub fn insert(&mut self, win: &Window, text: &str, pos: Pnt2f, padding: u32) -> TextId { debug!("Creating text..."); let (width, height) = self.rasterise(text, padding); - let texture = Texture2d::new( - win.facade(), - RawImage2d { - data: Cow::Borrowed(&self.pixel_buffer), - width, - height, - format: ClientFormat::U8U8, - }, - ) - .unwrap(); + let texture = todo!(); let (w, h) = ( width as f32 / win.width() as f32 * 2.0, height as f32 / win.height() as f32 * 2.0, ); let (x, y) = (pos.x * 2.0 - 1.0, 1.0 - pos.y * 2.0 - h); let text = Text { - buffer: VertexBuffer::immutable( - win.facade(), - &[ - vertex(x, y, 0.0, 1.0), - vertex(x, y + h, 0.0, 0.0), - vertex(x + w, y, 1.0, 1.0), - vertex(x + w, y + h, 1.0, 0.0), - ], - ) - .unwrap(), + buffer: todo!(), texture, visible: true, }; @@ -218,7 +199,7 @@ impl<'context> System<'context> for TextRenderer { font: Font::try_from_vec_and_index(font_bytes, 0) .ok_or_else(|| ErrorKind(format!("Failed to parse font at {:?}.", FONT_PATH)))?, slab: IdSlab::with_capacity(16), - program: Program::from_source(window.facade(), VERTEX_SRC, FRAGMENT_SRC, None).unwrap(), + program: todo!(), draw_params: DrawParameters { blend: Blend::alpha_blending(), ..DrawParameters::default() diff --git a/engine/src/window.rs b/engine/src/window.rs index 013f50b..0e35f54 100644 --- a/engine/src/window.rs +++ b/engine/src/window.rs @@ -5,10 +5,8 @@ use crate::ErrorKind; use super::errors::{Error, Result}; use super::system::System; use failchain::BoxedError; -use glium::backend::glutin::SimpleWindowBuilder; -use glium::glutin::surface::WindowSurface; -use glium::{Display, Frame, Surface}; use winit::event_loop::EventLoop; +use winit::window::WindowBuilder; pub struct WindowConfig { pub width: u32, @@ -21,7 +19,6 @@ pub struct Window { queue: wgpu::Queue, surface: wgpu::Surface<'static>, texture_format: wgpu::TextureFormat, - display: Display, window: Arc, event_loop: Option>, width: u32, @@ -41,12 +38,6 @@ impl Window { self.width as f32 / self.height as f32 } - pub fn draw(&self) -> Frame { - let mut frame = self.display.draw(); - frame.clear_all_srgb((0.06, 0.07, 0.09, 0.0), 1.0, 0); - frame - } - pub fn device(&self) -> &wgpu::Device { &self.device } @@ -73,10 +64,6 @@ impl Window { .map_err(|_| BoxedError::from(ErrorKind::Context("Could not get current texture"))) } - pub fn facade(&self) -> &Display { - &self.display - } - pub fn window(&self) -> &winit::window::Window { &self.window } @@ -93,12 +80,14 @@ impl<'context> System<'context> for Window { fn create(config: &'context WindowConfig) -> Result { let events = EventLoop::new().map_err(|e| ErrorKind::CreateWindow(e.to_string()))?; - let (window, display) = SimpleWindowBuilder::new() - .with_inner_size(config.width, config.height) - .with_title(&config.title) - .build(&events); + let window = Arc::new( + WindowBuilder::new() + .with_inner_size(winit::dpi::LogicalSize::new(config.width, config.height)) + .with_title(&config.title) + .build(&events) + .map_err(|e| ErrorKind::CreateWindow(e.to_string()))?, + ); - let window = Arc::new(window); let instance = create_instance(); let surface = instance .create_surface(window.clone()) @@ -120,7 +109,6 @@ impl<'context> System<'context> for Window { device, queue, surface, - display, texture_format: configuration.format, window, event_loop: Some(events), From f81ef91a3e9f31a40ed13f2f3af4879b28e2dfb4 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sat, 27 Jan 2024 17:07:54 +0100 Subject: [PATCH 21/58] Fixes to bind group layout --- assets/shaders/sprite.wgsl | 2 +- assets/shaders/static.wgsl | 2 +- engine/src/lib.rs | 2 +- engine/src/shaders.rs | 17 +++++++++++------ game/src/lights.rs | 3 ++- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/assets/shaders/sprite.wgsl b/assets/shaders/sprite.wgsl index 032d9ff..cd6b203 100644 --- a/assets/shaders/sprite.wgsl +++ b/assets/shaders/sprite.wgsl @@ -1,7 +1,7 @@ @group(0) @binding(0) var u_viewproj: mat4x4; // TODO: There should be a separate sampler for the palette, using clamp semantics rather than repeat @group(0) @binding(1) var u_sampler: sampler; -@group(0) @binding(2) var u_lights: array; +@group(0) @binding(2) var u_lights: array; @group(0) @binding(3) var u_time: f32; @group(0) @binding(4) var u_palette: texture_2d; diff --git a/assets/shaders/static.wgsl b/assets/shaders/static.wgsl index fd429d6..d7ed9b5 100644 --- a/assets/shaders/static.wgsl +++ b/assets/shaders/static.wgsl @@ -1,7 +1,7 @@ @group(0) @binding(0) var u_viewproj: mat4x4; // TODO: There should be a separate sampler for the palette, using clamp semantics rather than repeat @group(0) @binding(1) var u_sampler: sampler; -@group(0) @binding(2) var u_lights: array; +@group(0) @binding(2) var u_lights: array; @group(0) @binding(3) var u_time: f32; @group(0) @binding(4) var u_palette: texture_2d; diff --git a/engine/src/lib.rs b/engine/src/lib.rs index 7c54c28..b767910 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -31,7 +31,7 @@ pub use self::meshes::{Mesh, MeshId, Meshes}; pub use self::pipeline::RenderPipeline; pub use self::projections::{Projection, Projections}; pub use self::renderer::Renderer; -pub use self::shaders::{ShaderConfig, ShaderId, ShaderVertex, Shaders}; +pub use self::shaders::{ShaderConfig, ShaderId, ShaderVertex, Shaders, LIGHTS_COUNT}; pub use self::system::{InfallibleSystem, System}; pub use self::text::{Text, TextId, TextRenderer}; pub use self::tick::{Config as TickConfig, Tick, TickIndex}; diff --git a/engine/src/shaders.rs b/engine/src/shaders.rs index 66a742b..9fdbcaf 100644 --- a/engine/src/shaders.rs +++ b/engine/src/shaders.rs @@ -7,14 +7,16 @@ use crate::internal_derive::DependenciesFrom; use failchain::ResultExt; use idcontain::IdMapVec; -use log::{debug, error}; +use log::{debug, error, info}; use math::{Mat4, Vec2, Vec3}; use std::fs::File; use std::io::Read; use std::io::Result as IoResult; -use std::num::{NonZeroU32, NonZeroU64}; +use std::num::NonZeroU64; use std::path::{Path, PathBuf}; +pub const LIGHTS_COUNT: usize = 256; + #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Copy, Clone)] pub struct ShaderId(pub EntityId); @@ -169,6 +171,7 @@ impl<'context> InfallibleSystem<'context> for Shaders { } fn create(deps: Dependencies) -> Self { + info!("Shaders::create: Enter"); let global_bind_group_layout = deps.window.device().create_bind_group_layout( &wgpu::BindGroupLayoutDescriptor { label: Some("global_bind_group_layout"), @@ -193,11 +196,13 @@ impl<'context> InfallibleSystem<'context> for Shaders { binding: 2, visibility: wgpu::ShaderStages::VERTEX, ty: wgpu::BindingType::Buffer { - ty: wgpu::BufferBindingType::Uniform, + ty: wgpu::BufferBindingType::Storage { read_only: true }, has_dynamic_offset: false, - min_binding_size: NonZeroU64::new(std::mem::size_of::() as u64), + min_binding_size: NonZeroU64::new( + (LIGHTS_COUNT * std::mem::size_of::()) as u64, + ), }, - count: NonZeroU32::new(256), + count: None, }, wgpu::BindGroupLayoutEntry { binding: 3, @@ -280,7 +285,7 @@ impl<'context> InfallibleSystem<'context> for Shaders { count: None, }, wgpu::BindGroupLayoutEntry { - binding: 0, + binding: 1, visibility: wgpu::ShaderStages::VERTEX, ty: wgpu::BindingType::Buffer { ty: wgpu::BufferBindingType::Uniform, diff --git a/game/src/lights.rs b/game/src/lights.rs index 667d632..ac3e7eb 100644 --- a/game/src/lights.rs +++ b/game/src/lights.rs @@ -1,3 +1,4 @@ +use engine::LIGHTS_COUNT; use wad::{LightEffectKind, LightInfo}; pub struct Lights { @@ -7,7 +8,7 @@ pub struct Lights { impl Lights { pub fn new() -> Self { Self { - lights: Vec::with_capacity(256), + lights: Vec::with_capacity(LIGHTS_COUNT), } } From 5b7a7692517cc3210bc8defd70eb408068fee0c6 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sat, 27 Jan 2024 17:43:26 +0100 Subject: [PATCH 22/58] Port text rendering to WGPU --- engine/src/renderer.rs | 16 +-- engine/src/text.rs | 234 +++++++++++++++++++++++++++++++---------- 2 files changed, 189 insertions(+), 61 deletions(-) diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index be7a0de..0415836 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -11,6 +11,8 @@ use super::transforms::Transforms; use super::uniforms::Uniforms; use super::window::Window; use crate::internal_derive::DependenciesFrom; +use crate::ErrorKind; +use failchain::ResultExt; use log::{error, info}; use math::{prelude::*, Mat4}; @@ -20,7 +22,7 @@ pub struct Dependencies<'context> { meshes: &'context Meshes, materials: &'context Materials, shaders: &'context Shaders, - _text: &'context TextRenderer, + text: &'context TextRenderer, window: &'context Window, transforms: &'context Transforms, projections: &'context Projections, @@ -195,18 +197,18 @@ impl<'context> System<'context> for Renderer { render_pass.draw_indexed(0..mesh.index_count(), 0, 0..1); } - // Render text. TODO(cristicbz): text should render itself :( - // TODO - // deps.text - // .render(&mut frame) - // .chain_err(|| ErrorKind::System("render bypass", TextRenderer::debug_name()))?; - // Remove any missing models. for &index in self.removed.iter().rev() { pipe.models.remove_by_index(index); } self.removed.clear(); } + + // Render text. TODO(cristicbz): text should render itself :( + deps.text + .render(&mut encoder, &self.view) + .chain_err(|| ErrorKind::System("render bypass", TextRenderer::debug_name()))?; + deps.window.queue().submit([encoder.finish()]); surface_texture.present(); Ok(()) diff --git a/engine/src/text.rs b/engine/src/text.rs index 76b995d..116acaa 100644 --- a/engine/src/text.rs +++ b/engine/src/text.rs @@ -1,14 +1,12 @@ #![cfg_attr(feature = "cargo-clippy", allow(clippy::forget_copy))] +use crate::ShaderVertex; + use super::system::System; use super::window::Window; +use bytemuck::{offset_of, Pod, Zeroable}; use failchain::{ChainErrorKind, ResultExt, UnboxedError}; use failure::Fail; -use glium::index::{NoIndices, PrimitiveType}; -use glium::texture::Texture2d; -use glium::{ - implement_vertex, uniform, Blend, DrawParameters, Frame, Program, Surface, VertexBuffer, -}; use idcontain::{Id, IdSlab}; use log::{debug, error}; use math::Pnt2f; @@ -18,7 +16,10 @@ use std::io::Read; use std::ops::{Index, IndexMut}; use std::result::Result as StdResult; use std::str::Chars as StrChars; +use std::sync::OnceLock; use unicode_normalization::{Recompositions, UnicodeNormalization}; +use wgpu::include_wgsl; +use wgpu::util::DeviceExt; /// A handle to a piece of text created with a `TextRenderer`. #[derive(Copy, Clone, Eq, PartialEq)] @@ -28,9 +29,9 @@ pub struct TextId(Id); pub struct TextRenderer { font: Font<'static>, slab: IdSlab, - program: Program, - draw_params: DrawParameters<'static>, pixel_buffer: Vec, + pipeline: wgpu::RenderPipeline, + bind_group_layout: wgpu::BindGroupLayout, } #[derive(Clone, Eq, PartialEq, Debug, Fail)] @@ -48,15 +49,66 @@ impl TextRenderer { pub fn insert(&mut self, win: &Window, text: &str, pos: Pnt2f, padding: u32) -> TextId { debug!("Creating text..."); let (width, height) = self.rasterise(text, padding); - let texture = todo!(); + let texture = win.device().create_texture(&wgpu::TextureDescriptor { + label: Some("Text texture"), + size: wgpu::Extent3d { + width, + height, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rg8Unorm, + usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, + view_formats: &[], + }); + let sampler = win.device().create_sampler(&wgpu::SamplerDescriptor { + label: Some("Text sampler"), + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + mag_filter: wgpu::FilterMode::Nearest, + min_filter: wgpu::FilterMode::Nearest, + mipmap_filter: wgpu::FilterMode::Nearest, + ..Default::default() + }); + let bind_group = win.device().create_bind_group(&wgpu::BindGroupDescriptor { + label: Some("Text bind group"), + layout: &self.bind_group_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView( + &texture.create_view(&Default::default()), + ), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::Sampler(&sampler), + }, + ], + }); let (w, h) = ( width as f32 / win.width() as f32 * 2.0, height as f32 / win.height() as f32 * 2.0, ); let (x, y) = (pos.x * 2.0 - 1.0, 1.0 - pos.y * 2.0 - h); + let buffer = win + .device() + .create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("Text vertex buffer"), + contents: bytemuck::cast_slice(&[ + vertex(x, y, 0.0, 1.0), + vertex(x, y + h, 0.0, 0.0), + vertex(x + w, y, 1.0, 1.0), + vertex(x + w, y + h, 1.0, 0.0), + ]), + usage: wgpu::BufferUsages::VERTEX, + }); let text = Text { - buffer: todo!(), - texture, + buffer, + bind_group, visible: true, }; let id = self.slab.insert(text); @@ -77,23 +129,31 @@ impl TextRenderer { self.slab.get_mut(id.0) } - pub fn render(&self, frame: &mut Frame) -> Result<()> { + pub fn render( + &self, + encoder: &mut wgpu::CommandEncoder, + view: &wgpu::TextureView, + ) -> Result<()> { + let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: Some("Text render pass"), + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Load, + store: wgpu::StoreOp::Store, + }, + view, + })], + ..Default::default() + }); + render_pass.set_pipeline(&self.pipeline); for text in &self.slab { if !text.visible { continue; } - let uniforms = uniform! { - u_tex: &text.texture, - }; - frame - .draw( - &text.buffer, - NoIndices(PrimitiveType::TriangleStrip), - &self.program, - &uniforms, - &self.draw_params, - ) - .unwrap(); + render_pass.set_vertex_buffer(0, text.buffer.slice(..)); + render_pass.set_bind_group(0, &text.bind_group, &[]); + render_pass.draw(0..4, 0..1); } Ok(()) } @@ -195,16 +255,82 @@ impl<'context> System<'context> for TextRenderer { File::open(FONT_PATH) .and_then(|mut file| file.read_to_end(&mut font_bytes)) .chain_err(|| ErrorKind(format!("Cannot read font at {}", FONT_PATH)))?; + let bind_group_layout = + window + .device() + .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("Text bind group layout"), + entries: &[ + 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: false }, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), + count: None, + }, + ], + }); + let pipeline_layout = + window + .device() + .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("Text pipeline layout"), + bind_group_layouts: &[&bind_group_layout], + push_constant_ranges: &[], + }); + let shader_module = window + .device() + .create_shader_module(include_wgsl!("../../assets/shaders/text.wgsl")); + let pipeline = window + .device() + .create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Text pipeline"), + layout: Some(&pipeline_layout), + vertex: wgpu::VertexState { + module: &shader_module, + entry_point: "main", + buffers: &[TextVertex::desc()], + }, + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleList, + strip_index_format: None, + front_face: wgpu::FrontFace::Ccw, + cull_mode: Some(wgpu::Face::Back), + unclipped_depth: false, + polygon_mode: wgpu::PolygonMode::Fill, + conservative: false, + }, + depth_stencil: Some(wgpu::DepthStencilState { + format: wgpu::TextureFormat::Depth32Float, + depth_write_enabled: true, + depth_compare: wgpu::CompareFunction::Less, + stencil: wgpu::StencilState::default(), + bias: wgpu::DepthBiasState::default(), + }), + multisample: wgpu::MultisampleState { + count: 1, + mask: !0, + alpha_to_coverage_enabled: false, + }, + fragment: None, + multiview: None, + }); Ok(Self { font: Font::try_from_vec_and_index(font_bytes, 0) .ok_or_else(|| ErrorKind(format!("Failed to parse font at {:?}.", FONT_PATH)))?, slab: IdSlab::with_capacity(16), - program: todo!(), - draw_params: DrawParameters { - blend: Blend::alpha_blending(), - ..DrawParameters::default() - }, pixel_buffer: Vec::new(), + bind_group_layout, + pipeline, }) } @@ -221,8 +347,8 @@ impl<'context> System<'context> for TextRenderer { } pub struct Text { - texture: Texture2d, - buffer: VertexBuffer, + buffer: wgpu::Buffer, + bind_group: wgpu::BindGroup, visible: bool, } @@ -264,36 +390,36 @@ const FONT_PATH: &str = "assets/ttf/OpenSans-Regular.ttf"; /// Hard-coded font size. const POINT_SIZE: f32 = 24.0; -const VERTEX_SRC: &str = r#" - #version 140 - in vec2 a_pos; - in vec2 a_uv; - out vec2 v_uv; - void main() { - v_uv = a_uv; - gl_Position = vec4(a_pos, 0.0, 1.0); - } -"#; - -const FRAGMENT_SRC: &str = r#" - #version 140 - uniform sampler2D u_tex; - in vec2 v_uv; - out vec4 color; - void main() { - vec4 tex_color = texture(u_tex, v_uv); - color = vec4(tex_color.g, tex_color.g, tex_color.g, tex_color.r); - } -"#; - #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Pod, Zeroable, Default)] struct TextVertex { a_pos: [f32; 2], a_uv: [f32; 2], } -implement_vertex!(TextVertex, a_pos, a_uv); +impl ShaderVertex for TextVertex { + fn desc<'a>() -> wgpu::VertexBufferLayout<'a> { + static ATTRIBUTES: OnceLock> = OnceLock::new(); + wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &ATTRIBUTES.get_or_init(|| { + vec![ + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x2, + offset: offset_of!(TextVertex, a_pos) as u64, + shader_location: 0, + }, + wgpu::VertexAttribute { + format: wgpu::VertexFormat::Float32x2, + offset: offset_of!(TextVertex, a_uv) as u64, + shader_location: 1, + }, + ] + }), + } + } +} fn vertex(x: f32, y: f32, u: f32, v: f32) -> TextVertex { TextVertex { From 0477165fa3222fd8b8215c6c420bbecd5d2bec1d Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sat, 27 Jan 2024 17:46:36 +0100 Subject: [PATCH 23/58] Remove implement_vertex calls --- game/src/vertex.rs | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/game/src/vertex.rs b/game/src/vertex.rs index accc427..89fe6b0 100644 --- a/game/src/vertex.rs +++ b/game/src/vertex.rs @@ -2,7 +2,6 @@ use bytemuck::{offset_of, Pod, Zeroable}; use engine::ShaderVertex; -use glium::implement_vertex; use std::sync::OnceLock; use wgpu::VertexAttribute; @@ -74,18 +73,6 @@ impl ShaderVertex for StaticVertex { } } -implement_vertex! { - StaticVertex, - a_pos, - a_atlas_uv, - a_tile_uv, - a_tile_size, - a_scroll_rate, - a_row_height, - a_num_frames, - a_light, -} - #[repr(C)] #[derive(Copy, Clone, Pod, Zeroable, Default)] pub struct SpriteVertex { @@ -148,17 +135,6 @@ impl ShaderVertex for SpriteVertex { } } -implement_vertex! { - SpriteVertex, - a_pos, - a_atlas_uv, - a_tile_uv, - a_tile_size, - a_local_x, - a_num_frames, - a_light, -} - #[repr(C)] #[derive(Copy, Clone, Pod, Zeroable, Default)] pub struct SkyVertex { @@ -182,8 +158,3 @@ impl ShaderVertex for SkyVertex { } } } - -implement_vertex! { - SkyVertex, - a_pos, -} From 0d7db17ca6e56431bed4bdd9dd6238087212302a Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sat, 27 Jan 2024 17:49:39 +0100 Subject: [PATCH 24/58] Fixes to text pipeline --- assets/shaders/static.wgsl | 28 ++++++++++++++-------------- assets/shaders/text.wgsl | 14 +++++++------- engine/src/text.rs | 12 ++++++++++-- 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/assets/shaders/static.wgsl b/assets/shaders/static.wgsl index d7ed9b5..f3aa9d8 100644 --- a/assets/shaders/static.wgsl +++ b/assets/shaders/static.wgsl @@ -11,23 +11,23 @@ @group(2) @binding(0) var u_model: mat4x4; struct VertexInput { - @location(0) a_pos: vec3; - @location(1) a_atlas_uv: vec2; - @location(2) a_tile_uv: vec2; - @location(3) a_tile_size: vec2; - @location(4) a_scroll_rate: f32; - @location(5) a_row_height: f32; - @location(6) a_num_frames: i32; - @location(7) a_light: i32; + @location(0) a_pos: vec3, + @location(1) a_atlas_uv: vec2, + @location(2) a_tile_uv: vec2, + @location(3) a_tile_size: vec2, + @location(4) a_scroll_rate: f32, + @location(5) a_row_height: f32, + @location(6) a_num_frames: i32, + @location(7) a_light: i32, } struct VertexOutput { - @builtin(position) clip_position: vec3; - @location(0) v_dist: f32; - @location(1) v_tile_uv: vec2; - @location(2) v_atlas_uv: vec2; - @location(3) v_tile_size: vec2; - @location(4) v_light: f32; + @builtin(position) clip_position: vec3, + @location(0) v_dist: f32, + @location(1) v_tile_uv: vec2, + @location(2) v_atlas_uv: vec2, + @location(3) v_tile_size: vec2, + @location(4) v_light: f32, } const ANIM_FPS: f32 = 8.0 / 35.0; diff --git a/assets/shaders/text.wgsl b/assets/shaders/text.wgsl index 431fb2e..20c6ba2 100644 --- a/assets/shaders/text.wgsl +++ b/assets/shaders/text.wgsl @@ -2,20 +2,20 @@ @group(0) @binding(1) var u_sampler: sampler; struct VertexInput { - @location(0) a_pos: vec2; - @location(1) a_uv: vec2; + @location(0) a_pos: vec2, + @location(1) a_uv: vec2, } struct VertexOutput { - @location(0) v_uv: vec2; - @builtin(position) clip_position: vec4; + @location(0) v_uv: vec2, + @builtin(position) clip_position: vec4, } @vertex -fn main_vs() -> VertexOutput { +fn main_vs(in: VertexInput) -> VertexOutput { var out: VertexOutput; - out.v_uv = a_uv; - out.clip_position = vec4(a_pos, 0.0, 1.0); + out.v_uv = in.a_uv; + out.clip_position = vec4(in.a_pos, 0.0, 1.0); return out; } diff --git a/engine/src/text.rs b/engine/src/text.rs index 116acaa..5d2ea94 100644 --- a/engine/src/text.rs +++ b/engine/src/text.rs @@ -297,7 +297,7 @@ impl<'context> System<'context> for TextRenderer { layout: Some(&pipeline_layout), vertex: wgpu::VertexState { module: &shader_module, - entry_point: "main", + entry_point: "main_vs", buffers: &[TextVertex::desc()], }, primitive: wgpu::PrimitiveState { @@ -321,7 +321,15 @@ impl<'context> System<'context> for TextRenderer { mask: !0, alpha_to_coverage_enabled: false, }, - fragment: None, + fragment: Some(wgpu::FragmentState { + module: &shader_module, + entry_point: "main_fs", + targets: &[Some(wgpu::ColorTargetState { + format: window.texture_format(), + blend: Some(wgpu::BlendState::REPLACE), + write_mask: wgpu::ColorWrites::all(), + })], + }), multiview: None, }); Ok(Self { From c2e4018427c74968f8fd81f1c7e807551d1761e2 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sat, 27 Jan 2024 17:50:10 +0100 Subject: [PATCH 25/58] Fixes to WGSL --- assets/shaders/sky.wgsl | 6 +++--- assets/shaders/sprite.wgsl | 26 +++++++++++++------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/assets/shaders/sky.wgsl b/assets/shaders/sky.wgsl index 37d1f11..370da7f 100644 --- a/assets/shaders/sky.wgsl +++ b/assets/shaders/sky.wgsl @@ -9,9 +9,9 @@ @group(2) @binding(0) var u_model: mat4x4; struct VertexOutput { - @builtin(position) clip_position: vec4; - @location(0) v_r: vec2; - @location(1) v_p: vec4; + @builtin(position) clip_position: vec4, + @location(0) v_r: vec2, + @location(1) v_p: vec4, } @vertex diff --git a/assets/shaders/sprite.wgsl b/assets/shaders/sprite.wgsl index cd6b203..ec441b5 100644 --- a/assets/shaders/sprite.wgsl +++ b/assets/shaders/sprite.wgsl @@ -12,22 +12,22 @@ @group(2) @binding(1) var u_right: vec3; struct VertexInput { - @location(0) a_pos: vec3; - @location(1) a_atlas_uv: vec2; - @location(2) a_tile_uv: vec2; - @location(3) a_tile_size: vec2; - @location(4) a_local_x: f32; - @location(5) a_num_frames: i32; - @location(6) a_light: i32; + @location(0) a_pos: vec3, + @location(1) a_atlas_uv: vec2, + @location(2) a_tile_uv: vec2, + @location(3) a_tile_size: vec2, + @location(4) a_local_x: f32, + @location(5) a_num_frames: i32, + @location(6) a_light: i32, } struct VertexOutput { - @builtin(position) clip_position: vec3; - @location(0) v_dist: f32; - @location(1) v_tile_uv: vec2; - @location(2) v_atlas_uv: vec2; - @location(3) v_tile_size: vec2; - @location(4) v_light: f32; + @builtin(position) clip_position: vec3, + @location(0) v_dist: f32, + @location(1) v_tile_uv: vec2, + @location(2) v_atlas_uv: vec2, + @location(3) v_tile_size: vec2, + @location(4) v_light: f32, } const ANIM_FPS: f32 = 8.0 / 35.0; From a042baa6b566ea855fbc41632dc5947326ccf5b1 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sat, 27 Jan 2024 17:51:47 +0100 Subject: [PATCH 26/58] More fixes --- engine/src/shaders.rs | 3 +-- engine/src/text.rs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/engine/src/shaders.rs b/engine/src/shaders.rs index 9fdbcaf..f987fc3 100644 --- a/engine/src/shaders.rs +++ b/engine/src/shaders.rs @@ -7,7 +7,7 @@ use crate::internal_derive::DependenciesFrom; use failchain::ResultExt; use idcontain::IdMapVec; -use log::{debug, error, info}; +use log::{debug, error}; use math::{Mat4, Vec2, Vec3}; use std::fs::File; use std::io::Read; @@ -171,7 +171,6 @@ impl<'context> InfallibleSystem<'context> for Shaders { } fn create(deps: Dependencies) -> Self { - info!("Shaders::create: Enter"); let global_bind_group_layout = deps.window.device().create_bind_group_layout( &wgpu::BindGroupLayoutDescriptor { label: Some("global_bind_group_layout"), diff --git a/engine/src/text.rs b/engine/src/text.rs index 5d2ea94..7a3a646 100644 --- a/engine/src/text.rs +++ b/engine/src/text.rs @@ -267,7 +267,7 @@ impl<'context> System<'context> for TextRenderer { ty: wgpu::BindingType::Texture { multisampled: false, view_dimension: wgpu::TextureViewDimension::D2, - sample_type: wgpu::TextureSampleType::Float { filterable: false }, + sample_type: wgpu::TextureSampleType::Float { filterable: true }, }, count: None, }, From e348565012e89a3c521d1e9274ae3dff9c199fa5 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sat, 27 Jan 2024 21:22:04 +0100 Subject: [PATCH 27/58] More fixes --- assets/shaders/static.wgsl | 4 ++-- engine/src/shaders.rs | 6 ++---- game/src/game_shaders.rs | 26 +++++++++++++++++++++----- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/assets/shaders/static.wgsl b/assets/shaders/static.wgsl index f3aa9d8..7623d41 100644 --- a/assets/shaders/static.wgsl +++ b/assets/shaders/static.wgsl @@ -67,8 +67,8 @@ fn main_fs(in: VertexOutput) -> @location(0) vec4 { if palette_index.g > .5 { // Transparent pixel. discard; } else { - float dist_term = min(1.0, 1.0 - DIST_SCALE / (v_dist + DIST_SCALE)); - float light = v_light * LIGHT_SCALE - dist_term; + let dist_term = min(1.0, 1.0 - DIST_SCALE / (v_dist + DIST_SCALE)); + let light = v_light * LIGHT_SCALE - dist_term; return vec4(textureSample(u_palette, u_sampler, vec2(palette_index.r, 1.0 - light)).rgb, 1.0); } } diff --git a/engine/src/shaders.rs b/engine/src/shaders.rs index f987fc3..19a483e 100644 --- a/engine/src/shaders.rs +++ b/engine/src/shaders.rs @@ -40,13 +40,11 @@ impl Shaders { parent: EntityId, name: &'static str, asset_path: &'static str, + wgsl_source: &'static str, ) -> Result { let mut fragment_path = self.root.clone(); fragment_path.push(asset_path); - let wgsl_path = fragment_path.clone(); - fragment_path.set_extension("wgsl"); - let mut vertex_path = fragment_path.clone(); fragment_path.set_extension("frag"); vertex_path.set_extension("vert"); @@ -67,7 +65,7 @@ impl Shaders { .device() .create_shader_module(wgpu::ShaderModuleDescriptor { label: Some(name), - source: wgpu::ShaderSource::Wgsl(wgsl_path.to_string_lossy().into()), + source: wgpu::ShaderSource::Wgsl(wgsl_source.into()), }); let pipeline_layout = diff --git a/game/src/game_shaders.rs b/game/src/game_shaders.rs index ac67b8c..83fee70 100644 --- a/game/src/game_shaders.rs +++ b/game/src/game_shaders.rs @@ -129,7 +129,7 @@ impl<'context> Dependencies<'context> { "palette", &palette.pixels, Vec2::new(COLORMAP_SIZE, palette.pixels.len() / PALETTE_SIZE), - wgpu::TextureFormat::Rgba8Unorm, + wgpu::TextureFormat::R8Unorm, ) } @@ -148,9 +148,24 @@ impl<'context> Dependencies<'context> { BufferTextureType::Float, )?; - let static_shader = self.load_shader::(parent, "static_shader", "static")?; - let sky_shader = self.load_shader::(parent, "sky_shader", "sky")?; - let sprite_shader = self.load_shader::(parent, "sprite_shader", "sprite")?; + let static_shader = self.load_shader::( + parent, + "static_shader", + "static", + include_str!("../../assets/shaders/static.wgsl"), + )?; + let sky_shader = self.load_shader::( + parent, + "sky_shader", + "sky", + include_str!("../../assets/shaders/sky.wgsl"), + )?; + let sprite_shader = self.load_shader::( + parent, + "sprite_shader", + "sprite", + include_str!("../../assets/shaders/sprite.wgsl"), + )?; self.uniforms .set_globals(self.window.device(), self.shaders, &lights_buffer, &palette); @@ -405,9 +420,10 @@ impl<'context> Dependencies<'context> { parent: EntityId, name: &'static str, asset: &'static str, + wgsl_source: &'static str, ) -> Result { self.shaders - .add::(self.window, self.entities, parent, name, asset) + .add::(self.window, self.entities, parent, name, asset, wgsl_source) } } From 6b9254bbe6269292b4af756db656727ba9423604 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sat, 27 Jan 2024 21:31:13 +0100 Subject: [PATCH 28/58] Switch type of lights buffer to u32 --- assets/shaders/sprite.wgsl | 2 +- assets/shaders/static.wgsl | 2 +- engine/src/shaders.rs | 2 +- engine/src/uniforms.rs | 16 ++++++++++------ game/src/game_shaders.rs | 6 +++--- game/src/level.rs | 2 +- game/src/lights.rs | 4 ++-- 7 files changed, 19 insertions(+), 15 deletions(-) diff --git a/assets/shaders/sprite.wgsl b/assets/shaders/sprite.wgsl index ec441b5..2d85c52 100644 --- a/assets/shaders/sprite.wgsl +++ b/assets/shaders/sprite.wgsl @@ -1,7 +1,7 @@ @group(0) @binding(0) var u_viewproj: mat4x4; // TODO: There should be a separate sampler for the palette, using clamp semantics rather than repeat @group(0) @binding(1) var u_sampler: sampler; -@group(0) @binding(2) var u_lights: array; +@group(0) @binding(2) var u_lights: array; @group(0) @binding(3) var u_time: f32; @group(0) @binding(4) var u_palette: texture_2d; diff --git a/assets/shaders/static.wgsl b/assets/shaders/static.wgsl index 7623d41..5d3c2b4 100644 --- a/assets/shaders/static.wgsl +++ b/assets/shaders/static.wgsl @@ -1,7 +1,7 @@ @group(0) @binding(0) var u_viewproj: mat4x4; // TODO: There should be a separate sampler for the palette, using clamp semantics rather than repeat @group(0) @binding(1) var u_sampler: sampler; -@group(0) @binding(2) var u_lights: array; +@group(0) @binding(2) var u_lights: array; @group(0) @binding(3) var u_time: f32; @group(0) @binding(4) var u_palette: texture_2d; diff --git a/engine/src/shaders.rs b/engine/src/shaders.rs index 19a483e..5c7d2be 100644 --- a/engine/src/shaders.rs +++ b/engine/src/shaders.rs @@ -196,7 +196,7 @@ impl<'context> InfallibleSystem<'context> for Shaders { ty: wgpu::BufferBindingType::Storage { read_only: true }, has_dynamic_offset: false, min_binding_size: NonZeroU64::new( - (LIGHTS_COUNT * std::mem::size_of::()) as u64, + (LIGHTS_COUNT * std::mem::size_of::()) as u64, ), }, count: None, diff --git a/engine/src/uniforms.rs b/engine/src/uniforms.rs index b94eb72..d3b5081 100644 --- a/engine/src/uniforms.rs +++ b/engine/src/uniforms.rs @@ -207,7 +207,7 @@ impl Uniforms { } // TODO(cristicbz): Make u8 a type param. - pub fn add_persistent_buffer_u8( + pub fn add_persistent_buffer( &mut self, window: &Window, entities: &mut Entities, @@ -235,13 +235,17 @@ impl Uniforms { Ok(buffer) } - pub fn map_buffer_u8(&mut self, buffer: &wgpu::Buffer, writer: F, queue: &wgpu::Queue) - where - F: FnOnce(&mut [u8]), + pub fn map_buffer( + &mut self, + buffer: &wgpu::Buffer, + writer: F, + queue: &wgpu::Queue, + ) where + F: FnOnce(&mut [T]), { - let mut data = vec![0u8; buffer.size() as usize]; + let mut data = vec![T::default(); buffer.size() as usize / std::mem::size_of::()]; writer(&mut data); - queue.write_buffer(buffer, 0, &data); + queue.write_buffer(buffer, 0, bytemuck::cast_slice(&data)); } #[inline] diff --git a/game/src/game_shaders.rs b/game/src/game_shaders.rs index 83fee70..91af804 100644 --- a/game/src/game_shaders.rs +++ b/game/src/game_shaders.rs @@ -4,7 +4,7 @@ use super::wad_system::WadSystem; use engine::{ BufferTextureType, DependenciesFrom, Entities, EntityId, Error, FloatUniformId, MaterialId, Materials, RenderPipeline, Result, ShaderId, ShaderVertex, Shaders, System, Tick, Uniforms, - Window, + Window, LIGHTS_COUNT, }; use log::{error, info}; use math::Vec2; @@ -139,12 +139,12 @@ impl<'context> Dependencies<'context> { let time = self .uniforms .add_float(self.entities, parent, "time_uniform", 0.0)?; - let lights_buffer = self.uniforms.add_persistent_buffer_u8( + let lights_buffer = self.uniforms.add_persistent_buffer( self.window, self.entities, parent, "lights_buffer_texture", - 256, + LIGHTS_COUNT * std::mem::size_of::(), BufferTextureType::Float, )?; diff --git a/game/src/level.rs b/game/src/level.rs index ab3a77b..788e355 100644 --- a/game/src/level.rs +++ b/game/src/level.rs @@ -260,7 +260,7 @@ impl<'context> System<'context> for Level { .get_float_mut(deps.game_shaders.time()) .expect("missing time"); let light_infos = &mut self.lights; - deps.uniforms.map_buffer_u8( + deps.uniforms.map_buffer( deps.game_shaders.lights_buffer(), |buffer| light_infos.fill_buffer_at(time, buffer), deps.window.queue(), diff --git a/game/src/lights.rs b/game/src/lights.rs index ac3e7eb..67a9677 100644 --- a/game/src/lights.rs +++ b/game/src/lights.rs @@ -24,9 +24,9 @@ impl Lights { }) as u8 } - pub fn fill_buffer_at(&mut self, time: f32, buffer: &mut [u8]) { + pub fn fill_buffer_at(&mut self, time: f32, buffer: &mut [u32]) { for (value, info) in buffer.iter_mut().zip(self.lights.iter()) { - *value = (clamp(light_level_at(info, time)) * 255.0) as u8; + *value = (clamp(light_level_at(info, time)) * 255.0) as u32; } } } From bad177a939ec6515205643837163d192bebade6c Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sat, 27 Jan 2024 21:44:30 +0100 Subject: [PATCH 29/58] Shader fixes --- assets/shaders/sky.wgsl | 6 ++---- assets/shaders/sprite.wgsl | 10 +++++----- assets/shaders/static.wgsl | 17 ++++++++--------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/assets/shaders/sky.wgsl b/assets/shaders/sky.wgsl index 370da7f..a866503 100644 --- a/assets/shaders/sky.wgsl +++ b/assets/shaders/sky.wgsl @@ -31,11 +31,9 @@ fn main_fs(in: VertexOutput) -> @location(0) vec4 { let uv = vec2(in.v_p.x, in.v_p.y) / in.v_p.w * vec2(1, -1); uv = vec2(uv.x - 4.0 * in.v_r.x / 3.14159265358, uv.y + 1.0 + in.v_r.y); if uv.y < 0.0 { - uv.y = abs(mod(-uv.y + u_tiled_band_size, - u_tiled_band_size * 2.0) - u_tiled_band_size); + uv.y = abs((-uv.y + u_tiled_band_size) % (u_tiled_band_size * 2.0) - u_tiled_band_size); } else if uv.y >= 2.0 { - uv.y = abs(mod(uv.y - 2.0 + u_tiled_band_size, - u_tiled_band_size * 2.0) - u_tiled_band_size); + uv.y = abs((uv.y - 2.0 + u_tiled_band_size) % (u_tiled_band_size * 2.0) - u_tiled_band_size); } else if uv.y >= 1.0 { uv.y = 1.0 - uv.y; } diff --git a/assets/shaders/sprite.wgsl b/assets/shaders/sprite.wgsl index 2d85c52..3d8e45d 100644 --- a/assets/shaders/sprite.wgsl +++ b/assets/shaders/sprite.wgsl @@ -22,7 +22,7 @@ struct VertexInput { } struct VertexOutput { - @builtin(position) clip_position: vec3, + @builtin(position) clip_position: vec4, @location(0) v_dist: f32, @location(1) v_tile_uv: vec2, @location(2) v_atlas_uv: vec2, @@ -40,11 +40,11 @@ fn main_vs(in: VertexInput) -> VertexOutput { out.v_atlas_uv = in.a_atlas_uv; } else { let frame_index = u_time / ANIM_FPS; - frame_index = floor(mod(frame_index, f32(in.a_num_frames))); + frame_index = floor(frame_index % f32(in.a_num_frames)); let atlas_u = in.a_atlas_uv.x + frame_index * in.a_tile_size.x; let n_rows_down = ceil((atlas_u + in.a_tile_size.x) / u_atlas_size.x) - 1.0; - atlas_u += mod(u_atlas_size.x - in.a_atlas_uv.x, in.a_tile_size.x) * n_rows_down; + atlas_u += (u_atlas_size.x - in.a_atlas_uv.x) % in.a_tile_size.x * n_rows_down; let atlas_v = in.a_atlas_uv.y + n_rows_down * in.a_tile_size.y; out.v_atlas_uv = vec2(atlas_u, atlas_v); @@ -53,7 +53,7 @@ fn main_vs(in: VertexInput) -> VertexOutput { let pos = in.a_pos + u_right * in.a_local_x; let projected_pos = u_viewproj * (u_model * vec4(pos, 1.0)); - out.v_light = u_lights[in.a_light]; + out.v_light = f32(u_lights[in.a_light]); out.v_dist = projected_pos.w; out.clip_position = projected_pos; return out; @@ -64,7 +64,7 @@ const LIGHT_SCALE: f32 = 2.0; @fragment fn main_fs(in: VertexOutput) -> @location(0) vec4 { - let uv = mod(in.v_tile_uv, in.v_tile_size) + in.v_atlas_uv; + let uv = in.v_tile_uv % in.v_tile_size + in.v_atlas_uv; let palette_index = textureSample(u_atlas, u_sampler, uv / u_atlas_size).rg; if palette_index.g > .5 { // Transparent pixel. discard; diff --git a/assets/shaders/static.wgsl b/assets/shaders/static.wgsl index 5d3c2b4..1dfb056 100644 --- a/assets/shaders/static.wgsl +++ b/assets/shaders/static.wgsl @@ -22,7 +22,7 @@ struct VertexInput { } struct VertexOutput { - @builtin(position) clip_position: vec3, + @builtin(position) clip_position: vec4, @location(0) v_dist: f32, @location(1) v_tile_uv: vec2, @location(2) v_atlas_uv: vec2, @@ -39,12 +39,11 @@ fn main_vs(in: VertexInput) -> VertexOutput { if in.a_num_frames == 1 { out.v_atlas_uv = in.a_atlas_uv; } else { - let frame_index = u_time / ANIM_FPS; - frame_index = floor(mod(frame_index, f32(in.a_num_frames))); + let frame_index = floor((u_time / ANIM_FPS) % f32(in.a_num_frames)); - let atlas_u = in.a_atlas_uv.x + frame_index * in.a_tile_size.x; + var atlas_u = in.a_atlas_uv.x + frame_index * in.a_tile_size.x; let n_rows_down = ceil((atlas_u + in.a_tile_size.x) / u_atlas_size.x) - 1.0; - atlas_u += mod(u_atlas_size.x - in.a_atlas_uv.x, in.a_tile_size.x) * n_rows_down; + atlas_u += (u_atlas_size.x - in.a_atlas_uv.x) % in.a_tile_size.x * n_rows_down; let atlas_v = in.a_atlas_uv.y + n_rows_down * in.a_row_height; out.v_atlas_uv = vec2(atlas_u, atlas_v); @@ -52,7 +51,7 @@ fn main_vs(in: VertexInput) -> VertexOutput { out.v_tile_size = in.a_tile_size; let projected_pos = u_viewproj * u_model * vec4(in.a_pos, 1); out.v_dist = projected_pos.w; - out.v_light = u_lights[in.a_light]; + out.v_light = f32(u_lights[in.a_light]); out.clip_position = projected_pos; return out; } @@ -62,13 +61,13 @@ const LIGHT_SCALE: f32 = 2.0; @fragment fn main_fs(in: VertexOutput) -> @location(0) vec4 { - let uv = mod(v_tile_uv, v_tile_size) + v_atlas_uv; + let uv = in.v_tile_uv % in.v_tile_size + in.v_atlas_uv; let palette_index = textureSample(u_atlas, u_sampler, uv / u_atlas_size).rg; if palette_index.g > .5 { // Transparent pixel. discard; } else { - let dist_term = min(1.0, 1.0 - DIST_SCALE / (v_dist + DIST_SCALE)); - let light = v_light * LIGHT_SCALE - dist_term; + let dist_term = min(1.0, 1.0 - DIST_SCALE / (in.v_dist + DIST_SCALE)); + let light = in.v_light * LIGHT_SCALE - dist_term; return vec4(textureSample(u_palette, u_sampler, vec2(palette_index.r, 1.0 - light)).rgb, 1.0); } } From 997e3aa736f18eccb88f100b3de71352923efd22 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sat, 27 Jan 2024 22:11:45 +0100 Subject: [PATCH 30/58] Shader and WGPU fixes --- assets/shaders/sky.wgsl | 14 +++++++------- assets/shaders/sprite.wgsl | 11 +++++------ engine/src/shaders.rs | 2 +- engine/src/uniforms.rs | 2 +- game/src/level.rs | 10 +++++----- game/src/vertex.rs | 20 ++++++++++---------- 6 files changed, 29 insertions(+), 30 deletions(-) diff --git a/assets/shaders/sky.wgsl b/assets/shaders/sky.wgsl index a866503..3f16927 100644 --- a/assets/shaders/sky.wgsl +++ b/assets/shaders/sky.wgsl @@ -4,7 +4,7 @@ @group(0) @binding(4) var u_palette: texture_2d; @group(1) @binding(0) var u_texture: texture_2d; -@group(1) @binding(2) var u_tiled_band_size: f32; +@group(1) @binding(2) var u_tiled_band_size: f32; @group(2) @binding(0) var u_model: mat4x4; @@ -15,12 +15,12 @@ struct VertexOutput { } @vertex -fn main_vs(a_pos: vec3) -> VertexOutput { +fn main_vs(@location(0) a_pos: vec3) -> VertexOutput { var out: VertexOutput; - mat4 transform = u_viewproj * u_model; - vec4forward = transform[2]; - out.v_r = vec2(atan(forward.x, forward.z), forward.y / forward.w); - vec4projected_pos = transform * vec4(a_pos, 1); + let transform = u_viewproj * u_model; + let forward = transform[2]; + out.v_r = vec2(atan(forward.x / forward.z), forward.y / forward.w); + let projected_pos = transform * vec4(a_pos, 1); out.v_p = projected_pos; out.clip_position = projected_pos; return out; @@ -28,7 +28,7 @@ fn main_vs(a_pos: vec3) -> VertexOutput { @fragment fn main_fs(in: VertexOutput) -> @location(0) vec4 { - let uv = vec2(in.v_p.x, in.v_p.y) / in.v_p.w * vec2(1, -1); + var uv = vec2(in.v_p.x, in.v_p.y) / in.v_p.w * vec2(1, -1); uv = vec2(uv.x - 4.0 * in.v_r.x / 3.14159265358, uv.y + 1.0 + in.v_r.y); if uv.y < 0.0 { uv.y = abs((-uv.y + u_tiled_band_size) % (u_tiled_band_size * 2.0) - u_tiled_band_size); diff --git a/assets/shaders/sprite.wgsl b/assets/shaders/sprite.wgsl index 3d8e45d..da6029c 100644 --- a/assets/shaders/sprite.wgsl +++ b/assets/shaders/sprite.wgsl @@ -35,14 +35,13 @@ const ANIM_FPS: f32 = 8.0 / 35.0; @vertex fn main_vs(in: VertexInput) -> VertexOutput { var out: VertexOutput; - v_tile_uv = in.a_tile_uv; + out.v_tile_uv = in.a_tile_uv; if in.a_num_frames == 1 { out.v_atlas_uv = in.a_atlas_uv; } else { - let frame_index = u_time / ANIM_FPS; - frame_index = floor(frame_index % f32(in.a_num_frames)); + let frame_index = floor((u_time / ANIM_FPS) % f32(in.a_num_frames)); - let atlas_u = in.a_atlas_uv.x + frame_index * in.a_tile_size.x; + var atlas_u = in.a_atlas_uv.x + frame_index * in.a_tile_size.x; let n_rows_down = ceil((atlas_u + in.a_tile_size.x) / u_atlas_size.x) - 1.0; atlas_u += (u_atlas_size.x - in.a_atlas_uv.x) % in.a_tile_size.x * n_rows_down; @@ -69,8 +68,8 @@ fn main_fs(in: VertexOutput) -> @location(0) vec4 { if palette_index.g > .5 { // Transparent pixel. discard; } else { - float dist_term = min(1.0, 1.0 - DIST_SCALE / (in.v_dist + DIST_SCALE)); - float light = min(in.v_light, in.v_light * LIGHT_SCALE - dist_term); + let dist_term = min(1.0, 1.0 - DIST_SCALE / (in.v_dist + DIST_SCALE)); + let light = min(in.v_light, in.v_light * LIGHT_SCALE - dist_term); return vec4(textureSample(u_palette, u_sampler, vec2(palette_index.r, 1.0 - light)).rgb, 1.0); } } diff --git a/engine/src/shaders.rs b/engine/src/shaders.rs index 5c7d2be..2b76e67 100644 --- a/engine/src/shaders.rs +++ b/engine/src/shaders.rs @@ -186,7 +186,7 @@ impl<'context> InfallibleSystem<'context> for Shaders { wgpu::BindGroupLayoutEntry { binding: 1, visibility: wgpu::ShaderStages::FRAGMENT, - ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Comparison), + ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), count: None, }, wgpu::BindGroupLayoutEntry { diff --git a/engine/src/uniforms.rs b/engine/src/uniforms.rs index d3b5081..3d4c3fb 100644 --- a/engine/src/uniforms.rs +++ b/engine/src/uniforms.rs @@ -223,7 +223,7 @@ impl Uniforms { let buffer = window.device().create_buffer(&wgpu::BufferDescriptor { label: Some(name), size: size as u64, - usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, + usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST, mapped_at_creation: false, }); debug!("Buffer texture {:?} created successfully", name); diff --git a/game/src/level.rs b/game/src/level.rs index 788e355..8a64c70 100644 --- a/game/src/level.rs +++ b/game/src/level.rs @@ -529,9 +529,9 @@ impl<'a> Builder<'a> { a_tile_uv: [tile_u, tile_v], a_tile_size: [bounds.size[0], bounds.size[1]], a_scroll_rate: scroll_rate, - a_num_frames: bounds.num_frames as u32, + a_num_frames: bounds.num_frames as i32, a_row_height: bounds.row_height as f32, - a_light: light_info as u32, + a_light: light_info as i32, ..Default::default() }); self @@ -544,9 +544,9 @@ impl<'a> Builder<'a> { a_tile_uv: [-xz[0] * 100.0, -xz[1] * 100.0], a_tile_size: [bounds.size[0], bounds.size[1]], a_scroll_rate: 0.0, - a_num_frames: bounds.num_frames as u32, + a_num_frames: bounds.num_frames as i32, a_row_height: bounds.row_height as f32, - a_light: light_info as u32, + a_light: light_info as i32, ..Default::default() }); self @@ -576,7 +576,7 @@ impl<'a> Builder<'a> { a_tile_uv: [tile_u, tile_v], a_tile_size: [bounds.size[0], bounds.size[1]], a_num_frames: 1, - a_light: light_info as u32, + a_light: light_info as i32, ..Default::default() }); self diff --git a/game/src/vertex.rs b/game/src/vertex.rs index 89fe6b0..a5aa911 100644 --- a/game/src/vertex.rs +++ b/game/src/vertex.rs @@ -15,8 +15,8 @@ pub struct StaticVertex { pub a_tile_size: [f32; 2], pub a_scroll_rate: f32, pub a_row_height: f32, - pub a_num_frames: u32, - pub a_light: u32, + pub a_num_frames: i32, + pub a_light: i32, } impl ShaderVertex for StaticVertex { @@ -33,7 +33,7 @@ impl ShaderVertex for StaticVertex { shader_location: 0, }, wgpu::VertexAttribute { - format: wgpu::VertexFormat::Float32, + format: wgpu::VertexFormat::Float32x2, offset: offset_of!(StaticVertex, a_atlas_uv) as u64, shader_location: 1, }, @@ -48,7 +48,7 @@ impl ShaderVertex for StaticVertex { shader_location: 3, }, wgpu::VertexAttribute { - format: wgpu::VertexFormat::Float32x2, + format: wgpu::VertexFormat::Float32, offset: offset_of!(StaticVertex, a_scroll_rate) as u64, shader_location: 4, }, @@ -58,12 +58,12 @@ impl ShaderVertex for StaticVertex { shader_location: 5, }, wgpu::VertexAttribute { - format: wgpu::VertexFormat::Uint32, + format: wgpu::VertexFormat::Sint32, offset: offset_of!(StaticVertex, a_num_frames) as u64, shader_location: 6, }, wgpu::VertexAttribute { - format: wgpu::VertexFormat::Uint32, + format: wgpu::VertexFormat::Sint32, offset: offset_of!(StaticVertex, a_light) as u64, shader_location: 7, }, @@ -82,8 +82,8 @@ pub struct SpriteVertex { pub a_tile_uv: [f32; 2], pub a_tile_size: [f32; 2], pub a_local_x: f32, - pub a_num_frames: u32, - pub a_light: u32, + pub a_num_frames: i32, + pub a_light: i32, } impl ShaderVertex for SpriteVertex { @@ -120,12 +120,12 @@ impl ShaderVertex for SpriteVertex { shader_location: 4, }, wgpu::VertexAttribute { - format: wgpu::VertexFormat::Uint32, + format: wgpu::VertexFormat::Sint32, offset: offset_of!(SpriteVertex, a_num_frames) as u64, shader_location: 5, }, wgpu::VertexAttribute { - format: wgpu::VertexFormat::Uint32, + format: wgpu::VertexFormat::Sint32, offset: offset_of!(SpriteVertex, a_light) as u64, shader_location: 6, }, From c05f84af292b7c8d065d77f239c129b0d06b0920 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sat, 27 Jan 2024 22:17:03 +0100 Subject: [PATCH 31/58] More WGPU fixes --- engine/src/materials.rs | 20 +++++++++++++++++++- game/src/game_shaders.rs | 4 ++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/engine/src/materials.rs b/engine/src/materials.rs index 6411c95..21143c5 100644 --- a/engine/src/materials.rs +++ b/engine/src/materials.rs @@ -140,6 +140,11 @@ impl<'a> MaterialRefMut<'a> { contents: bytemuck::cast_slice(&atlas_size), usage: wgpu::BufferUsages::UNIFORM, }); + let tiled_band_size_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice(&[0.0f32]), + usage: wgpu::BufferUsages::UNIFORM, + }); self.material.bind_group = Some(device.create_bind_group(&wgpu::BindGroupDescriptor { label: None, layout: &shaders.material_bind_group_layout(), @@ -152,6 +157,10 @@ impl<'a> MaterialRefMut<'a> { binding: 1, resource: atlas_size_buffer.as_entire_binding(), }, + wgpu::BindGroupEntry { + binding: 2, + resource: tiled_band_size_buffer.as_entire_binding(), + }, ], })); self @@ -165,6 +174,11 @@ impl<'a> MaterialRefMut<'a> { shaders: &Shaders, ) -> &mut Self { let texture_view = texture.create_view(&Default::default()); + let atlas_size_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice(&[0.0f32, 0.0]), + usage: wgpu::BufferUsages::UNIFORM, + }); let tiled_band_size_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: None, contents: bytemuck::cast_slice(&[tiled_band_size]), @@ -179,7 +193,11 @@ impl<'a> MaterialRefMut<'a> { resource: wgpu::BindingResource::TextureView(&texture_view), }, wgpu::BindGroupEntry { - binding: 3, + binding: 1, + resource: atlas_size_buffer.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 2, resource: tiled_band_size_buffer.as_entire_binding(), }, ], diff --git a/game/src/game_shaders.rs b/game/src/game_shaders.rs index 91af804..91125b2 100644 --- a/game/src/game_shaders.rs +++ b/game/src/game_shaders.rs @@ -401,7 +401,7 @@ impl<'context> Dependencies<'context> { name, pixels, size, - wgpu::TextureFormat::Rgba8Unorm, + wgpu::TextureFormat::Rg8Unorm, )?, ImageRef::Opaque { pixels, size } => self.uniforms.add_texture_2d( self.window, @@ -410,7 +410,7 @@ impl<'context> Dependencies<'context> { name, pixels, size, - wgpu::TextureFormat::Rgba8Unorm, + wgpu::TextureFormat::R8Unorm, )?, }) } From 2c48a650443109314d8394f7c2652036c0d56b6b Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 16:02:35 +0100 Subject: [PATCH 32/58] Remove references to glium --- engine/src/materials.rs | 23 +--------------- engine/src/renderer.rs | 4 +-- engine/src/uniforms.rs | 58 ++-------------------------------------- game/src/game_shaders.rs | 7 +++-- 4 files changed, 7 insertions(+), 85 deletions(-) diff --git a/engine/src/materials.rs b/engine/src/materials.rs index 21143c5..e203c2c 100644 --- a/engine/src/materials.rs +++ b/engine/src/materials.rs @@ -2,7 +2,7 @@ use super::entities::{Entities, Entity, EntityId}; use super::errors::Result; use super::shaders::{ShaderId, Shaders}; use super::system::InfallibleSystem; -use super::uniforms::{UniformId, Uniforms}; +use super::uniforms::UniformId; use idcontain::IdMapVec; use log::{debug, error}; use wgpu::util::DeviceExt; @@ -59,7 +59,6 @@ impl Materials { pub fn get<'a>( &'a self, shaders: &'a Shaders, - uniforms: &'a Uniforms, material_id: MaterialId, ) -> Option> { let material = self.map.get(material_id.0)?; @@ -72,26 +71,6 @@ impl Materials { return None; }; - let mut uniform_values = [None; MAX_UNIFORMS]; - for (value, &uniform) in (&mut uniform_values[..]) - .iter_mut() - .zip(&material.uniforms[..]) - { - if let Some((name, id)) = uniform { - if let Some(uniform_value) = uniforms.get_value(id) { - *value = Some((name, uniform_value)); - } else { - error!( - "Missing uniform for material {:?}: name={:?} id={:?}", - material_id, name, id - ); - return None; - } - } else { - break; - } - } - Some(MaterialRef { pipeline, bind_group: material diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 0415836..12de766 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -174,9 +174,7 @@ impl<'context> System<'context> for Renderer { // TODO: Set u_right on the mesh - let material = if let Some(material) = - deps.materials.get(deps.shaders, deps.uniforms, material) - { + let material = if let Some(material) = deps.materials.get(deps.shaders, material) { material } else { // If there is a mesh but no material, the model is badly set up. This is an diff --git a/engine/src/uniforms.rs b/engine/src/uniforms.rs index 3d4c3fb..db50ad8 100644 --- a/engine/src/uniforms.rs +++ b/engine/src/uniforms.rs @@ -7,9 +7,6 @@ use super::window::Window; use crate::internal_derive::DependenciesFrom; use bytemuck::Pod; use cgmath::SquareMatrix; -use glium::buffer::Content as BufferContent; -use glium::texture::buffer_texture::{BufferTexture, BufferTextureType}; -use glium::uniforms::{AsUniformValue, UniformValue}; use idcontain::IdMapVec; use log::{debug, error}; use math::{Mat4, Vec2, Vec2f}; @@ -23,10 +20,7 @@ pub struct Texture2dId(EntityId); pub struct FloatUniformId(EntityId); #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Copy, Clone)] -pub struct BufferTextureId -where - [T]: BufferContent, -{ +pub struct BufferTextureId { id: EntityId, _phantom: PhantomData<*const T>, @@ -51,7 +45,6 @@ pub struct Uniforms { // TODO(cristicbz): Textures should be their own resource! texture2ds: IdMapVec, floats: IdMapVec, - buffer_textures_u8: IdMapVec>, mat4s: IdMapVec, vec2fs: IdMapVec, global_bind_group: Option, @@ -66,7 +59,6 @@ impl Uniforms { let Uniforms { ref mut texture2ds, ref mut floats, - ref mut buffer_textures_u8, ref mut mat4s, ref mut vec2fs, global_bind_group: _, @@ -80,9 +72,6 @@ impl Uniforms { if floats.remove(entity).is_some() { debug!("Removed uniform {:?}.", entity); } - if buffer_textures_u8.remove(entity).is_some() { - debug!("Removed uniform {:?}.", entity); - } if mat4s.remove(entity).is_some() { debug!("Removed uniform {:?}.", entity); } @@ -214,12 +203,8 @@ impl Uniforms { parent: EntityId, name: &'static str, size: usize, - texture_type: BufferTextureType, ) -> Result { - debug!( - "Creating persistent buffer {:?}, size={:?}, type={:?}", - name, size, texture_type - ); + debug!("Creating persistent buffer {:?}, size={:?}", name, size); let buffer = window.device().create_buffer(&wgpu::BufferDescriptor { label: Some(name), size: size as u64, @@ -248,33 +233,6 @@ impl Uniforms { queue.write_buffer(buffer, 0, bytemuck::cast_slice(&data)); } - #[inline] - pub fn get_value(&self, id: UniformId) -> Option { - match id { - UniformId::Texture2d(_) => unimplemented!(), - UniformId::Float(id) => self - .floats - .get(id.0) - .map(|&value| UniformValue::Float(value)), - UniformId::Vec2f(id) => self - .vec2fs - .get(id.0) - .map(|vec2| UniformValue::Vec2([vec2[0], vec2[1]])), - UniformId::Mat4(id) => self.mat4s.get(id.0).map(|mat4| { - UniformValue::Mat4([ - [mat4[0][0], mat4[0][1], mat4[0][2], mat4[0][3]], - [mat4[1][0], mat4[1][1], mat4[1][2], mat4[1][3]], - [mat4[2][0], mat4[2][1], mat4[2][2], mat4[2][3]], - [mat4[3][0], mat4[3][1], mat4[3][2], mat4[3][3]], - ]) - }), - UniformId::BufferTextureU8(id) => self - .buffer_textures_u8 - .get(id.id) - .map(AsUniformValue::as_uniform_value), - } - } - pub fn set_globals( &mut self, device: &wgpu::Device, @@ -415,7 +373,6 @@ impl<'context> InfallibleSystem<'context> for Uniforms { Uniforms { texture2ds: IdMapVec::with_capacity(32), floats: IdMapVec::with_capacity(32), - buffer_textures_u8: IdMapVec::with_capacity(32), mat4s: IdMapVec::with_capacity(32), vec2fs: IdMapVec::with_capacity(32), global_bind_group: None, @@ -430,7 +387,6 @@ impl<'context> InfallibleSystem<'context> for Uniforms { let Uniforms { ref mut texture2ds, ref mut floats, - ref mut buffer_textures_u8, ref mut mat4s, ref mut vec2fs, global_bind_group: _, @@ -444,9 +400,6 @@ impl<'context> InfallibleSystem<'context> for Uniforms { if floats.remove(entity).is_some() { debug!("Removed uniform {:?}.", entity); } - if buffer_textures_u8.remove(entity).is_some() { - debug!("Removed uniform> {:?}.", entity); - } if mat4s.remove(entity).is_some() { debug!("Removed uniform {:?}.", entity); } @@ -473,13 +426,6 @@ impl<'context> InfallibleSystem<'context> for Uniforms { error!("Uniforms leaked, {} instances.", self.floats.len()); } - if !self.buffer_textures_u8.is_empty() { - error!( - "Uniforms > leaked, {} instances.", - self.buffer_textures_u8.len() - ); - } - if !self.mat4s.is_empty() { error!("Uniforms leaked, {} instances.", self.mat4s.len()); } diff --git a/game/src/game_shaders.rs b/game/src/game_shaders.rs index 91125b2..b7e237c 100644 --- a/game/src/game_shaders.rs +++ b/game/src/game_shaders.rs @@ -2,9 +2,9 @@ use crate::vertex::{SkyVertex, SpriteVertex, StaticVertex}; use super::wad_system::WadSystem; use engine::{ - BufferTextureType, DependenciesFrom, Entities, EntityId, Error, FloatUniformId, MaterialId, - Materials, RenderPipeline, Result, ShaderId, ShaderVertex, Shaders, System, Tick, Uniforms, - Window, LIGHTS_COUNT, + DependenciesFrom, Entities, EntityId, Error, FloatUniformId, MaterialId, Materials, + RenderPipeline, Result, ShaderId, ShaderVertex, Shaders, System, Tick, Uniforms, Window, + LIGHTS_COUNT, }; use log::{error, info}; use math::Vec2; @@ -145,7 +145,6 @@ impl<'context> Dependencies<'context> { parent, "lights_buffer_texture", LIGHTS_COUNT * std::mem::size_of::(), - BufferTextureType::Float, )?; let static_shader = self.load_shader::( From 418fa12701acb0b18b33a6f39f4a768db6b8c3b7 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 16:04:10 +0100 Subject: [PATCH 33/58] Remove glium dependency --- Cargo.lock | 127 ++----------------------------------------- engine/Cargo.toml | 4 -- engine/src/errors.rs | 82 ---------------------------- engine/src/lib.rs | 5 -- game/Cargo.toml | 6 +- 5 files changed, 7 insertions(+), 217 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 801b9b7..4e9f302 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -344,15 +344,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" -[[package]] -name = "cgl" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" -dependencies = [ - "libc", -] - [[package]] name = "cgmath" version = "0.18.0" @@ -592,7 +583,6 @@ dependencies = [ "failchain", "failure", "futures", - "glium", "idcontain", "image", "lock_api", @@ -720,12 +710,6 @@ dependencies = [ "spin", ] -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - [[package]] name = "foreign-types" version = "0.5.0" @@ -859,7 +843,6 @@ dependencies = [ "failchain", "failure", "futures", - "glium", "idcontain", "image", "lock_api", @@ -921,25 +904,6 @@ dependencies = [ "xml-rs", ] -[[package]] -name = "glium" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d5813c960a54b76e20fe4ef7e54fbeb12545776a11ecf14f42a946a1c65964" -dependencies = [ - "backtrace", - "fnv", - "gl_generator", - "glutin", - "glutin-winit", - "lazy_static", - "memoffset 0.9.0", - "raw-window-handle 0.5.2", - "smallvec", - "takeable-option", - "winit", -] - [[package]] name = "glow" version = "0.13.1" @@ -952,62 +916,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "glutin" -version = "0.31.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "005459a22af86adc706522d78d360101118e2638ec21df3852fcc626e0dbb212" -dependencies = [ - "bitflags 2.4.1", - "cfg_aliases", - "cgl", - "core-foundation", - "dispatch", - "glutin_egl_sys", - "glutin_glx_sys", - "glutin_wgl_sys", - "icrate", - "libloading 0.8.1", - "objc2", - "once_cell", - "raw-window-handle 0.5.2", - "wayland-sys", - "windows-sys 0.48.0", - "x11-dl", -] - -[[package]] -name = "glutin-winit" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebcdfba24f73b8412c5181e56f092b5eff16671c514ce896b258a0a64bd7735" -dependencies = [ - "cfg_aliases", - "glutin", - "raw-window-handle 0.5.2", - "winit", -] - -[[package]] -name = "glutin_egl_sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77cc5623f5309ef433c3dd4ca1223195347fe62c413da8e2fdd0eb76db2d9bcd" -dependencies = [ - "gl_generator", - "windows-sys 0.48.0", -] - -[[package]] -name = "glutin_glx_sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a165fd686c10dcc2d45380b35796e577eacfd43d4660ee741ec8ebe2201b3b4f" -dependencies = [ - "gl_generator", - "x11-dl", -] - [[package]] name = "glutin_wgl_sys" version = "0.5.0" @@ -1379,15 +1287,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "metal" version = "0.27.0" @@ -1454,8 +1353,7 @@ dependencies = [ "log", "ndk-sys", "num_enum", - "raw-window-handle 0.5.2", - "raw-window-handle 0.6.0", + "raw-window-handle", "thiserror", ] @@ -1483,7 +1381,7 @@ dependencies = [ "bitflags 1.2.1", "cfg-if", "libc", - "memoffset 0.7.1", + "memoffset", ] [[package]] @@ -1797,12 +1695,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" 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 = "raw-window-handle" version = "0.6.0" @@ -2140,12 +2032,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "takeable-option" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ae8932fcfea38b7d3883ae2ab357b0d57a02caaa18ebb4f5ece08beaec4aa0" - [[package]] name = "termcolor" version = "1.4.1" @@ -2611,7 +2497,7 @@ dependencies = [ "naga", "parking_lot", "profiling", - "raw-window-handle 0.6.0", + "raw-window-handle", "smallvec", "static_assertions", "wasm-bindgen", @@ -2639,7 +2525,7 @@ dependencies = [ "once_cell", "parking_lot", "profiling", - "raw-window-handle 0.6.0", + "raw-window-handle", "rustc-hash", "smallvec", "thiserror", @@ -2681,7 +2567,7 @@ dependencies = [ "parking_lot", "profiling", "range-alloc", - "raw-window-handle 0.6.0", + "raw-window-handle", "renderdoc-sys", "rustc-hash", "smallvec", @@ -2984,8 +2870,7 @@ dependencies = [ "once_cell", "orbclient", "percent-encoding", - "raw-window-handle 0.5.2", - "raw-window-handle 0.6.0", + "raw-window-handle", "redox_syscall 0.3.5", "rustix", "sctk-adwaita", diff --git a/engine/Cargo.toml b/engine/Cargo.toml index 534e3c7..607e07a 100644 --- a/engine/Cargo.toml +++ b/engine/Cargo.toml @@ -29,9 +29,5 @@ lock_api = "0.4.11" features = ["release_max_level_info"] version = "0.4.14" -[dependencies.glium] -features = ["glutin"] -version = "0.34.0" - [dev-dependencies] env_logger = "*" diff --git a/engine/src/errors.rs b/engine/src/errors.rs index 61c1356..2b895b0 100644 --- a/engine/src/errors.rs +++ b/engine/src/errors.rs @@ -74,85 +74,3 @@ impl ConvertGlium for T { ErrorKind::UnsupportedFeature { needed_by } } } - -impl UnsupportedFeature for glium::vertex::BufferCreationError {} -impl UnsupportedFeature for glium::index::BufferCreationError {} -impl UnsupportedFeature for glium::texture::TextureCreationError {} - -impl ConvertGlium for glium::texture::buffer_texture::CreationError { - fn convert_glium(self, needed_by: String) -> ErrorKind { - use glium::buffer::BufferCreationError::*; - use glium::texture::buffer_texture::CreationError::*; - use glium::texture::buffer_texture::TextureCreationError::*; - - match self { - BufferCreationError(OutOfMemory) => ErrorKind::OutOfVideoMemory { needed_by }, - TextureCreationError(FormatNotSupported) - | TextureCreationError(NotSupported) - | TextureCreationError(TooLarge) - | BufferCreationError(BufferTypeNotSupported) => { - ErrorKind::UnsupportedFeature { needed_by } - } - } - } -} - -impl ConvertGlium for glium::ProgramCreationError { - fn convert_glium(self, needed_by: String) -> ErrorKind { - use glium::ProgramCreationError::*; - match &self { - CompilationError(log, _) | LinkingError(log) => ErrorKind::Shader { - log: log.clone(), - needed_by, - }, - - BinaryHeaderError => ErrorKind::Shader { - log: "Binary header error.".to_owned(), - needed_by, - }, - - ShaderTypeNotSupported - | CompilationNotSupported - | TransformFeedbackNotSupported - | PointSizeNotSupported => ErrorKind::UnsupportedFeature { needed_by }, - } - } -} - -impl ConvertGlium for glium::DrawError { - fn convert_glium(self, needed_by: String) -> ErrorKind { - use glium::DrawError::*; - match self { - FixedIndexRestartingNotSupported - | ViewportTooLarge - | UnsupportedVerticesPerPatch - | TessellationNotSupported - | SamplersNotSupported - | TransformFeedbackNotSupported - | SmoothingNotSupported - | ProvokingVertexNotSupported - | RasterizerDiscardNotSupported - | DepthClampNotSupported - | ClipControlNotSupported - | BlendingParameterNotSupported => ErrorKind::UnsupportedFeature { needed_by }, - - NoDepthBuffer - | AttributeTypeMismatch - | AttributeMissing - | InvalidDepthRange - | UniformTypeMismatch { .. } - | UniformBufferToValue { .. } - | UniformValueToBlock { .. } - | UniformBlockLayoutMismatch { .. } - | TessellationWithoutPatches - | InstancesCountMismatch - | VerticesSourcesLengthMismatch - | SubroutineNotFound { .. } - | SubroutineUniformMissing { .. } - | SubroutineUniformToValue { .. } - | ClipPlaneIndexOutOfBounds { .. } - | InsufficientImageUnits - | WrongQueryOperation => panic!("Invalid draw call: {:?}", self), - } - } -} diff --git a/engine/src/lib.rs b/engine/src/lib.rs index b767910..4bcfe8f 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -41,11 +41,6 @@ pub use self::uniforms::{ Vec2fUniformId, }; pub use self::window::{Window, WindowConfig}; -pub use glium::texture::buffer_texture::BufferTextureType; -pub use glium::texture::{ClientFormat, PixelValue}; -pub use glium::uniforms::{ - MagnifySamplerFilter, MinifySamplerFilter, SamplerBehavior, SamplerWrapFunction, -}; mod internal_derive { pub use super::context::DependenciesFrom; diff --git a/game/Cargo.toml b/game/Cargo.toml index a4d034b..b6bcde3 100644 --- a/game/Cargo.toml +++ b/game/Cargo.toml @@ -26,8 +26,4 @@ lock_api = "0.4.11" [dependencies.log] features = ["release_max_level_info"] -version = "0.4.14" - -[dependencies.glium] -features = ["glutin"] -version = "0.34.0" +version = "0.4.14" \ No newline at end of file From 66d1c4a4eb0393c2508abd19088e1128c59cdc29 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 16:06:22 +0100 Subject: [PATCH 34/58] Remove unused trait --- engine/src/errors.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/engine/src/errors.rs b/engine/src/errors.rs index 2b895b0..ec47e51 100644 --- a/engine/src/errors.rs +++ b/engine/src/errors.rs @@ -63,14 +63,4 @@ impl ChainErrorKind for ErrorKind { type Error = Error; } -pub(crate) trait ConvertGlium: Fail + Sized { - fn convert_glium(self, needed_by: String) -> ErrorKind; -} - pub(crate) trait UnsupportedFeature: Fail + Sized {} - -impl ConvertGlium for T { - fn convert_glium(self, needed_by: String) -> ErrorKind { - ErrorKind::UnsupportedFeature { needed_by } - } -} From 916cc73c2abada0c6506bdcebf779c4fea6aa57b Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 16:10:37 +0100 Subject: [PATCH 35/58] Add label --- engine/src/renderer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 12de766..9bff95f 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -130,7 +130,7 @@ impl<'context> System<'context> for Renderer { .create_command_encoder(&Default::default()); { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: None, + label: Some("Main render pass"), color_attachments: &[Some(wgpu::RenderPassColorAttachment { view: &self.view, resolve_target: Some(&view), From 5f3c2d762a30a508f319893ffe0aa3d0fc3c1ce7 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 16:59:28 +0100 Subject: [PATCH 36/58] Remove GLSL shaders --- assets/shaders/sky.frag | 26 --------------------- assets/shaders/sky.vert | 16 ------------- assets/shaders/sprite.frag | 28 ----------------------- assets/shaders/sprite.vert | 47 -------------------------------------- assets/shaders/static.frag | 28 ----------------------- assets/shaders/static.vert | 45 ------------------------------------ engine/src/platform.rs | 7 ------ engine/src/shaders.rs | 35 +++------------------------- 8 files changed, 3 insertions(+), 229 deletions(-) delete mode 100644 assets/shaders/sky.frag delete mode 100644 assets/shaders/sky.vert delete mode 100644 assets/shaders/sprite.frag delete mode 100644 assets/shaders/sprite.vert delete mode 100644 assets/shaders/static.frag delete mode 100644 assets/shaders/static.vert diff --git a/assets/shaders/sky.frag b/assets/shaders/sky.frag deleted file mode 100644 index 23f2e6d..0000000 --- a/assets/shaders/sky.frag +++ /dev/null @@ -1,26 +0,0 @@ -precision mediump float; - -out vec3 color; - -uniform sampler2D u_palette; -uniform sampler2D u_texture; -uniform float u_tiled_band_size; - -flat in vec2 v_r; -in vec4 v_p; - -void main() { - vec2 uv = vec2(v_p.x, v_p.y) / v_p.w * vec2(1, -1); - uv = vec2(uv.x - 4.0 * v_r.x / 3.14159265358, uv.y + 1.0 + v_r.y); - if (uv.y < 0.0) { - uv.y = abs(mod(-uv.y + u_tiled_band_size, - u_tiled_band_size * 2.0) - u_tiled_band_size); - } else if (uv.y >= 2.0) { - uv.y = abs(mod(uv.y - 2.0 + u_tiled_band_size, - u_tiled_band_size * 2.0) - u_tiled_band_size); - } else if (uv.y >= 1.0) { - uv.y = 1.0 - uv.y; - } - float palette_index = texture(u_texture, uv).r; - color = texture(u_palette, vec2(palette_index, 0.0)).rgb; -} diff --git a/assets/shaders/sky.vert b/assets/shaders/sky.vert deleted file mode 100644 index 857f81b..0000000 --- a/assets/shaders/sky.vert +++ /dev/null @@ -1,16 +0,0 @@ -uniform mat4 u_modelview; -uniform mat4 u_projection; - -in vec3 a_pos; - -flat out vec2 v_r; -out vec4 v_p; - -void main() { - mat4 transform = u_projection * u_modelview; - vec4 forward = transform[2]; - v_r = vec2(atan(forward.x, forward.z), forward.y / forward.w); - vec4 projected_pos = transform * vec4(a_pos, 1); - v_p = projected_pos; - gl_Position = projected_pos; -} diff --git a/assets/shaders/sprite.frag b/assets/shaders/sprite.frag deleted file mode 100644 index aceb615..0000000 --- a/assets/shaders/sprite.frag +++ /dev/null @@ -1,28 +0,0 @@ -precision mediump float; - -out vec3 color; - -uniform vec2 u_atlas_size; -uniform sampler2D u_atlas; -uniform sampler2D u_palette; - -in float v_dist; -in vec2 v_tile_uv; -flat in vec2 v_atlas_uv; -flat in vec2 v_tile_size; -flat in float v_light; - -const float DIST_SCALE = 1.0; -const float LIGHT_SCALE = 2.0; - -void main() { - vec2 uv = mod(v_tile_uv, v_tile_size) + v_atlas_uv; - vec2 palette_index = texture(u_atlas, uv / u_atlas_size).rg; - if (palette_index.g > .5) { // Transparent pixel. - discard; - } else { - float dist_term = min(1.0, 1.0 - DIST_SCALE / (v_dist + DIST_SCALE)); - float light = min(v_light, v_light * LIGHT_SCALE - dist_term); - color = texture(u_palette, vec2(palette_index.r, 1.0 - light)).rgb; - } -} diff --git a/assets/shaders/sprite.vert b/assets/shaders/sprite.vert deleted file mode 100644 index 4fbdac6..0000000 --- a/assets/shaders/sprite.vert +++ /dev/null @@ -1,47 +0,0 @@ -uniform mat4 u_modelview; -uniform mat4 u_projection; -uniform vec2 u_atlas_size; -uniform float u_time; -uniform samplerBuffer u_lights; - -in vec3 a_pos; -in vec2 a_atlas_uv; -in vec2 a_tile_uv; -in vec2 a_tile_size; -in float a_local_x; -in int a_num_frames; -in int a_light; - -out float v_dist; -out vec2 v_tile_uv; -flat out vec2 v_atlas_uv; -flat out vec2 v_tile_size; -flat out float v_light; - -const float ANIM_FPS = 8.0 / 35.0; - -void main() { - v_tile_uv = a_tile_uv; - if (a_num_frames == 1) { - v_atlas_uv = a_atlas_uv; - } else { - float frame_index = u_time / ANIM_FPS; - frame_index = floor(mod(frame_index, float(a_num_frames))); - - float atlas_u = a_atlas_uv.x + frame_index * a_tile_size.x; - float n_rows_down = ceil((atlas_u + a_tile_size.x) / u_atlas_size.x) - 1.0; - atlas_u += mod(u_atlas_size.x - a_atlas_uv.x, a_tile_size.x) * n_rows_down; - - float atlas_v = a_atlas_uv.y + n_rows_down * a_tile_size.y; - v_atlas_uv = vec2(atlas_u, atlas_v); - } - v_tile_size = a_tile_size; - - vec3 right = vec3(u_modelview[0][0], u_modelview[1][0], u_modelview[2][0]); - vec3 pos = a_pos + right * a_local_x; - vec4 projected_pos = u_projection * (u_modelview * vec4(pos, 1.0)); - v_light = texelFetch(u_lights, a_light).r; - v_dist = projected_pos.w; - gl_Position = projected_pos; - -} diff --git a/assets/shaders/static.frag b/assets/shaders/static.frag deleted file mode 100644 index c646707..0000000 --- a/assets/shaders/static.frag +++ /dev/null @@ -1,28 +0,0 @@ -precision mediump float; - -out vec3 color; - -uniform vec2 u_atlas_size; -uniform sampler2D u_atlas; -uniform sampler2D u_palette; - -in float v_dist; -in vec2 v_tile_uv; -flat in vec2 v_atlas_uv; -flat in vec2 v_tile_size; -flat in float v_light; - -const float DIST_SCALE = 0.9; -const float LIGHT_SCALE = 2.0; - -void main() { - vec2 uv = mod(v_tile_uv, v_tile_size) + v_atlas_uv; - vec2 palette_index = texture(u_atlas, uv / u_atlas_size).rg; - if (palette_index.g > .5) { // Transparent pixel. - discard; - } else { - float dist_term = min(1.0, 1.0 - DIST_SCALE / (v_dist + DIST_SCALE)); - float light = v_light * LIGHT_SCALE - dist_term; - color = texture(u_palette, vec2(palette_index.r, 1.0 - light)).rgb; - } -} diff --git a/assets/shaders/static.vert b/assets/shaders/static.vert deleted file mode 100644 index 91fa4a6..0000000 --- a/assets/shaders/static.vert +++ /dev/null @@ -1,45 +0,0 @@ -uniform samplerBuffer u_lights; -uniform mat4 u_projection; -uniform mat4 u_modelview; - -uniform vec2 u_atlas_size; -uniform float u_time; - -in vec3 a_pos; -in vec2 a_atlas_uv; -in vec2 a_tile_uv; -in vec2 a_tile_size; -in float a_scroll_rate; -in float a_row_height; -in int a_num_frames; -in int a_light; - -out float v_dist; -out vec2 v_tile_uv; -flat out vec2 v_atlas_uv; -flat out vec2 v_tile_size; -flat out float v_light; - -const float ANIM_FPS = 8.0 / 35.0; - -void main() { - v_tile_uv = a_tile_uv + vec2(u_time * a_scroll_rate, 0.0); - if (a_num_frames == 1) { - v_atlas_uv = a_atlas_uv; - } else { - float frame_index = u_time / ANIM_FPS; - frame_index = floor(mod(frame_index, float(a_num_frames))); - - float atlas_u = a_atlas_uv.x + frame_index * a_tile_size.x; - float n_rows_down = ceil((atlas_u + a_tile_size.x) / u_atlas_size.x) - 1.0; - atlas_u += mod(u_atlas_size.x - a_atlas_uv.x, a_tile_size.x) * n_rows_down; - - float atlas_v = a_atlas_uv.y + n_rows_down * a_row_height; - v_atlas_uv = vec2(atlas_u, atlas_v); - } - v_tile_size = a_tile_size; - vec4 projected_pos = u_projection * u_modelview * vec4(a_pos, 1); - v_dist = projected_pos.w; - v_light = texelFetch(u_lights, a_light).r; - gl_Position = projected_pos; -} diff --git a/engine/src/platform.rs b/engine/src/platform.rs index 9a66cad..5b9e6d5 100644 --- a/engine/src/platform.rs +++ b/engine/src/platform.rs @@ -1,13 +1,6 @@ -#[cfg(target_os = "linux")] -mod internal { - pub const GLSL_VERSION_STRING: &str = "140"; -} - #[cfg(not(target_os = "linux"))] mod internal { pub const GLSL_VERSION_STRING: &str = "330 core"; pub const GL_MAJOR_VERSION: u8 = 3; pub const GL_MINOR_VERSION: u8 = 3; } - -pub use self::internal::*; diff --git a/engine/src/shaders.rs b/engine/src/shaders.rs index 2b76e67..45749f8 100644 --- a/engine/src/shaders.rs +++ b/engine/src/shaders.rs @@ -1,19 +1,14 @@ use super::entities::{Entities, Entity, EntityId}; -use super::errors::{ErrorKind, Result}; -use super::platform; +use super::errors::Result; use super::system::InfallibleSystem; use super::window::Window; use crate::internal_derive::DependenciesFrom; -use failchain::ResultExt; use idcontain::IdMapVec; use log::{debug, error}; use math::{Mat4, Vec2, Vec3}; -use std::fs::File; -use std::io::Read; -use std::io::Result as IoResult; use std::num::NonZeroU64; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; pub const LIGHTS_COUNT: usize = 256; @@ -26,7 +21,6 @@ pub struct ShaderConfig { pub struct Shaders { map: IdMapVec, - root: PathBuf, global_bind_group_layout: wgpu::BindGroupLayout, material_bind_group_layout: wgpu::BindGroupLayout, model_bind_group_layout: wgpu::BindGroupLayout, @@ -42,24 +36,7 @@ impl Shaders { asset_path: &'static str, wgsl_source: &'static str, ) -> Result { - let mut fragment_path = self.root.clone(); - fragment_path.push(asset_path); - - let mut vertex_path = fragment_path.clone(); - fragment_path.set_extension("frag"); - vertex_path.set_extension("vert"); - - let mut fragment_source = format!("#version {}\n", platform::GLSL_VERSION_STRING); - let mut vertex_source = fragment_source.clone(); - - debug!( - "Loading shader {:?} (from {}, fragment={:?} and vert={:?})", - name, asset_path, fragment_path, vertex_path - ); - read_utf8_file(&fragment_path, &mut fragment_source) - .chain_err(|| ErrorKind::ResourceIo("fragment shader", name))?; - read_utf8_file(&vertex_path, &mut vertex_source) - .chain_err(|| ErrorKind::ResourceIo("vertex shader", name))?; + debug!("Loading shader {:?} (from {})", name, asset_path); let shader_module = window .device() @@ -156,7 +133,6 @@ pub struct Shader { #[derive(DependenciesFrom)] pub struct Dependencies<'context> { - config: &'context ShaderConfig, entities: &'context Entities, window: &'context Window, } @@ -298,7 +274,6 @@ impl<'context> InfallibleSystem<'context> for Shaders { Shaders { map: IdMapVec::with_capacity(32), - root: deps.config.root_path.clone(), global_bind_group_layout, material_bind_group_layout, model_bind_group_layout, @@ -325,10 +300,6 @@ impl<'context> InfallibleSystem<'context> for Shaders { } } -fn read_utf8_file(path: &Path, into: &mut String) -> IoResult<()> { - File::open(path)?.read_to_string(into).map(|_| ()) -} - pub trait ShaderVertex { fn desc<'a>() -> wgpu::VertexBufferLayout<'a>; } From 0e45638791f83093e8e632da4a38d5351e1135bb Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 17:06:44 +0100 Subject: [PATCH 37/58] Extract constant for MSAA sample count --- engine/src/renderer.rs | 6 ++++-- engine/src/shaders.rs | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 9bff95f..ff029e1 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -16,6 +16,8 @@ use failchain::ResultExt; use log::{error, info}; use math::{prelude::*, Mat4}; +pub(crate) const MSAA_SAMPLE_COUNT: u32 = 1; + #[derive(DependenciesFrom)] pub struct Dependencies<'context> { pipe: &'context mut RenderPipeline, @@ -54,7 +56,7 @@ impl<'context> System<'context> for Renderer { label: Some("Intermediate attachment"), size: deps.window.size(), mip_level_count: 1, - sample_count: 1, + sample_count: MSAA_SAMPLE_COUNT, dimension: wgpu::TextureDimension::D2, format: deps.window.texture_format(), usage: wgpu::TextureUsages::RENDER_ATTACHMENT, @@ -68,7 +70,7 @@ impl<'context> System<'context> for Renderer { label: Some("Depth atachment"), size: deps.window.size(), mip_level_count: 1, - sample_count: 1, + sample_count: MSAA_SAMPLE_COUNT, dimension: wgpu::TextureDimension::D2, format: wgpu::TextureFormat::Depth32Float, usage: wgpu::TextureUsages::RENDER_ATTACHMENT, diff --git a/engine/src/shaders.rs b/engine/src/shaders.rs index 45749f8..2c7c8a3 100644 --- a/engine/src/shaders.rs +++ b/engine/src/shaders.rs @@ -3,6 +3,7 @@ use super::errors::Result; use super::system::InfallibleSystem; use super::window::Window; use crate::internal_derive::DependenciesFrom; +use crate::renderer::MSAA_SAMPLE_COUNT; use idcontain::IdMapVec; use log::{debug, error}; @@ -85,7 +86,7 @@ impl Shaders { bias: wgpu::DepthBiasState::default(), }), multisample: wgpu::MultisampleState { - count: 1, + count: MSAA_SAMPLE_COUNT, mask: !0, alpha_to_coverage_enabled: false, }, From b944ae04fa9b56ef11e86045e54f80749f6b2124 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 17:10:00 +0100 Subject: [PATCH 38/58] Enable MSAA --- engine/src/renderer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index ff029e1..faece8e 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -16,7 +16,7 @@ use failchain::ResultExt; use log::{error, info}; use math::{prelude::*, Mat4}; -pub(crate) const MSAA_SAMPLE_COUNT: u32 = 1; +pub(crate) const MSAA_SAMPLE_COUNT: u32 = 4; #[derive(DependenciesFrom)] pub struct Dependencies<'context> { From 88f3127a084e46a0ce721b70af498298f29511fa Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 17:11:13 +0100 Subject: [PATCH 39/58] Remove depth stencil from text pipeline --- engine/src/text.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/engine/src/text.rs b/engine/src/text.rs index 7a3a646..0e489a1 100644 --- a/engine/src/text.rs +++ b/engine/src/text.rs @@ -309,13 +309,7 @@ impl<'context> System<'context> for TextRenderer { polygon_mode: wgpu::PolygonMode::Fill, conservative: false, }, - depth_stencil: Some(wgpu::DepthStencilState { - format: wgpu::TextureFormat::Depth32Float, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::Less, - stencil: wgpu::StencilState::default(), - bias: wgpu::DepthBiasState::default(), - }), + depth_stencil: None, multisample: wgpu::MultisampleState { count: 1, mask: !0, From c25da2f1c7696966f7a855de8b1e7d97dfce9079 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 17:12:58 +0100 Subject: [PATCH 40/58] Align MSAA for text pipeline --- engine/src/text.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/src/text.rs b/engine/src/text.rs index 0e489a1..bfe5dc6 100644 --- a/engine/src/text.rs +++ b/engine/src/text.rs @@ -1,5 +1,6 @@ #![cfg_attr(feature = "cargo-clippy", allow(clippy::forget_copy))] +use crate::renderer::MSAA_SAMPLE_COUNT; use crate::ShaderVertex; use super::system::System; @@ -311,7 +312,7 @@ impl<'context> System<'context> for TextRenderer { }, depth_stencil: None, multisample: wgpu::MultisampleState { - count: 1, + count: MSAA_SAMPLE_COUNT, mask: !0, alpha_to_coverage_enabled: false, }, From b930ced07594ec5765c7ccca79150f2bc6f2fecc Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 17:24:43 +0100 Subject: [PATCH 41/58] Fix palette mapping --- game/src/game_shaders.rs | 6 +++--- wad/src/tex.rs | 5 +++-- wad/src/types.rs | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/game/src/game_shaders.rs b/game/src/game_shaders.rs index b7e237c..c08576f 100644 --- a/game/src/game_shaders.rs +++ b/game/src/game_shaders.rs @@ -9,7 +9,7 @@ use engine::{ use log::{error, info}; use math::Vec2; use wad::tex::BoundsLookup; -use wad::types::{COLORMAP_SIZE, PALETTE_SIZE}; +use wad::types::{COLORMAP_SIZE, MAPPED_PALETTE_SIZE}; use wad::util::{is_sky_flat, is_untextured}; use wad::{OpaqueImage as WadOpaqueImage, TransparentImage as WadTransparentImage, WadName}; @@ -128,8 +128,8 @@ impl<'context> Dependencies<'context> { parent, "palette", &palette.pixels, - Vec2::new(COLORMAP_SIZE, palette.pixels.len() / PALETTE_SIZE), - wgpu::TextureFormat::R8Unorm, + Vec2::new(COLORMAP_SIZE, palette.pixels.len() / MAPPED_PALETTE_SIZE), + wgpu::TextureFormat::Rgba8Unorm, ) } diff --git a/wad/src/tex.rs b/wad/src/tex.rs index 42d160c..0b73a72 100644 --- a/wad/src/tex.rs +++ b/wad/src/tex.rs @@ -141,7 +141,7 @@ impl TextureDirectory { colormap_end: usize, ) -> MappedPalette { let num_colormaps = colormap_end - colormap_start; - let mut mapped = vec![0u8; 256 * num_colormaps * 3]; + let mut mapped = vec![0u8; 256 * num_colormaps * 4]; let palette = &self.palettes[palette]; let colormaps_with_offsets = self @@ -154,8 +154,9 @@ impl TextureDirectory { for (offset, colormap) in colormaps_with_offsets { for (i_color, color) in colormap.0.iter().enumerate() { - mapped[i_color * 3 + offset..][..3] + mapped[i_color * 4 + offset..][..3] .copy_from_slice(&palette.0[usize::from(*color) * 3..][..3]); + mapped[i_color * 4 + offset..][3] = 255; } } diff --git a/wad/src/types.rs b/wad/src/types.rs index 1cbe527..e77912f 100644 --- a/wad/src/types.rs +++ b/wad/src/types.rs @@ -169,6 +169,7 @@ pub struct WadTexturePatchRef { } pub const PALETTE_SIZE: usize = 256 * 3; +pub const MAPPED_PALETTE_SIZE: usize = 256 * 4; pub const COLORMAP_SIZE: usize = 256; pub struct Palette(pub [u8; PALETTE_SIZE]); From f906cd101a31f81de8ad67bba2001613205e00e3 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 17:30:12 +0100 Subject: [PATCH 42/58] Implement second sampler for palette --- assets/shaders/sky.wgsl | 8 ++++---- assets/shaders/sprite.wgsl | 8 ++++---- assets/shaders/static.wgsl | 8 ++++---- engine/src/shaders.rs | 6 ++++++ engine/src/uniforms.rs | 21 +++++++++++++++++---- 5 files changed, 35 insertions(+), 16 deletions(-) diff --git a/assets/shaders/sky.wgsl b/assets/shaders/sky.wgsl index 3f16927..fc01187 100644 --- a/assets/shaders/sky.wgsl +++ b/assets/shaders/sky.wgsl @@ -1,7 +1,7 @@ @group(0) @binding(0) var u_viewproj: mat4x4; -// TODO: There should be a separate sampler for the palette, using clamp semantics rather than repeat -@group(0) @binding(1) var u_sampler: sampler; +@group(0) @binding(1) var u_atlas_sampler: sampler; @group(0) @binding(4) var u_palette: texture_2d; +@group(0) @binding(5) var u_palette_sampler: sampler; @group(1) @binding(0) var u_texture: texture_2d; @group(1) @binding(2) var u_tiled_band_size: f32; @@ -37,6 +37,6 @@ fn main_fs(in: VertexOutput) -> @location(0) vec4 { } else if uv.y >= 1.0 { uv.y = 1.0 - uv.y; } - let palette_index = textureSample(u_texture, u_sampler, uv).r; - return vec4(textureSample(u_palette, u_sampler, vec2(palette_index, 0.0)).rgb, 1.0); + let palette_index = textureSample(u_texture, u_atlas_sampler, uv).r; + return vec4(textureSample(u_palette, u_palette_sampler, vec2(palette_index, 0.0)).rgb, 1.0); } diff --git a/assets/shaders/sprite.wgsl b/assets/shaders/sprite.wgsl index da6029c..f803e2c 100644 --- a/assets/shaders/sprite.wgsl +++ b/assets/shaders/sprite.wgsl @@ -1,9 +1,9 @@ @group(0) @binding(0) var u_viewproj: mat4x4; -// TODO: There should be a separate sampler for the palette, using clamp semantics rather than repeat -@group(0) @binding(1) var u_sampler: sampler; +@group(0) @binding(1) var u_atlas_sampler: sampler; @group(0) @binding(2) var u_lights: array; @group(0) @binding(3) var u_time: f32; @group(0) @binding(4) var u_palette: texture_2d; +@group(0) @binding(5) var u_palette_sampler: sampler; @group(1) @binding(0) var u_atlas: texture_2d; @group(1) @binding(1) var u_atlas_size: vec2; @@ -64,12 +64,12 @@ const LIGHT_SCALE: f32 = 2.0; @fragment fn main_fs(in: VertexOutput) -> @location(0) vec4 { let uv = in.v_tile_uv % in.v_tile_size + in.v_atlas_uv; - let palette_index = textureSample(u_atlas, u_sampler, uv / u_atlas_size).rg; + let palette_index = textureSample(u_atlas, u_atlas_sampler, uv / u_atlas_size).rg; if palette_index.g > .5 { // Transparent pixel. discard; } else { let dist_term = min(1.0, 1.0 - DIST_SCALE / (in.v_dist + DIST_SCALE)); let light = min(in.v_light, in.v_light * LIGHT_SCALE - dist_term); - return vec4(textureSample(u_palette, u_sampler, vec2(palette_index.r, 1.0 - light)).rgb, 1.0); + return vec4(textureSample(u_palette, u_palette_sampler, vec2(palette_index.r, 1.0 - light)).rgb, 1.0); } } diff --git a/assets/shaders/static.wgsl b/assets/shaders/static.wgsl index 1dfb056..1a945b0 100644 --- a/assets/shaders/static.wgsl +++ b/assets/shaders/static.wgsl @@ -1,9 +1,9 @@ @group(0) @binding(0) var u_viewproj: mat4x4; -// TODO: There should be a separate sampler for the palette, using clamp semantics rather than repeat -@group(0) @binding(1) var u_sampler: sampler; +@group(0) @binding(1) var u_atlas_sampler: sampler; @group(0) @binding(2) var u_lights: array; @group(0) @binding(3) var u_time: f32; @group(0) @binding(4) var u_palette: texture_2d; +@group(0) @binding(5) var u_palette_sampler: sampler; @group(1) @binding(0) var u_atlas: texture_2d; @group(1) @binding(1) var u_atlas_size: vec2; @@ -62,12 +62,12 @@ const LIGHT_SCALE: f32 = 2.0; @fragment fn main_fs(in: VertexOutput) -> @location(0) vec4 { let uv = in.v_tile_uv % in.v_tile_size + in.v_atlas_uv; - let palette_index = textureSample(u_atlas, u_sampler, uv / u_atlas_size).rg; + let palette_index = textureSample(u_atlas, u_atlas_sampler, uv / u_atlas_size).rg; if palette_index.g > .5 { // Transparent pixel. discard; } else { let dist_term = min(1.0, 1.0 - DIST_SCALE / (in.v_dist + DIST_SCALE)); let light = in.v_light * LIGHT_SCALE - dist_term; - return vec4(textureSample(u_palette, u_sampler, vec2(palette_index.r, 1.0 - light)).rgb, 1.0); + return vec4(textureSample(u_palette, u_palette_sampler, vec2(palette_index.r, 1.0 - light)).rgb, 1.0); } } diff --git a/engine/src/shaders.rs b/engine/src/shaders.rs index 2c7c8a3..871d2d1 100644 --- a/engine/src/shaders.rs +++ b/engine/src/shaders.rs @@ -198,6 +198,12 @@ impl<'context> InfallibleSystem<'context> for Shaders { }, count: None, }, + wgpu::BindGroupLayoutEntry { + binding: 5, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), + count: None, + }, ], }, ); diff --git a/engine/src/uniforms.rs b/engine/src/uniforms.rs index db50ad8..c754bfe 100644 --- a/engine/src/uniforms.rs +++ b/engine/src/uniforms.rs @@ -240,9 +240,8 @@ impl Uniforms { lights_buffer: &wgpu::Buffer, palette: &wgpu::Texture, ) { - // TODO: Create a second sampler for the palette, using clamp address mode. - let sampler = device.create_sampler(&wgpu::SamplerDescriptor { - label: Some("Texture sampler"), + let atlas_sampler = device.create_sampler(&wgpu::SamplerDescriptor { + label: Some("Atlas sampler"), address_mode_u: wgpu::AddressMode::Repeat, address_mode_v: wgpu::AddressMode::Repeat, address_mode_w: wgpu::AddressMode::Repeat, @@ -252,6 +251,16 @@ impl Uniforms { ..Default::default() }); let palette_view = palette.create_view(&Default::default()); + let palette_sampler = device.create_sampler(&wgpu::SamplerDescriptor { + label: Some("Palette sampler"), + 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() + }); self.global_bind_group = Some(device.create_bind_group(&wgpu::BindGroupDescriptor { label: Some("Global bind group"), layout: shaders.global_bind_group_layout(), @@ -262,7 +271,7 @@ impl Uniforms { }, wgpu::BindGroupEntry { binding: 1, - resource: wgpu::BindingResource::Sampler(&sampler), + resource: wgpu::BindingResource::Sampler(&atlas_sampler), }, wgpu::BindGroupEntry { binding: 2, @@ -276,6 +285,10 @@ impl Uniforms { binding: 4, resource: wgpu::BindingResource::TextureView(&palette_view), }, + wgpu::BindGroupEntry { + binding: 5, + resource: wgpu::BindingResource::Sampler(&palette_sampler), + }, ], })) } From 237996244463cae77133c89b09310151f780517e Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 17:32:27 +0100 Subject: [PATCH 43/58] Use nearest sampling rather than linear sampling --- engine/src/uniforms.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/src/uniforms.rs b/engine/src/uniforms.rs index c754bfe..ddc597b 100644 --- a/engine/src/uniforms.rs +++ b/engine/src/uniforms.rs @@ -245,7 +245,7 @@ impl Uniforms { address_mode_u: wgpu::AddressMode::Repeat, address_mode_v: wgpu::AddressMode::Repeat, address_mode_w: wgpu::AddressMode::Repeat, - mag_filter: wgpu::FilterMode::Linear, + mag_filter: wgpu::FilterMode::Nearest, min_filter: wgpu::FilterMode::Nearest, mipmap_filter: wgpu::FilterMode::Nearest, ..Default::default() @@ -256,7 +256,7 @@ impl Uniforms { address_mode_u: wgpu::AddressMode::ClampToEdge, address_mode_v: wgpu::AddressMode::ClampToEdge, address_mode_w: wgpu::AddressMode::ClampToEdge, - mag_filter: wgpu::FilterMode::Linear, + mag_filter: wgpu::FilterMode::Nearest, min_filter: wgpu::FilterMode::Nearest, mipmap_filter: wgpu::FilterMode::Nearest, ..Default::default() From 38e59d6f4e2b0460b35094accf4f29967668e61f Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 17:48:13 +0100 Subject: [PATCH 44/58] Remove padding from vertex structs --- game/src/vertex.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/game/src/vertex.rs b/game/src/vertex.rs index a5aa911..121e2d9 100644 --- a/game/src/vertex.rs +++ b/game/src/vertex.rs @@ -9,7 +9,6 @@ use wgpu::VertexAttribute; #[derive(Copy, Clone, Pod, Zeroable, Default)] pub struct StaticVertex { pub a_pos: [f32; 3], - pub _padding_1: f32, pub a_atlas_uv: [f32; 2], pub a_tile_uv: [f32; 2], pub a_tile_size: [f32; 2], @@ -77,7 +76,6 @@ impl ShaderVertex for StaticVertex { #[derive(Copy, Clone, Pod, Zeroable, Default)] pub struct SpriteVertex { pub a_pos: [f32; 3], - pub _padding_1: f32, pub a_atlas_uv: [f32; 2], pub a_tile_uv: [f32; 2], pub a_tile_size: [f32; 2], @@ -139,7 +137,6 @@ impl ShaderVertex for SpriteVertex { #[derive(Copy, Clone, Pod, Zeroable, Default)] pub struct SkyVertex { pub a_pos: [f32; 3], - pub _padding_1: f32, } impl ShaderVertex for SkyVertex { From 5fcaed66773f5025e35d691702879f7d1b4ab4a1 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 20:18:26 +0100 Subject: [PATCH 45/58] Make model and right buffers available in mesh --- engine/src/meshes.rs | 128 ++++++++++++++++++++++++++----------------- game/src/level.rs | 78 ++++++++++++++++++++------ 2 files changed, 137 insertions(+), 69 deletions(-) diff --git a/engine/src/meshes.rs b/engine/src/meshes.rs index 22bacfc..2dfe3ec 100644 --- a/engine/src/meshes.rs +++ b/engine/src/meshes.rs @@ -23,7 +23,22 @@ impl Meshes { entities: &'a mut Entities, parent: EntityId, name: &'static str, + device: &wgpu::Device, + shaders: &Shaders, ) -> MeshAdder<'a, (), ()> { + let model_transform: [[f32; 4]; 4] = Mat4::identity().into(); + let model_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice(&model_transform), + usage: wgpu::BufferUsages::UNIFORM, + }); + let right_vector = [1.0f32, 0.0, 0.0]; + let right_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: None, + contents: bytemuck::cast_slice(&right_vector), + usage: wgpu::BufferUsages::UNIFORM, + }); + let bind_group = create_bind_group(device, shaders, &model_buffer, &right_buffer); MeshAdder { context: MeshAdderContext { meshes: self, @@ -33,7 +48,9 @@ impl Meshes { }, vertices: (), indices: (), - bind_group: None, + model_buffer, + right_buffer, + bind_group, } } @@ -42,6 +59,8 @@ impl Meshes { InternalMeshData::Owned { ref vertices, ref indices, + model_buffer: _, + right_buffer: _, ref bind_group, } => MeshRef { vertices, @@ -51,6 +70,8 @@ impl Meshes { InternalMeshData::Inherit { vertices_from, ref indices, + model_buffer: _, + right_buffer: _, ref bind_group, } => MeshRef { vertices: match self @@ -73,6 +94,8 @@ impl Meshes { InternalMeshData::Owned { ref mut vertices, ref mut indices, + model_buffer: _, + right_buffer: _, bind_group: _, } => MeshRefMut { vertices: Some(vertices), @@ -81,6 +104,8 @@ impl Meshes { InternalMeshData::Inherit { vertices_from: _vertices_from, ref mut indices, + model_buffer: _, + right_buffer: _, bind_group: _, } => MeshRefMut { vertices: None, @@ -124,7 +149,9 @@ pub struct MeshAdder<'a, VertexDataT, IndexDataT> { context: MeshAdderContext<'a>, vertices: VertexDataT, indices: IndexDataT, - bind_group: Option, + model_buffer: wgpu::Buffer, + right_buffer: wgpu::Buffer, + bind_group: wgpu::BindGroup, } pub struct OwnedVertexData(wgpu::Buffer); @@ -136,22 +163,22 @@ impl<'a, IndexDataT> MeshAdder<'a, (), IndexDataT> { self, vertices: &[VertexT], device: &wgpu::Device, - shaders: &Shaders, ) -> Result> where VertexT: Pod + Send + 'static, { - let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: None, contents: bytemuck::cast_slice(vertices), usage: wgpu::BufferUsages::VERTEX, }); - let bind_group = create_bind_group(device, shaders); Ok(MeshAdder { - vertices: OwnedVertexData(buffer), - indices: self.indices, + vertices: OwnedVertexData(vertex_buffer), context: self.context, - bind_group: Some(bind_group), + indices: self.indices, + model_buffer: self.model_buffer, + right_buffer: self.right_buffer, + bind_group: self.bind_group, }) } @@ -159,31 +186,26 @@ impl<'a, IndexDataT> MeshAdder<'a, (), IndexDataT> { self, vertices: &[VertexT], device: &wgpu::Device, - shaders: &Shaders, ) -> Result> where VertexT: Pod + Send + 'static, { - let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: None, contents: bytemuck::cast_slice(vertices), usage: wgpu::BufferUsages::VERTEX, }); - let bind_group = create_bind_group(device, shaders); Ok(MeshAdder { - vertices: OwnedVertexData(buffer), - indices: self.indices, + vertices: OwnedVertexData(vertex_buffer), context: self.context, - bind_group: Some(bind_group), + indices: self.indices, + model_buffer: self.model_buffer, + right_buffer: self.right_buffer, + bind_group: self.bind_group, }) } - pub fn shared( - self, - vertices_from: MeshId, - device: &wgpu::Device, - shaders: &Shaders, - ) -> MeshAdder<'a, SharedVertexData, IndexDataT> { + pub fn shared(self, vertices_from: MeshId) -> MeshAdder<'a, SharedVertexData, IndexDataT> { // TODO(cristicbz): If parent comes from a different `Meshes` object, the assertion that // the parent is in the map is in incorrect. let mut owner = vertices_from; @@ -197,12 +219,13 @@ impl<'a, IndexDataT> MeshAdder<'a, (), IndexDataT> { { owner = vertices_from; } - let bind_group = create_bind_group(device, shaders); MeshAdder { vertices: SharedVertexData(owner), - indices: self.indices, context: self.context, - bind_group: Some(bind_group), + indices: self.indices, + model_buffer: self.model_buffer, + right_buffer: self.right_buffer, + bind_group: self.bind_group, } } } @@ -212,19 +235,19 @@ impl<'a, VertexDataT> MeshAdder<'a, VertexDataT, ()> { self, indices: &[u32], device: &wgpu::Device, - shaders: &Shaders, ) -> Result> { - let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: None, contents: bytemuck::cast_slice(indices), usage: wgpu::BufferUsages::INDEX, }); - let bind_group = create_bind_group(device, shaders); Ok(MeshAdder { - indices: IndexData(buffer), - vertices: self.vertices, + indices: IndexData(index_buffer), context: self.context, - bind_group: Some(bind_group), + vertices: self.vertices, + model_buffer: self.model_buffer, + right_buffer: self.right_buffer, + bind_group: self.bind_group, }) } @@ -232,19 +255,19 @@ impl<'a, VertexDataT> MeshAdder<'a, VertexDataT, ()> { self, indices: &[u32], device: &wgpu::Device, - shaders: &Shaders, ) -> Result> { - let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: None, contents: bytemuck::cast_slice(indices), usage: wgpu::BufferUsages::INDEX, }); - let bind_group = create_bind_group(device, shaders); Ok(MeshAdder { - indices: IndexData(buffer), - vertices: self.vertices, + indices: IndexData(index_buffer), context: self.context, - bind_group: Some(bind_group), + vertices: self.vertices, + model_buffer: self.model_buffer, + right_buffer: self.right_buffer, + bind_group: self.bind_group, }) } } @@ -254,7 +277,9 @@ impl<'a> MeshAdder<'a, OwnedVertexData, ()> { self.context.add(InternalMeshData::Owned { vertices: self.vertices.0, indices: None, - bind_group: self.bind_group.expect("missing bind group"), + model_buffer: self.model_buffer, + right_buffer: self.right_buffer, + bind_group: self.bind_group, }) } } @@ -264,7 +289,9 @@ impl<'a> MeshAdder<'a, SharedVertexData, IndexData> { self.context.add(InternalMeshData::Inherit { vertices_from: self.vertices.0, indices: self.indices.0, - bind_group: self.bind_group.expect("missing bind group"), + model_buffer: self.model_buffer, + right_buffer: self.right_buffer, + bind_group: self.bind_group, }) } } @@ -274,24 +301,19 @@ impl<'a> MeshAdder<'a, OwnedVertexData, IndexData> { self.context.add(InternalMeshData::Owned { vertices: self.vertices.0, indices: Some(self.indices.0), - bind_group: self.bind_group.expect("missing bind group"), + model_buffer: self.model_buffer, + right_buffer: self.right_buffer, + bind_group: self.bind_group, }) } } -fn create_bind_group(device: &wgpu::Device, shaders: &Shaders) -> wgpu::BindGroup { - let model_transform: [[f32; 4]; 4] = Mat4::identity().into(); - let model_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: None, - contents: bytemuck::cast_slice(&model_transform), - usage: wgpu::BufferUsages::UNIFORM, - }); - let right_vector = [1.0f32, 0.0, 0.0]; - let right_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: None, - contents: bytemuck::cast_slice(&right_vector), - usage: wgpu::BufferUsages::UNIFORM, - }); +fn create_bind_group( + device: &wgpu::Device, + shaders: &Shaders, + model_buffer: &wgpu::Buffer, + right_buffer: &wgpu::Buffer, +) -> wgpu::BindGroup { device.create_bind_group(&wgpu::BindGroupDescriptor { label: None, layout: shaders.model_bind_group_layout(), @@ -350,11 +372,15 @@ enum InternalMeshData { Owned { vertices: wgpu::Buffer, indices: Option, + model_buffer: wgpu::Buffer, + right_buffer: wgpu::Buffer, bind_group: wgpu::BindGroup, }, Inherit { vertices_from: MeshId, indices: wgpu::Buffer, + model_buffer: wgpu::Buffer, + right_buffer: wgpu::Buffer, bind_group: wgpu::BindGroup, }, } diff --git a/game/src/level.rs b/game/src/level.rs index 8a64c70..030e398 100644 --- a/game/src/level.rs +++ b/game/src/level.rs @@ -426,20 +426,38 @@ impl<'a> Builder<'a> { info!("Creating static meshes and models..."); let global_static_mesh = deps .meshes - .add(deps.entities, root, "global_world_static_mesh") - .immutable(&builder.static_vertices, deps.window.device(), deps.shaders)? + .add( + deps.entities, + root, + "global_world_static_mesh", + deps.window.device(), + deps.shaders, + ) + .immutable(&builder.static_vertices, deps.window.device())? .build_unindexed()?; let global_sky_mesh = deps .meshes - .add(deps.entities, root, "global_world_sky_mesh") - .immutable(&builder.sky_vertices, deps.window.device(), deps.shaders)? + .add( + deps.entities, + root, + "global_world_sky_mesh", + deps.window.device(), + deps.shaders, + ) + .immutable(&builder.sky_vertices, deps.window.device())? .build_unindexed()?; let global_decor_mesh = deps .meshes - .add(deps.entities, root, "global_world_decor_mesh") - .immutable(&builder.decor_vertices, deps.window.device(), deps.shaders)? + .add( + deps.entities, + root, + "global_world_decor_mesh", + deps.window.device(), + deps.shaders, + ) + .immutable(&builder.decor_vertices, deps.window.device())? .build_unindexed()?; for (id, indices) in &builder.object_indices { @@ -448,9 +466,15 @@ impl<'a> Builder<'a> { let entity = deps.entities.add(object, "flats")?; let mesh = deps .meshes - .add(deps.entities, entity, "object_flats_mesh") - .shared(global_static_mesh, deps.window.device(), deps.shaders) - .immutable_indices(&indices.flat, deps.window.device(), deps.shaders)? + .add( + deps.entities, + entity, + "object_flats_mesh", + deps.window.device(), + deps.shaders, + ) + .shared(global_static_mesh) + .immutable_indices(&indices.flat, deps.window.device())? .build()?; deps.transforms.attach_identity(entity); deps.render @@ -461,9 +485,15 @@ impl<'a> Builder<'a> { let entity = deps.entities.add(object, "walls")?; let mesh = deps .meshes - .add(deps.entities, entity, "object_walls_mesh") - .shared(global_static_mesh, deps.window.device(), deps.shaders) - .immutable_indices(&indices.wall, deps.window.device(), deps.shaders)? + .add( + deps.entities, + entity, + "object_walls_mesh", + deps.window.device(), + deps.shaders, + ) + .shared(global_static_mesh) + .immutable_indices(&indices.wall, deps.window.device())? .build()?; deps.transforms.attach_identity(entity); deps.render @@ -474,9 +504,15 @@ impl<'a> Builder<'a> { let entity = deps.entities.add(object, "decor")?; let mesh = deps .meshes - .add(deps.entities, entity, "object_decor_mesh") - .shared(global_decor_mesh, deps.window.device(), deps.shaders) - .immutable_indices(&indices.decor, deps.window.device(), deps.shaders)? + .add( + deps.entities, + entity, + "object_decor_mesh", + deps.window.device(), + deps.shaders, + ) + .shared(global_decor_mesh) + .immutable_indices(&indices.decor, deps.window.device())? .build()?; deps.transforms.attach_identity(entity); deps.render @@ -487,9 +523,15 @@ impl<'a> Builder<'a> { let entity = deps.entities.add(object, "sky")?; let mesh = deps .meshes - .add(deps.entities, entity, "object_sky_mesh") - .shared(global_sky_mesh, deps.window.device(), deps.shaders) - .immutable_indices(&indices.sky, deps.window.device(), deps.shaders)? + .add( + deps.entities, + entity, + "object_sky_mesh", + deps.window.device(), + deps.shaders, + ) + .shared(global_sky_mesh) + .immutable_indices(&indices.sky, deps.window.device())? .build()?; deps.transforms.attach_identity(entity); deps.render From 4b8728697555cbe1e1035922e58572c0c33d36d8 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 20:47:14 +0100 Subject: [PATCH 46/58] Update model and right in renderer --- engine/src/meshes.rs | 37 +++++++++++++++++++++++++++++-------- engine/src/renderer.rs | 8 +++++++- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/engine/src/meshes.rs b/engine/src/meshes.rs index 2dfe3ec..d6a0087 100644 --- a/engine/src/meshes.rs +++ b/engine/src/meshes.rs @@ -4,10 +4,10 @@ use super::entities::{Entities, Entity, EntityId}; use super::errors::Result; use super::system::InfallibleSystem; use bytemuck::Pod; -use cgmath::SquareMatrix; +use cgmath::{Quaternion, SquareMatrix, Vector3}; use idcontain::IdMapVec; use log::{debug, error}; -use math::Mat4; +use math::{Decomposed, Mat4}; use wgpu::util::DeviceExt; #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Copy, Clone)] @@ -30,13 +30,13 @@ impl Meshes { let model_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: None, contents: bytemuck::cast_slice(&model_transform), - usage: wgpu::BufferUsages::UNIFORM, + usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, }); let right_vector = [1.0f32, 0.0, 0.0]; let right_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: None, contents: bytemuck::cast_slice(&right_vector), - usage: wgpu::BufferUsages::UNIFORM, + usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, }); let bind_group = create_bind_group(device, shaders, &model_buffer, &right_buffer); MeshAdder { @@ -59,19 +59,21 @@ impl Meshes { InternalMeshData::Owned { ref vertices, ref indices, - model_buffer: _, - right_buffer: _, + ref model_buffer, + ref right_buffer, ref bind_group, } => MeshRef { vertices, indices: indices.as_ref(), + model_buffer, + right_buffer, bind_group, }, InternalMeshData::Inherit { vertices_from, ref indices, - model_buffer: _, - right_buffer: _, + ref model_buffer, + ref right_buffer, ref bind_group, } => MeshRef { vertices: match self @@ -84,6 +86,8 @@ impl Meshes { _ => panic!("unowned mesh in stored vertices_from"), }, indices: Some(indices), + model_buffer, + right_buffer, bind_group, }, }) @@ -123,6 +127,8 @@ pub struct MeshRefMut<'a> { pub struct MeshRef<'a> { vertices: &'a wgpu::Buffer, indices: Option<&'a wgpu::Buffer>, + model_buffer: &'a wgpu::Buffer, + right_buffer: &'a wgpu::Buffer, bind_group: &'a wgpu::BindGroup, } @@ -142,6 +148,21 @@ impl<'a> MeshRef<'a> { pub(crate) fn bind_group(&self) -> &'a wgpu::BindGroup { self.bind_group } + + pub(crate) fn update_model( + &self, + transform: Decomposed, Quaternion>, + queue: &wgpu::Queue, + ) { + let matrix: Mat4 = transform.into(); + let matrix: [[f32; 4]; 4] = matrix.into(); + queue.write_buffer(self.model_buffer, 0, bytemuck::cast_slice(&matrix)); + } + + pub(crate) fn update_right(&self, right: Vector3, queue: &wgpu::Queue) { + let vector: [f32; 3] = right.into(); + queue.write_buffer(self.right_buffer, 0, bytemuck::cast_slice(&vector)); + } } #[must_use] diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index faece8e..c8f1395 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -12,6 +12,7 @@ use super::uniforms::Uniforms; use super::window::Window; use crate::internal_derive::DependenciesFrom; use crate::ErrorKind; +use cgmath::Vector3; use failchain::ResultExt; use log::{error, info}; use math::{prelude::*, Mat4}; @@ -174,7 +175,12 @@ impl<'context> System<'context> for Renderer { continue; }; - // TODO: Set u_right on the mesh + if let Some(transform) = deps.transforms.get_absolute(entity) { + mesh.update_model(*transform, deps.window.queue()); + let right = view_transform + .transform_vector(transform.transform_vector(Vector3::new(1.0, 0.0, 0.0))); + mesh.update_right(right, deps.window.queue()); + } let material = if let Some(material) = deps.materials.get(deps.shaders, material) { material From 0520028fbb06dbbac641b713a5212f9cf33055ad Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 20:50:51 +0100 Subject: [PATCH 47/58] Update model and right in renderer --- engine/src/renderer.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index c8f1395..e6dfee4 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -180,6 +180,9 @@ impl<'context> System<'context> for Renderer { let right = view_transform .transform_vector(transform.transform_vector(Vector3::new(1.0, 0.0, 0.0))); mesh.update_right(right, deps.window.queue()); + } else { + let right = view_transform.transform_vector(Vector3::new(1.0, 0.0, 0.0)); + mesh.update_right(right, deps.window.queue()); } let material = if let Some(material) = deps.materials.get(deps.shaders, material) { From 2f46b40c2d00264821dac0d556d51dc9fce1e757 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 21:18:21 +0100 Subject: [PATCH 48/58] Fix sprite rendering --- engine/src/renderer.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index e6dfee4..b8bb3db 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -175,10 +175,13 @@ impl<'context> System<'context> for Renderer { continue; }; - if let Some(transform) = deps.transforms.get_absolute(entity) { - mesh.update_model(*transform, deps.window.queue()); + if let Some(model_transform) = deps.transforms.get_absolute(entity) { + mesh.update_model(*model_transform, deps.window.queue()); let right = view_transform - .transform_vector(transform.transform_vector(Vector3::new(1.0, 0.0, 0.0))); + .inverse_transform_vector( + model_transform.transform_vector(Vector3::new(1.0, 0.0, 0.0)), + ) + .expect("view transform should be invertible"); mesh.update_right(right, deps.window.queue()); } else { let right = view_transform.transform_vector(Vector3::new(1.0, 0.0, 0.0)); From 52c9ee58f06dc6f5c5c728a24695de46807585f6 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Sun, 28 Jan 2024 21:29:42 +0100 Subject: [PATCH 49/58] Simplify logic --- engine/src/renderer.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index b8bb3db..5a5ed48 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -175,18 +175,16 @@ impl<'context> System<'context> for Renderer { continue; }; - if let Some(model_transform) = deps.transforms.get_absolute(entity) { + let right = if let Some(model_transform) = deps.transforms.get_absolute(entity) { mesh.update_model(*model_transform, deps.window.queue()); - let right = view_transform - .inverse_transform_vector( - model_transform.transform_vector(Vector3::new(1.0, 0.0, 0.0)), - ) - .expect("view transform should be invertible"); - mesh.update_right(right, deps.window.queue()); + model_transform.transform_vector(Vector3::new(1.0, 0.0, 0.0)) } else { - let right = view_transform.transform_vector(Vector3::new(1.0, 0.0, 0.0)); - mesh.update_right(right, deps.window.queue()); - } + Vector3::new(1.0, 0.0, 0.0) + }; + let right = view_transform + .inverse_transform_vector(right) + .expect("view transform should be invertible"); + mesh.update_right(right, deps.window.queue()); let material = if let Some(material) = deps.materials.get(deps.shaders, material) { material From ebab1e1e9ceceaa37ab8b2afc8a6fd9f7919d76d Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Mon, 29 Jan 2024 11:28:46 +0100 Subject: [PATCH 50/58] Eliminate extra matrix inversion --- engine/src/renderer.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 5a5ed48..12057df 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -103,15 +103,19 @@ impl<'context> System<'context> for Renderer { }; // Compute view transform by inverting the camera entity transform. - let view_transform = if let Some(transform) = deps.transforms.get_absolute(camera_id) { - transform - .inverse_transform() - .expect("singular view transform") - } else { - info!("Camera transform missing, disabling renderer."); - pipe.camera = None; - return Ok(()); - }; + let (camera_transform, view_transform) = + if let Some(transform) = deps.transforms.get_absolute(camera_id) { + ( + transform, + transform + .inverse_transform() + .expect("singular view transform"), + ) + } else { + info!("Camera transform missing, disabling renderer."); + pipe.camera = None; + return Ok(()); + }; let view_matrix: Mat4 = view_transform.into(); // Set view-projection. @@ -181,9 +185,7 @@ impl<'context> System<'context> for Renderer { } else { Vector3::new(1.0, 0.0, 0.0) }; - let right = view_transform - .inverse_transform_vector(right) - .expect("view transform should be invertible"); + let right = camera_transform.transform_vector(right); mesh.update_right(right, deps.window.queue()); let material = if let Some(material) = deps.materials.get(deps.shaders, material) { From b854329250e5beafc160417c21ab33294a1e8b32 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Mon, 29 Jan 2024 11:38:18 +0100 Subject: [PATCH 51/58] Remove unneeded calls --- game/src/game_shaders.rs | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/game/src/game_shaders.rs b/game/src/game_shaders.rs index c08576f..775be32 100644 --- a/game/src/game_shaders.rs +++ b/game/src/game_shaders.rs @@ -2,9 +2,8 @@ use crate::vertex::{SkyVertex, SpriteVertex, StaticVertex}; use super::wad_system::WadSystem; use engine::{ - DependenciesFrom, Entities, EntityId, Error, FloatUniformId, MaterialId, Materials, - RenderPipeline, Result, ShaderId, ShaderVertex, Shaders, System, Tick, Uniforms, Window, - LIGHTS_COUNT, + DependenciesFrom, Entities, EntityId, Error, FloatUniformId, MaterialId, Materials, Result, + ShaderId, ShaderVertex, Shaders, System, Tick, Uniforms, Window, LIGHTS_COUNT, }; use log::{error, info}; use math::Vec2; @@ -46,7 +45,6 @@ pub struct Dependencies<'context> { entities: &'context mut Entities, shaders: &'context mut Shaders, uniforms: &'context mut Uniforms, - render: &'context mut RenderPipeline, materials: &'context mut Materials, wad: &'context mut WadSystem, @@ -179,9 +177,6 @@ impl<'context> Dependencies<'context> { } fn load_level(&mut self, globals: &Globals, parent: EntityId) -> Result { - let modelview = self.render.modelview(); - let projection = self.render.projection(); - let flats_atlas = self.load_flats_atlas(parent)?; let flats_material = self .materials @@ -192,9 +187,6 @@ impl<'context> Dependencies<'context> { "flats_material", )? .with_atlas(&flats_atlas.texture, self.window.device(), self.shaders) - .add_uniform("u_modelview", modelview) - .add_uniform("u_projection", projection) - .add_uniform("u_time", globals.time) .id(); let walls_atlas = self.load_walls_atlas(parent)?; @@ -207,9 +199,6 @@ impl<'context> Dependencies<'context> { "walls_material", )? .with_atlas(&walls_atlas.texture, self.window.device(), self.shaders) - .add_uniform("u_modelview", modelview) - .add_uniform("u_projection", projection) - .add_uniform("u_time", globals.time) .id(); let sky_uniforms = self.load_sky_uniforms(parent)?; @@ -222,8 +211,6 @@ impl<'context> Dependencies<'context> { self.window.device(), self.shaders, ) - .add_uniform("u_modelview", modelview) - .add_uniform("u_projection", projection) .id(); let decor_atlas = self.load_decor_atlas(parent)?; @@ -236,9 +223,6 @@ impl<'context> Dependencies<'context> { "decor_material", )? .with_atlas(&decor_atlas.texture, self.window.device(), self.shaders) - .add_uniform("u_modelview", modelview) - .add_uniform("u_projection", projection) - .add_uniform("u_time", globals.time) .id(); Ok(LevelMaterials { From f319e06f0fc6ad52f789483ec38865b3fd203a25 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Mon, 29 Jan 2024 15:27:43 +0100 Subject: [PATCH 52/58] Enforce positive remainder in shader --- assets/shaders/static.wgsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/shaders/static.wgsl b/assets/shaders/static.wgsl index 1a945b0..8cbb7a6 100644 --- a/assets/shaders/static.wgsl +++ b/assets/shaders/static.wgsl @@ -61,7 +61,7 @@ const LIGHT_SCALE: f32 = 2.0; @fragment fn main_fs(in: VertexOutput) -> @location(0) vec4 { - let uv = in.v_tile_uv % in.v_tile_size + in.v_atlas_uv; + let uv = ((in.v_tile_uv % in.v_tile_size) + in.v_tile_size) % in.v_tile_size + in.v_atlas_uv; let palette_index = textureSample(u_atlas, u_atlas_sampler, uv / u_atlas_size).rg; if palette_index.g > .5 { // Transparent pixel. discard; From c008fbfd0895465776648fc076cfb0cab1b5556c Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Mon, 29 Jan 2024 15:49:03 +0100 Subject: [PATCH 53/58] Update time uniform --- engine/src/uniforms.rs | 12 +++++++++++- game/src/game_shaders.rs | 6 ++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/engine/src/uniforms.rs b/engine/src/uniforms.rs index ddc597b..8536c88 100644 --- a/engine/src/uniforms.rs +++ b/engine/src/uniforms.rs @@ -50,6 +50,7 @@ pub struct Uniforms { global_bind_group: Option, projection_buffer: wgpu::Buffer, time_buffer: wgpu::Buffer, + time: f32, } impl Uniforms { @@ -64,6 +65,7 @@ impl Uniforms { global_bind_group: _, projection_buffer: _, time_buffer: _, + time: _, } = *self; for &entity in entities.last_removed() { if texture2ds.remove(entity).is_some() { @@ -81,6 +83,11 @@ impl Uniforms { } } + pub fn increment_time(&mut self, timestep: f32, queue: &wgpu::Queue) { + self.time += timestep; + queue.write_buffer(&self.time_buffer, 0, bytemuck::cast_slice(&[self.time])); + } + pub fn add_float( &mut self, entities: &mut Entities, @@ -375,12 +382,13 @@ impl<'context> InfallibleSystem<'context> for Uniforms { contents: bytemuck::cast_slice(&projection), usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, }); + let time = 0.0; let time_buffer = deps.window .device() .create_buffer_init(&wgpu::util::BufferInitDescriptor { label: Some("Time buffer"), - contents: bytemuck::cast_slice(&[0.0f32]), + contents: bytemuck::cast_slice(&[time]), usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, }); Uniforms { @@ -390,6 +398,7 @@ impl<'context> InfallibleSystem<'context> for Uniforms { vec2fs: IdMapVec::with_capacity(32), global_bind_group: None, projection_buffer, + time, time_buffer, } } @@ -405,6 +414,7 @@ impl<'context> InfallibleSystem<'context> for Uniforms { global_bind_group: _, projection_buffer: _, time_buffer: _, + time: _, } = *self; for &entity in deps.entities.last_removed() { if texture2ds.remove(entity).is_some() { diff --git a/game/src/game_shaders.rs b/game/src/game_shaders.rs index 775be32..53759a4 100644 --- a/game/src/game_shaders.rs +++ b/game/src/game_shaders.rs @@ -85,10 +85,8 @@ impl<'context> System<'context> for GameShaders { .get_float_mut(self.globals.time) .expect("missing time") = 0.0; } else { - *deps - .uniforms - .get_float_mut(self.globals.time) - .expect("missing time") += deps.tick.timestep(); + deps.uniforms + .increment_time(deps.tick.timestep(), deps.window.queue()); } Ok(()) From 5fdfd4746839947beb2554831c805e7253757de0 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Mon, 29 Jan 2024 16:16:12 +0100 Subject: [PATCH 54/58] Fix lighting and use correct time when updating lights --- assets/shaders/sprite.wgsl | 10 +++++----- assets/shaders/static.wgsl | 10 +++++----- engine/src/uniforms.rs | 4 ++++ game/src/level.rs | 5 +---- game/src/lights.rs | 4 ++-- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/assets/shaders/sprite.wgsl b/assets/shaders/sprite.wgsl index f803e2c..73e1803 100644 --- a/assets/shaders/sprite.wgsl +++ b/assets/shaders/sprite.wgsl @@ -1,6 +1,6 @@ @group(0) @binding(0) var u_viewproj: mat4x4; @group(0) @binding(1) var u_atlas_sampler: sampler; -@group(0) @binding(2) var u_lights: array; +@group(0) @binding(2) var u_lights: array; @group(0) @binding(3) var u_time: f32; @group(0) @binding(4) var u_palette: texture_2d; @group(0) @binding(5) var u_palette_sampler: sampler; @@ -52,14 +52,14 @@ fn main_vs(in: VertexInput) -> VertexOutput { let pos = in.a_pos + u_right * in.a_local_x; let projected_pos = u_viewproj * (u_model * vec4(pos, 1.0)); - out.v_light = f32(u_lights[in.a_light]); + out.v_light = u_lights[in.a_light]; out.v_dist = projected_pos.w; out.clip_position = projected_pos; return out; } -const DIST_SCALE: f32 = 1.0; -const LIGHT_SCALE: f32 = 2.0; +const DIST_SCALE: f32 = 1.5; +const LIGHT_SCALE: f32 = 1.75; @fragment fn main_fs(in: VertexOutput) -> @location(0) vec4 { @@ -70,6 +70,6 @@ fn main_fs(in: VertexOutput) -> @location(0) vec4 { } else { let dist_term = min(1.0, 1.0 - DIST_SCALE / (in.v_dist + DIST_SCALE)); let light = min(in.v_light, in.v_light * LIGHT_SCALE - dist_term); - return vec4(textureSample(u_palette, u_palette_sampler, vec2(palette_index.r, 1.0 - light)).rgb, 1.0); + return vec4(textureSample(u_palette, u_palette_sampler, vec2(palette_index.r, 0.0)).rgb * light, 1.0); } } diff --git a/assets/shaders/static.wgsl b/assets/shaders/static.wgsl index 8cbb7a6..d73e7be 100644 --- a/assets/shaders/static.wgsl +++ b/assets/shaders/static.wgsl @@ -1,6 +1,6 @@ @group(0) @binding(0) var u_viewproj: mat4x4; @group(0) @binding(1) var u_atlas_sampler: sampler; -@group(0) @binding(2) var u_lights: array; +@group(0) @binding(2) var u_lights: array; @group(0) @binding(3) var u_time: f32; @group(0) @binding(4) var u_palette: texture_2d; @group(0) @binding(5) var u_palette_sampler: sampler; @@ -51,13 +51,13 @@ fn main_vs(in: VertexInput) -> VertexOutput { out.v_tile_size = in.a_tile_size; let projected_pos = u_viewproj * u_model * vec4(in.a_pos, 1); out.v_dist = projected_pos.w; - out.v_light = f32(u_lights[in.a_light]); + out.v_light = u_lights[in.a_light]; out.clip_position = projected_pos; return out; } -const DIST_SCALE: f32 = 0.9; -const LIGHT_SCALE: f32 = 2.0; +const DIST_SCALE: f32 = 1.5; +const LIGHT_SCALE: f32 = 1.75; @fragment fn main_fs(in: VertexOutput) -> @location(0) vec4 { @@ -68,6 +68,6 @@ fn main_fs(in: VertexOutput) -> @location(0) vec4 { } else { let dist_term = min(1.0, 1.0 - DIST_SCALE / (in.v_dist + DIST_SCALE)); let light = in.v_light * LIGHT_SCALE - dist_term; - return vec4(textureSample(u_palette, u_palette_sampler, vec2(palette_index.r, 1.0 - light)).rgb, 1.0); + return vec4(textureSample(u_palette, u_palette_sampler, vec2(palette_index.r, 0.0)).rgb * light, 1.0); } } diff --git a/engine/src/uniforms.rs b/engine/src/uniforms.rs index 8536c88..2f5756e 100644 --- a/engine/src/uniforms.rs +++ b/engine/src/uniforms.rs @@ -88,6 +88,10 @@ impl Uniforms { queue.write_buffer(&self.time_buffer, 0, bytemuck::cast_slice(&[self.time])); } + pub fn time(&self) -> f32 { + self.time + } + pub fn add_float( &mut self, entities: &mut Entities, diff --git a/game/src/level.rs b/game/src/level.rs index 030e398..66a09a2 100644 --- a/game/src/level.rs +++ b/game/src/level.rs @@ -255,10 +255,7 @@ impl<'context> System<'context> for Level { } self.removed.clear(); - let time = *deps - .uniforms - .get_float_mut(deps.game_shaders.time()) - .expect("missing time"); + let time = deps.uniforms.time(); let light_infos = &mut self.lights; deps.uniforms.map_buffer( deps.game_shaders.lights_buffer(), diff --git a/game/src/lights.rs b/game/src/lights.rs index 67a9677..38054e6 100644 --- a/game/src/lights.rs +++ b/game/src/lights.rs @@ -24,9 +24,9 @@ impl Lights { }) as u8 } - pub fn fill_buffer_at(&mut self, time: f32, buffer: &mut [u32]) { + pub fn fill_buffer_at(&mut self, time: f32, buffer: &mut [f32]) { for (value, info) in buffer.iter_mut().zip(self.lights.iter()) { - *value = (clamp(light_level_at(info, time)) * 255.0) as u32; + *value = clamp(light_level_at(info, time)); } } } From 6c205246b300acd04c0b93d8a2778b2273598540 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Mon, 29 Jan 2024 16:30:17 +0100 Subject: [PATCH 55/58] Fix text rendering --- engine/src/renderer.rs | 6 +----- engine/src/text.rs | 10 +++++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/engine/src/renderer.rs b/engine/src/renderer.rs index 12057df..561b84e 100644 --- a/engine/src/renderer.rs +++ b/engine/src/renderer.rs @@ -11,9 +11,7 @@ use super::transforms::Transforms; use super::uniforms::Uniforms; use super::window::Window; use crate::internal_derive::DependenciesFrom; -use crate::ErrorKind; use cgmath::Vector3; -use failchain::ResultExt; use log::{error, info}; use math::{prelude::*, Mat4}; @@ -217,9 +215,7 @@ impl<'context> System<'context> for Renderer { } // Render text. TODO(cristicbz): text should render itself :( - deps.text - .render(&mut encoder, &self.view) - .chain_err(|| ErrorKind::System("render bypass", TextRenderer::debug_name()))?; + deps.text.render(&mut encoder, &self.view, &view); deps.window.queue().submit([encoder.finish()]); surface_texture.present(); diff --git a/engine/src/text.rs b/engine/src/text.rs index bfe5dc6..e2055d3 100644 --- a/engine/src/text.rs +++ b/engine/src/text.rs @@ -134,11 +134,12 @@ impl TextRenderer { &self, encoder: &mut wgpu::CommandEncoder, view: &wgpu::TextureView, - ) -> Result<()> { + target_view: &wgpu::TextureView, + ) { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("Text render pass"), color_attachments: &[Some(wgpu::RenderPassColorAttachment { - resolve_target: None, + resolve_target: Some(target_view), ops: wgpu::Operations { load: wgpu::LoadOp::Load, store: wgpu::StoreOp::Store, @@ -156,7 +157,6 @@ impl TextRenderer { render_pass.set_bind_group(0, &text.bind_group, &[]); render_pass.draw(0..4, 0..1); } - Ok(()) } fn rasterise(&mut self, text: &str, padding: u32) -> (u32, u32) { @@ -302,7 +302,7 @@ impl<'context> System<'context> for TextRenderer { buffers: &[TextVertex::desc()], }, primitive: wgpu::PrimitiveState { - topology: wgpu::PrimitiveTopology::TriangleList, + topology: wgpu::PrimitiveTopology::TriangleStrip, strip_index_format: None, front_face: wgpu::FrontFace::Ccw, cull_mode: Some(wgpu::Face::Back), @@ -321,7 +321,7 @@ impl<'context> System<'context> for TextRenderer { entry_point: "main_fs", targets: &[Some(wgpu::ColorTargetState { format: window.texture_format(), - blend: Some(wgpu::BlendState::REPLACE), + blend: Some(wgpu::BlendState::ALPHA_BLENDING), write_mask: wgpu::ColorWrites::all(), })], }), From 67723dbe6687bd10667ba3a802d93ae7a6f33c91 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Mon, 29 Jan 2024 16:35:43 +0100 Subject: [PATCH 56/58] Use Srgb colorspace --- assets/shaders/sprite.wgsl | 4 ++-- assets/shaders/static.wgsl | 4 ++-- game/src/game_shaders.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/shaders/sprite.wgsl b/assets/shaders/sprite.wgsl index 73e1803..80b0903 100644 --- a/assets/shaders/sprite.wgsl +++ b/assets/shaders/sprite.wgsl @@ -58,8 +58,8 @@ fn main_vs(in: VertexInput) -> VertexOutput { return out; } -const DIST_SCALE: f32 = 1.5; -const LIGHT_SCALE: f32 = 1.75; +const DIST_SCALE: f32 = 0.9; +const LIGHT_SCALE: f32 = 2.0; @fragment fn main_fs(in: VertexOutput) -> @location(0) vec4 { diff --git a/assets/shaders/static.wgsl b/assets/shaders/static.wgsl index d73e7be..5c4ea02 100644 --- a/assets/shaders/static.wgsl +++ b/assets/shaders/static.wgsl @@ -56,8 +56,8 @@ fn main_vs(in: VertexInput) -> VertexOutput { return out; } -const DIST_SCALE: f32 = 1.5; -const LIGHT_SCALE: f32 = 1.75; +const DIST_SCALE: f32 = 0.9; +const LIGHT_SCALE: f32 = 2.0; @fragment fn main_fs(in: VertexOutput) -> @location(0) vec4 { diff --git a/game/src/game_shaders.rs b/game/src/game_shaders.rs index 53759a4..e184cba 100644 --- a/game/src/game_shaders.rs +++ b/game/src/game_shaders.rs @@ -125,7 +125,7 @@ impl<'context> Dependencies<'context> { "palette", &palette.pixels, Vec2::new(COLORMAP_SIZE, palette.pixels.len() / MAPPED_PALETTE_SIZE), - wgpu::TextureFormat::Rgba8Unorm, + wgpu::TextureFormat::Rgba8UnormSrgb, ) } From a80a8f6dc2dc71a45bb1ac0df1eec6a5b3d220ce Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Mon, 29 Jan 2024 16:39:57 +0100 Subject: [PATCH 57/58] Fix palette creation --- wad/src/tex.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/wad/src/tex.rs b/wad/src/tex.rs index 0b73a72..c5230f0 100644 --- a/wad/src/tex.rs +++ b/wad/src/tex.rs @@ -141,7 +141,7 @@ impl TextureDirectory { colormap_end: usize, ) -> MappedPalette { let num_colormaps = colormap_end - colormap_start; - let mut mapped = vec![0u8; 256 * num_colormaps * 4]; + let mut mapped = vec![255u8; 256 * num_colormaps * 4]; let palette = &self.palettes[palette]; let colormaps_with_offsets = self @@ -150,13 +150,12 @@ impl TextureDirectory { .enumerate() .take(colormap_end) .skip(colormap_start) - .map(|(i_colormap, colormap)| (i_colormap * 256 * 3, colormap)); + .map(|(i_colormap, colormap)| (i_colormap * 256 * 4, colormap)); for (offset, colormap) in colormaps_with_offsets { for (i_color, color) in colormap.0.iter().enumerate() { mapped[i_color * 4 + offset..][..3] .copy_from_slice(&palette.0[usize::from(*color) * 3..][..3]); - mapped[i_color * 4 + offset..][3] = 255; } } From 676e89e31fc96c7b518cd09ab1c236e13c17a299 Mon Sep 17 00:00:00 2001 From: Bradford Hovinen Date: Mon, 29 Jan 2024 16:51:16 +0100 Subject: [PATCH 58/58] Actually copy text texture to GPU --- engine/src/text.rs | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/engine/src/text.rs b/engine/src/text.rs index e2055d3..43c5e4d 100644 --- a/engine/src/text.rs +++ b/engine/src/text.rs @@ -50,20 +50,25 @@ impl TextRenderer { pub fn insert(&mut self, win: &Window, text: &str, pos: Pnt2f, padding: u32) -> TextId { debug!("Creating text..."); let (width, height) = self.rasterise(text, padding); - let texture = win.device().create_texture(&wgpu::TextureDescriptor { - label: Some("Text texture"), - size: wgpu::Extent3d { - width, - height, - depth_or_array_layers: 1, + let texture = win.device().create_texture_with_data( + win.queue(), + &wgpu::TextureDescriptor { + label: Some("Text texture"), + size: wgpu::Extent3d { + width, + height, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Rg8Unorm, + usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, + view_formats: &[], }, - mip_level_count: 1, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Rg8Unorm, - usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, - view_formats: &[], - }); + wgpu::util::TextureDataOrder::LayerMajor, + bytemuck::cast_slice(&self.pixel_buffer), + ); let sampler = win.device().create_sampler(&wgpu::SamplerDescriptor { label: Some("Text sampler"), address_mode_u: wgpu::AddressMode::ClampToEdge, @@ -304,8 +309,8 @@ impl<'context> System<'context> for TextRenderer { primitive: wgpu::PrimitiveState { topology: wgpu::PrimitiveTopology::TriangleStrip, strip_index_format: None, - front_face: wgpu::FrontFace::Ccw, - cull_mode: Some(wgpu::Face::Back), + front_face: wgpu::FrontFace::Cw, + cull_mode: None, unclipped_depth: false, polygon_mode: wgpu::PolygonMode::Fill, conservative: false,