diff options
-rw-r--r-- | Cargo.lock | 502 | ||||
-rw-r--r-- | client/Cargo.toml | 1 | ||||
-rw-r--r-- | client/src/renderer.rs | 15 | ||||
-rw-r--r-- | client/src/scene_prepare.rs | 286 | ||||
-rw-r--r-- | client/src/scene_render.rs | 109 | ||||
-rw-r--r-- | client/src/shader.wgsl | 4 | ||||
-rw-r--r-- | client/src/state.rs | 3 | ||||
-rw-r--r-- | client/src/window.rs | 2 | ||||
-rw-r--r-- | shared/src/packets.rs | 27 | ||||
-rw-r--r-- | shared/src/resources.rs | 119 | ||||
-rw-r--r-- | world/Cargo.toml | 3 | ||||
-rw-r--r-- | world/src/main.rs | 35 |
12 files changed, 886 insertions, 220 deletions
@@ -47,6 +47,12 @@ dependencies = [ ] [[package]] +name = "aligned-vec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" + +[[package]] name = "alsa" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -160,6 +166,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "arrayref" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -218,6 +241,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e335041290c43101ca215eed6f43ec437eb5a42125573f600fc3fa42b9bddd62" +dependencies = [ + "arrayvec", +] + +[[package]] name = "base64" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -241,7 +287,7 @@ dependencies = [ "bitflags 2.6.0", "cexpr", "clang-sys", - "itertools", + "itertools 0.13.0", "proc-macro2", "quote", "regex", @@ -266,6 +312,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[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.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -278,6 +330,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] +name = "bitstream-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" + +[[package]] name = "block" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -302,6 +360,12 @@ dependencies = [ ] [[package]] +name = "built" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c360505aed52b7ec96a3636c3f039d99103c37d1d9b4f7a8c743d3ea9ffcd03b" + +[[package]] name = "bumpalo" version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -384,6 +448,16 @@ dependencies = [ ] [[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -463,6 +537,12 @@ dependencies = [ ] [[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] name = "colorchoice" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -595,12 +675,37 @@ dependencies = [ ] [[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +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.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] name = "crypto-common" version = "0.2.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -716,6 +821,21 @@ dependencies = [ ] [[package]] +name = "exr" +version = "1.73.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" +dependencies = [ + "bit_field", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] name = "fdeflate" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -804,6 +924,16 @@ dependencies = [ ] [[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] name = "gl_generator" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -941,6 +1071,16 @@ dependencies = [ ] [[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] name = "hashbrown" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -990,13 +1130,38 @@ checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" dependencies = [ "bytemuck", "byteorder-lite", + "color_quant", + "exr", + "gif", + "image-webp", "num-traits", "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", "zune-core", "zune-jpeg", ] [[package]] +name = "image-webp" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e031e8e3d94711a9ccb5d6ea357439ef3dcbed361798bd4071dc4d9793fbe22f" +dependencies = [ + "byteorder-lite", + "quick-error", +] + +[[package]] +name = "imgref" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" + +[[package]] name = "indexmap" version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1013,6 +1178,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" [[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] name = "is_terminal_polyfill" version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1020,6 +1196,15 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" @@ -1065,6 +1250,12 @@ dependencies = [ ] [[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + +[[package]] name = "js-sys" version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1098,12 +1289,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[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.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] +name = "libfuzzer-sys" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b9569d2f74e257076d8c6bfa73fb505b46b851e51ddaecc825944aa3bed17fa" +dependencies = [ + "arbitrary", + "cc", +] + +[[package]] name = "libloading" version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1153,6 +1360,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + +[[package]] name = "mach2" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1171,6 +1387,16 @@ dependencies = [ ] [[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + +[[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1291,6 +1517,12 @@ dependencies = [ ] [[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] name = "nom" version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1301,6 +1533,22 @@ dependencies = [ ] [[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] name = "num-derive" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1312,6 +1560,26 @@ dependencies = [ ] [[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] name = "num-traits" version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1739,6 +2007,34 @@ name = "profiling" version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quick-xml" @@ -1760,17 +2056,38 @@ dependencies = [ [[package]] name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" version = "0.9.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8478de76992f2825a1052cc2ae9d1401cdb62687761d4100ddd69a73dc3dc48" dependencies = [ - "rand_chacha", + "rand_chacha 0.9.0-beta.1", "rand_core 0.9.0-beta.1", "zerocopy 0.8.14", ] [[package]] name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" version = "0.9.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f16da77124f4ee9fabd55ce6540866e9101431863b4876de58b68797f331adf2" @@ -1805,12 +2122,82 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab" [[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io", + "built", + "cfg-if", + "interpolate_name", + "itertools 0.12.1", + "libc", + "libfuzzer-sys", + "log", + "maybe-rayon", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand 0.8.5", + "rand_chacha 0.3.1", + "simd_helpers", + "system-deps", + "thiserror", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "ravif" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2413fd96bd0ea5cdeeb37eaf446a22e6ed7b981d792828721e74ded1980a45c6" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + +[[package]] name = "raw-window-handle" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +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 = "redb" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1873,6 +2260,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" [[package]] +name = "rgb" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" + +[[package]] name = "rustc-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1964,6 +2357,15 @@ dependencies = [ ] [[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] name = "sha2" version = "0.11.0-pre.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1987,6 +2389,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + +[[package]] name = "slab" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2083,6 +2494,25 @@ dependencies = [ ] [[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + +[[package]] name = "termcolor" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2112,6 +2542,17 @@ dependencies = [ ] [[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.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2137,10 +2578,25 @@ dependencies = [ ] [[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] name = "toml_datetime" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -2149,6 +2605,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", + "serde", + "serde_spanned", "toml_datetime", "winnow", ] @@ -2218,6 +2676,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] +name = "v_frame" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" +dependencies = [ + "aligned-vec", + "num-traits", + "wasm-bindgen", +] + +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + +[[package]] name = "version_check" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2434,9 +2909,10 @@ dependencies = [ "cpal", "env_logger", "glam", + "image", "log", "pollster", - "rand", + "rand 0.9.0-beta.1", "weareshared", "wgpu", "winit", @@ -2462,7 +2938,7 @@ dependencies = [ "bincode", "glam", "log", - "rand", + "rand 0.9.0-beta.1", "redb", "sha2", ] @@ -2475,8 +2951,9 @@ dependencies = [ "clap", "env_logger", "gltf", + "image", "log", - "rand", + "rand 0.9.0-beta.1", "weareshared", ] @@ -2501,6 +2978,12 @@ dependencies = [ ] [[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + +[[package]] name = "wgpu" version = "23.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3100,6 +3583,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" [[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] name = "zune-jpeg" version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/client/Cargo.toml b/client/Cargo.toml index 4bcfb4c..da0f5c6 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -16,3 +16,4 @@ winit = "0.30.8" weareshared = { path = "../shared" } rand = "0.9.0-beta.1" glam = "0.29.2" +image = "0.25.5" diff --git a/client/src/renderer.rs b/client/src/renderer.rs index 3561d87..3591503 100644 --- a/client/src/renderer.rs +++ b/client/src/renderer.rs @@ -13,7 +13,7 @@ use winit::window::Window; pub struct Renderer<'a> { surface: Surface<'a>, - queue: Queue, + queue: Arc<Queue>, device: Arc<Device>, surface_configuration: SurfaceConfiguration, scene_pipeline: ScenePipeline, @@ -60,10 +60,15 @@ impl<'a> Renderer<'a> { surface.configure(&device, &surface_configuration); let device = Arc::new(device); + let queue = Arc::new(queue); + + let (scene_pipeline, texture_bgl) = + ScenePipeline::new(&device, surface_configuration.format); + let scene_prepare = ScenePreparer::new(device.clone(), queue.clone(), texture_bgl); Ok(Self { - scene_pipeline: ScenePipeline::new(&device, surface_configuration.format), - scene_prepare: ScenePreparer::new(device.clone()), + scene_pipeline, + scene_prepare, surface, device, queue, @@ -77,6 +82,7 @@ impl<'a> Renderer<'a> { self.surface_configuration.height = height; self.surface .configure(&self.device, &self.surface_configuration); + self.scene_pipeline.resize(&self.device, width, height); } pub fn draw(&mut self, scene: &SceneTree) -> Result<()> { @@ -102,8 +108,7 @@ impl<'a> Renderer<'a> { &mut commands, &target_view, scene, - &self.scene_prepare.prefabs, - &mut self.scene_prepare.prefabs_needed, + &mut self.scene_prepare.prefabs, ); let i = self.queue.submit(Some(commands.finish())); diff --git a/client/src/scene_prepare.rs b/client/src/scene_prepare.rs index 85db160..f7a5bc8 100644 --- a/client/src/scene_prepare.rs +++ b/client/src/scene_prepare.rs @@ -1,31 +1,62 @@ use crate::download::Downloader; use anyhow::{Context, Result}; +use image::{ImageFormat, ImageReader}; use log::debug; use std::{ collections::{HashMap, HashSet}, + hash::Hash, + io::Cursor, sync::Arc, }; use weareshared::{ Affine3A, packets::{ReadWrite, Resource}, - resources::{Attribute, Part, Prefab}, + resources::{Part, Prefab}, }; use wgpu::{ - Buffer, BufferUsages, Device, - util::{BufferInitDescriptor, DeviceExt}, + BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindingResource, Buffer, + BufferUsages, Device, Extent3d, Queue, SamplerDescriptor, Texture, TextureDescriptor, + TextureDimension, TextureFormat, TextureUsages, TextureViewDescriptor, + util::{BufferInitDescriptor, DeviceExt, TextureDataOrder}, }; -pub struct ScenePreparer { - index_buffers: HashMap<Resource, (Arc<Buffer>, u32)>, - index_buffers_needed: HashSet<Resource>, - vertex_buffers: HashMap<Resource, Arc<Buffer>>, - vertex_buffers_needed: HashSet<Resource>, - parts: HashMap<Resource, Arc<RPart>>, - parts_needed: HashSet<Resource>, - pub prefabs: HashMap<Resource, RPrefab>, - pub prefabs_needed: HashSet<Resource>, +pub struct DemandMap<K, V> { + values: HashMap<K, V>, + needed: HashSet<K>, +} +impl<K: Hash + Eq, V: Clone> DemandMap<K, V> { + pub fn new() -> Self { + Self { + needed: HashSet::new(), + values: HashMap::new(), + } + } + pub fn insert(&mut self, key: K, value: V) { + self.needed.remove(&key); + self.values.insert(key, value); + } + pub fn try_get(&mut self, key: K) -> Option<V> { + if let Some(k) = self.values.get(&key) { + Some(k.to_owned()) + } else { + self.needed.insert(key); + None + } + } +} +pub struct ScenePreparer { device: Arc<Device>, + queue: Arc<Queue>, + texture_bgl: BindGroupLayout, + + textures: DemandMap<Resource, (Arc<Texture>, Arc<BindGroup>)>, + placeholder_textures: DemandMap<(), (Arc<Texture>, Arc<BindGroup>)>, + index_buffers: DemandMap<Resource, (Arc<Buffer>, u32)>, + vertex_buffers: DemandMap<Resource, (Arc<Buffer>, u32)>, + placeholder_vertex_buffers: DemandMap<(u32, bool), Arc<Buffer>>, + parts: DemandMap<Resource, Arc<RPart>>, + pub prefabs: DemandMap<Resource, Arc<RPrefab>>, } pub struct RPrefab(pub Vec<(Affine3A, Arc<RPart>)>); @@ -35,44 +66,42 @@ pub struct RPart { pub position: [Arc<Buffer>; 3], pub normal: [Arc<Buffer>; 3], pub texcoord: [Arc<Buffer>; 2], + pub texture: Arc<BindGroup>, } impl ScenePreparer { - pub fn new(device: Arc<Device>) -> Self { + pub fn new(device: Arc<Device>, queue: Arc<Queue>, texture_bgl: BindGroupLayout) -> Self { Self { - index_buffers: HashMap::new(), - vertex_buffers: HashMap::new(), - vertex_buffers_needed: HashSet::new(), - parts: HashMap::new(), - parts_needed: HashSet::new(), - prefabs: HashMap::new(), - prefabs_needed: HashSet::new(), - index_buffers_needed: HashSet::new(), + texture_bgl, + index_buffers: DemandMap::new(), + vertex_buffers: DemandMap::new(), + parts: DemandMap::new(), + prefabs: DemandMap::new(), + textures: DemandMap::new(), + placeholder_vertex_buffers: DemandMap::new(), + placeholder_textures: DemandMap::new(), device, + queue, } } pub fn update(&mut self, dls: &mut Downloader) -> Result<()> { - let mut done = Vec::new(); - for pres in &self.prefabs_needed { - if let Some(buf) = dls.try_get(*pres)? { + for pres in self.prefabs.needed.clone() { + if let Some(buf) = dls.try_get(pres)? { let prefab = Prefab::read(&mut buf.as_slice()).context("parsing prefab")?; let mut rprefab = RPrefab(Vec::new()); for (aff, partres) in &prefab.0 { - if let Some(part) = self.parts.get(partres) { + if let Some(part) = self.parts.try_get(*partres) { rprefab.0.push((*aff, part.clone())); - } else { - self.parts_needed.insert(*partres); } } if rprefab.0.len() == prefab.0.len() { - self.prefabs.insert(*pres, rprefab); + self.prefabs.insert(pres, Arc::new(rprefab)); debug!("prefab created ({pres})"); - done.push(*pres); } } } - for pres in &self.index_buffers_needed { - if let Some(buf) = dls.try_get(*pres)? { + for pres in self.index_buffers.needed.clone() { + if let Some(buf) = dls.try_get(pres)? { let buf = buf .into_iter() .array_chunks::<2>() @@ -86,13 +115,12 @@ impl ScenePreparer { usage: BufferUsages::INDEX | BufferUsages::COPY_DST, }); self.index_buffers - .insert(*pres, (Arc::new(buffer), buf.len() as u32 / 2)); - debug!("index buffer created (len={}) {pres}", buf.len() / 6); - done.push(*pres); + .insert(pres, (Arc::new(buffer), (buf.len() / 2) as u32)); + debug!("index buffer created (len={}) {pres}", buf.len() / 2); } } - for pres in &self.vertex_buffers_needed { - if let Some(buf) = dls.try_get(*pres)? { + for pres in self.vertex_buffers.needed.clone() { + if let Some(buf) = dls.try_get(pres)? { let buf = buf .into_iter() .array_chunks::<4>() @@ -105,94 +133,174 @@ impl ScenePreparer { label: None, usage: BufferUsages::VERTEX | BufferUsages::COPY_DST, }); - self.vertex_buffers.insert(*pres, Arc::new(buffer)); + self.vertex_buffers + .insert(pres, (Arc::new(buffer), (buf.len() / 4) as u32)); debug!( "vertex attribute buffer created (len={}) {pres}", buf.len() / 4 ); - done.push(*pres); } } - for pres in &self.parts_needed { - if let Some(buf) = dls.try_get(*pres)? { + for pres in self.textures.needed.clone() { + if let Some(buf) = dls.try_get(pres)? { + let image = ImageReader::new(Cursor::new(buf)).with_guessed_format()?; + let image = image.decode()?; + let image = image.to_rgba8(); + let image_raw = image.to_vec(); + let tex_bg = create_texture( + &self.device, + &self.queue, + &self.texture_bgl, + &image_raw, + image.width(), + image.height(), + ); + self.textures.insert(pres, tex_bg); + } + } + for pres in self.placeholder_textures.needed.clone() { + let tex_bg = create_texture( + &self.device, + &self.queue, + &self.texture_bgl, + &[255, 255, 255, 255], + 1, + 1, + ); + self.placeholder_textures.insert(pres, tex_bg); + } + for pres in self.parts.needed.clone() { + if let Some(buf) = dls.try_get(pres)? { let part = Part::read(&mut buf.as_slice()).context("parsing part")?; - if let (Some(indexres), Some(positionres), Some(normalres), Some(texcoordres)) = ( - part.index, - part.va_position, - part.va_normal, - part.va_texcoord, - ) { - let Some((index, index_count)) = self.index_buffers.get(&indexres).cloned() - else { - self.index_buffers_needed.insert(indexres); + if let (Some(indexres), Some(positionres)) = (part.index, part.va_position) { + let Some((index, index_count)) = self.index_buffers.try_get(indexres) else { + self.index_buffers.needed.insert(indexres); continue; }; let mut position = Vec::new(); + let mut vertex_count = 0; for vr in positionres { - match vr { - Attribute::Constant(_) => todo!(), - Attribute::Vertex(resource) => { - if let Some(vertex) = self.vertex_buffers.get(&resource).cloned() { - position.push(vertex); - } else { - self.vertex_buffers_needed.insert(resource); - }; - } - Attribute::Texture(_resource, _ch) => todo!(), + if let Some((vertex, n)) = self.vertex_buffers.try_get(vr) { + vertex_count = n; + position.push(vertex); } } let mut normal = Vec::new(); - for vr in normalres { - match vr { - Attribute::Constant(_) => todo!(), - Attribute::Vertex(resource) => { - if let Some(vertex) = self.vertex_buffers.get(&resource).cloned() { - normal.push(vertex); - } else { - self.vertex_buffers_needed.insert(resource); - }; + if let Some(normalres) = part.va_normal { + for vr in normalres { + if let Some((vertex, _)) = self.vertex_buffers.try_get(vr) { + normal.push(vertex); + } + } + } else { + // TODO generate normals + for _ in 0..3 { + if let Some(buf) = self + .placeholder_vertex_buffers + .try_get((vertex_count, false)) + { + normal.push(buf); } - Attribute::Texture(_resource, _ch) => todo!(), } } let mut texcoord = Vec::new(); - for vr in texcoordres { - match vr { - Attribute::Constant(_) => todo!(), - Attribute::Vertex(resource) => { - if let Some(vertex) = self.vertex_buffers.get(&resource).cloned() { - texcoord.push(vertex); - } else { - self.vertex_buffers_needed.insert(resource); - }; + if let Some(texcoordres) = part.va_texcoord { + for vr in texcoordres { + if let Some((vertex, _)) = self.vertex_buffers.try_get(vr) { + texcoord.push(vertex); } - Attribute::Texture(_resource, _ch) => todo!(), + } + } else { + // TODO generate UVs + for _ in 0..3 { + if let Some(buf) = self + .placeholder_vertex_buffers + .try_get((vertex_count, false)) + { + texcoord.push(buf); + } + } + } + let mut texture = None; + if let Some(albedores) = part.tex_pbr_albedo { + if let Some((_tex, bg)) = self.textures.try_get(albedores) { + texture = Some(bg) + } + } else { + if let Some((_tex, bg)) = self.placeholder_textures.try_get(()) { + texture = Some(bg) } } - if texcoord.len() == 2 && normal.len() == 3 && position.len() == 3 { + + if texcoord.len() == 2 + && normal.len() == 3 + && position.len() == 3 + && texture.is_some() + { debug!("part created ({pres})"); self.parts.insert( - *pres, + pres, Arc::new(RPart { index_count, index, texcoord: texcoord.try_into().unwrap(), normal: normal.try_into().unwrap(), position: position.try_into().unwrap(), + texture: texture.unwrap(), }), ); - done.push(*pres); } } } } - - for d in done { - self.parts_needed.remove(&d); - self.prefabs_needed.remove(&d); - self.index_buffers_needed.remove(&d); - self.vertex_buffers_needed.remove(&d); - } Ok(()) } } + +fn create_texture( + device: &Device, + queue: &Queue, + bgl: &BindGroupLayout, + data: &[u8], + width: u32, + height: u32, +) -> (Arc<Texture>, Arc<BindGroup>) { + let texture = device.create_texture_with_data( + &queue, + &TextureDescriptor { + label: None, + size: Extent3d { + depth_or_array_layers: 1, + width, + height, + }, + mip_level_count: 1, + sample_count: 1, + dimension: TextureDimension::D2, + format: TextureFormat::Rgba8UnormSrgb, + usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST, + view_formats: &[], + }, + TextureDataOrder::LayerMajor, + data, + ); + let textureview = texture.create_view(&TextureViewDescriptor::default()); + let sampler = device.create_sampler(&SamplerDescriptor { + ..Default::default() + }); + let bindgroup = device.create_bind_group(&BindGroupDescriptor { + label: None, + layout: &bgl, + entries: &[ + BindGroupEntry { + binding: 0, + resource: BindingResource::TextureView(&textureview), + }, + BindGroupEntry { + binding: 1, + resource: BindingResource::Sampler(&sampler), + }, + ], + }); + (Arc::new(texture), Arc::new(bindgroup)) +} diff --git a/client/src/scene_render.rs b/client/src/scene_render.rs index b4965e1..8703c9f 100644 --- a/client/src/scene_render.rs +++ b/client/src/scene_render.rs @@ -1,21 +1,24 @@ use glam::{EulerRot, Mat3, Mat4, Vec3, vec3}; -use std::collections::{HashMap, HashSet}; +use std::sync::Arc; use weareshared::{packets::Resource, tree::SceneTree}; use wgpu::{ - BindGroup, BindGroupDescriptor, BindGroupLayoutDescriptor, BlendState, Color, ColorTargetState, - ColorWrites, CommandEncoder, Device, FragmentState, FrontFace, IndexFormat, LoadOp, + BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType, BlendState, + Color, ColorTargetState, ColorWrites, CommandEncoder, CompareFunction, DepthBiasState, + DepthStencilState, Device, Extent3d, FragmentState, FrontFace, IndexFormat, LoadOp, MultisampleState, Operations, PipelineCompilationOptions, PipelineLayoutDescriptor, PolygonMode, PrimitiveState, PrimitiveTopology, PushConstantRange, RenderPassColorAttachment, - RenderPassDescriptor, RenderPipeline, RenderPipelineDescriptor, ShaderStages, StoreOp, - TextureFormat, TextureView, VertexAttribute, VertexBufferLayout, VertexFormat, VertexState, - VertexStepMode, include_wgsl, + RenderPassDepthStencilAttachment, RenderPassDescriptor, RenderPipeline, + RenderPipelineDescriptor, SamplerBindingType, ShaderStages, StencilState, StoreOp, + TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType, TextureUsages, + TextureView, TextureViewDescriptor, TextureViewDimension, VertexAttribute, VertexBufferLayout, + VertexFormat, VertexState, VertexStepMode, include_wgsl, }; -use crate::scene_prepare::RPrefab; +use crate::scene_prepare::{DemandMap, RPrefab}; pub struct ScenePipeline { pipeline: RenderPipeline, - bind_group: BindGroup, + depth: TextureView, } macro_rules! v_attr { @@ -33,17 +36,45 @@ macro_rules! v_attr { } impl ScenePipeline { - pub fn new(device: &Device, format: TextureFormat) -> Self { + pub fn new(device: &Device, format: TextureFormat) -> (Self, BindGroupLayout) { let module = device.create_shader_module(include_wgsl!("shader.wgsl")); - let bind_group_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor { - entries: &[], + let depth = device.create_texture(&TextureDescriptor { label: None, + size: Extent3d { + height: 256, + width: 256, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: TextureDimension::D2, + format: TextureFormat::Depth32Float, + usage: TextureUsages::RENDER_ATTACHMENT, + view_formats: &[], }); - let bind_group = device.create_bind_group(&BindGroupDescriptor { + let depth = depth.create_view(&TextureViewDescriptor::default()); + + let bind_group_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor { + entries: &[ + BindGroupLayoutEntry { + binding: 0, + count: None, + visibility: ShaderStages::FRAGMENT, + ty: BindingType::Texture { + sample_type: TextureSampleType::Float { filterable: true }, + view_dimension: TextureViewDimension::D2, + multisampled: false, + }, + }, + BindGroupLayoutEntry { + binding: 1, + count: None, + visibility: ShaderStages::FRAGMENT, + ty: BindingType::Sampler(SamplerBindingType::Filtering), + }, + ], label: None, - layout: &bind_group_layout, - entries: &[], }); let pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor { label: None, @@ -79,23 +110,45 @@ impl ScenePipeline { polygon_mode: PolygonMode::Fill, ..Default::default() }, - depth_stencil: Default::default(), + depth_stencil: Some(DepthStencilState { + depth_compare: CompareFunction::Greater, + depth_write_enabled: true, + format: TextureFormat::Depth32Float, + bias: DepthBiasState::default(), + stencil: StencilState::default(), + }), multisample: MultisampleState::default(), multiview: None, cache: None, }); - Self { - bind_group, - pipeline, - } + (Self { pipeline, depth }, bind_group_layout) + } + + pub fn resize(&mut self, device: &Device, width: u32, height: u32) { + self.depth = device + .create_texture(&TextureDescriptor { + label: None, + size: Extent3d { + height, + width, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: TextureDimension::D2, + format: TextureFormat::Depth32Float, + usage: TextureUsages::RENDER_ATTACHMENT, + view_formats: &[], + }) + .create_view(&TextureViewDescriptor::default()); } + pub fn draw( &mut self, commands: &mut CommandEncoder, target: &TextureView, scene: &SceneTree, - prefabs: &HashMap<Resource, RPrefab>, - prefabs_needed: &mut HashSet<Resource>, + prefabs: &mut DemandMap<Resource, Arc<RPrefab>>, ) { let mut rpass = commands.begin_render_pass(&RenderPassDescriptor { label: None, @@ -112,6 +165,14 @@ impl ScenePipeline { }), }, })], + depth_stencil_attachment: Some(RenderPassDepthStencilAttachment { + view: &self.depth, + depth_ops: Some(Operations { + load: LoadOp::Clear(0.), + store: StoreOp::Store, + }), + stencil_ops: None, + }), ..Default::default() }); @@ -127,14 +188,14 @@ impl ScenePipeline { ob.rot.z, )) * Mat4::from_translation(ob.pos.into()); - if let Some(prefab) = prefabs.get(&ob.res) { + if let Some(prefab) = prefabs.try_get(ob.res) { for (affine, part) in &prefab.0 { let part_projection = prefab_projection * Mat4::from_mat3a(affine.matrix3) * Mat4::from_translation(affine.translation.into()); let projection = part_projection.to_cols_array().map(|v| v.to_le_bytes()); - rpass.set_bind_group(0, &self.bind_group, &[]); + rpass.set_bind_group(0, &*part.texture, &[]); rpass.set_pipeline(&self.pipeline); rpass.set_push_constants(ShaderStages::VERTEX, 0, projection.as_flattened()); rpass.set_index_buffer(part.index.slice(..), IndexFormat::Uint16); @@ -148,8 +209,6 @@ impl ScenePipeline { rpass.set_vertex_buffer(7, part.texcoord[1].slice(..)); rpass.draw_indexed(0..part.index_count, 0, 0..1); } - } else { - prefabs_needed.insert(ob.res); } } } diff --git a/client/src/shader.wgsl b/client/src/shader.wgsl index d2b2d9f..b40bf57 100644 --- a/client/src/shader.wgsl +++ b/client/src/shader.wgsl @@ -15,6 +15,8 @@ struct VertexOut { @location(1) uv: vec2<f32>, } +@group(0) @binding(0) var tex_albedo: texture_2d<f32>; +@group(0) @binding(1) var tex_albedo_sampler: sampler; var<push_constant> project: mat4x4<f32>; @vertex @@ -30,5 +32,5 @@ fn vs_main(vi: VertexIn) -> VertexOut { } @fragment fn fs_main(vo: VertexOut) -> @location(0) vec4<f32> { - return vec4<f32>(vo.normal, 1.0); + return textureSample(tex_albedo, tex_albedo_sampler, vo.uv); } diff --git a/client/src/state.rs b/client/src/state.rs index e8188d8..a370264 100644 --- a/client/src/state.rs +++ b/client/src/state.rs @@ -26,6 +26,9 @@ impl<'a> State<'a> { warn!("draw failed: {e:?}"); } } + pub fn resize(&mut self, width: u32, height: u32) { + self.renderer.resize(width, height); + } pub fn update(&mut self) -> Result<()> { for p in self.network.packet_recv.try_iter() { self.downloader.packet(&p)?; diff --git a/client/src/window.rs b/client/src/window.rs index 2430479..6ee7fa4 100644 --- a/client/src/window.rs +++ b/client/src/window.rs @@ -41,7 +41,7 @@ impl ApplicationHandler for WindowState { if let Some((win, sta)) = &mut self.window { match event { WindowEvent::Resized(size) => { - sta.renderer.resize(size.width, size.height); + sta.resize(size.width, size.height); } WindowEvent::RedrawRequested => { sta.draw(); diff --git a/shared/src/packets.rs b/shared/src/packets.rs index 0f1a886..07c4345 100644 --- a/shared/src/packets.rs +++ b/shared/src/packets.rs @@ -103,14 +103,13 @@ impl ReadWrite for Packet { fn write(&self, w: &mut dyn Write) -> Result<()> { let mut buf = Vec::new(); self.serialize_inner(&mut buf)?; - w.write_all(&(buf.len() as u16).to_be_bytes())?; + w.write_all(&(buf.len() as u32).to_be_bytes())?; w.write_all(&buf)?; Ok(()) } fn read(r: &mut dyn Read) -> Result<Self> { - let mut size_tag = [0u8; 3]; - r.read_exact(&mut size_tag)?; - Ok(match size_tag[2] { + let packet_len = u32::read(r)?; + Ok(match u8::read(r)? { 0x00 => Packet::Connect(read_u128(r)?), 0x01 => Packet::RequestResource(Resource::read(r)?), 0x02 => Packet::RespondResource(Data::read(r)?), @@ -125,8 +124,7 @@ impl ReadWrite for Packet { 0x07 => Packet::Parent(Object(read_u128(r)?), Object(read_u128(r)?)), 0x08 => Packet::Sound(Object(read_u128(r)?), Data::read(r)?), _ => { - let len = u16::from_be_bytes([size_tag[0], size_tag[1]]); - for _ in 0..len.max(1) - 1 { + for _ in 0..packet_len.max(1) - 1 { r.read_exact(&mut [0])?; } bail!("unknown packet tag"); @@ -153,14 +151,14 @@ impl ReadWrite for Resource { } impl ReadWrite for Data { fn write(&self, w: &mut dyn Write) -> Result<()> { - w.write_all(&(self.0.len() as u16).to_be_bytes())?; + w.write_all(&(self.0.len() as u32).to_be_bytes())?; w.write_all(&self.0)?; Ok(()) } fn read(r: &mut dyn Read) -> Result<Self> { - let mut size = [0; 2]; + let mut size = [0; 4]; r.read_exact(&mut size)?; - let size = u16::from_be_bytes(size); + let size = u32::from_be_bytes(size); let mut buf = vec![0; size as usize]; r.read_exact(&mut buf)?; Ok(Data(buf)) @@ -188,6 +186,17 @@ impl ReadWrite for f32 { Ok(f32::from_be_bytes(buf)) } } +impl ReadWrite for u32 { + fn write(&self, w: &mut dyn Write) -> Result<()> { + w.write_all(&self.to_be_bytes())?; + Ok(()) + } + fn read(r: &mut dyn Read) -> Result<Self> { + let mut buf = [0; 4]; + r.read_exact(&mut buf)?; + Ok(u32::from_be_bytes(buf)) + } +} impl Display for Resource { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { diff --git a/shared/src/resources.rs b/shared/src/resources.rs index a071f1c..4c6321f 100644 --- a/shared/src/resources.rs +++ b/shared/src/resources.rs @@ -1,5 +1,5 @@ use crate::packets::{ReadWrite, Resource}; -use anyhow::{Result, bail}; +use anyhow::Result; use glam::{Affine3A, Vec3A}; use log::warn; use std::io::{Read, Write}; @@ -7,23 +7,27 @@ use std::io::{Read, Write}; #[derive(Debug, Default, Clone)] pub struct Prefab(pub Vec<(Affine3A, Resource)>); +/// Combinations of va_* and tex_* are multiplied except normal which is added. +/// Defaults should be the identity for that operation, so default is 1 (or white) except normals are Vec3::ZERO. #[derive(Debug, Default, Clone)] pub struct Part { pub index: Option<Resource>, - pub va_position: Option<[Attribute; 3]>, - pub va_normal: Option<[Attribute; 3]>, - pub va_texcoord: Option<[Attribute; 2]>, - pub va_pbr_roughness: Option<Attribute>, - pub va_pbr_metallic: Option<Attribute>, - pub va_pbr_albedo: Option<[Attribute; 3]>, - pub va_pbr_transmission: Option<Attribute>, -} - -#[derive(Debug, Clone)] -pub enum Attribute { - Constant(f32), - Vertex(Resource), - Texture(Resource, u8), + pub g_metallic: Option<f32>, + pub g_roughness: Option<f32>, + pub g_albedo: Option<Vec3A>, + pub g_transmission: Option<f32>, + pub va_position: Option<[Resource; 3]>, + pub va_normal: Option<[Resource; 3]>, + pub va_texcoord: Option<[Resource; 2]>, + pub va_pbr_roughness: Option<Resource>, + pub va_pbr_metallic: Option<Resource>, + pub va_pbr_albedo: Option<[Resource; 3]>, + pub va_pbr_transmission: Option<Resource>, + pub tex_normal: Option<Resource>, + pub tex_pbr_roughness: Option<Resource>, + pub tex_pbr_metallic: Option<Resource>, + pub tex_pbr_albedo: Option<Resource>, + pub tex_pbr_transmission: Option<Resource>, } #[derive(Debug, Default, Clone)] @@ -86,27 +90,24 @@ impl ReadWrite for AttributeArray { } impl ReadWrite for Part { fn write(&self, w: &mut dyn Write) -> Result<()> { - if let Some(a) = &self.index { - write_kv(w, b"index", &a.write_alloc())?; - } - if let Some(a) = &self.va_position { - write_kv(w, b"va_position", &a.write_alloc())?; - } - if let Some(a) = &self.va_normal { - write_kv(w, b"va_normal", &a.write_alloc())?; - } - if let Some(a) = &self.va_texcoord { - write_kv(w, b"va_texcoord", &a.write_alloc())?; - } - if let Some(a) = &self.va_pbr_roughness { - write_kv(w, b"va_pbr_roughness", &a.write_alloc())?; - } - if let Some(a) = &self.va_pbr_metallic { - write_kv(w, b"va_pbr_metallic", &a.write_alloc())?; - } - if let Some(a) = &self.va_pbr_albedo { - write_kv(w, b"va_pbr_albedo", &a.write_alloc())?; - } + write_kv_opt(w, b"index", &self.index)?; + write_kv_opt(w, b"g_metallic", &self.g_metallic)?; + write_kv_opt(w, b"g_roughness", &self.g_roughness)?; + write_kv_opt(w, b"g_albedo", &self.g_albedo)?; + write_kv_opt(w, b"g_transmission", &self.g_transmission)?; + write_kv_opt(w, b"va_position", &self.va_position)?; + write_kv_opt(w, b"va_normal", &self.va_normal)?; + write_kv_opt(w, b"va_texcoord", &self.va_texcoord)?; + write_kv_opt(w, b"va_pbr_roughness", &self.va_pbr_roughness)?; + write_kv_opt(w, b"va_pbr_metallic", &self.va_pbr_metallic)?; + write_kv_opt(w, b"va_pbr_albedo", &self.va_pbr_albedo)?; + write_kv_opt(w, b"va_pbr_transmission", &self.va_pbr_transmission)?; + write_kv_opt(w, b"tex_normal", &self.tex_normal)?; + write_kv_opt(w, b"tex_pbr_roughness", &self.tex_pbr_roughness)?; + write_kv_opt(w, b"tex_pbr_metallic", &self.tex_pbr_metallic)?; + write_kv_opt(w, b"tex_pbr_albedo", &self.tex_pbr_albedo)?; + write_kv_opt(w, b"tex_pbr_transmission", &self.tex_pbr_transmission)?; + Ok(()) } fn read(r: &mut dyn Read) -> Result<Self> { @@ -119,6 +120,10 @@ impl ReadWrite for Part { let mut v = v.as_slice(); match k.as_slice() { b"index" => s.index = Some(<_ as ReadWrite>::read(&mut v)?), + b"g_metallic" => s.g_metallic = Some(<_ as ReadWrite>::read(&mut v)?), + b"g_roughness" => s.g_roughness = Some(<_ as ReadWrite>::read(&mut v)?), + b"g_albedo" => s.g_albedo = Some(<_ as ReadWrite>::read(&mut v)?), + b"g_transmission" => s.g_transmission = Some(<_ as ReadWrite>::read(&mut v)?), b"va_position" => s.va_position = Some(<_ as ReadWrite>::read(&mut v)?), b"va_normal" => s.va_normal = Some(<_ as ReadWrite>::read(&mut v)?), b"va_texcoord" => s.va_texcoord = Some(<_ as ReadWrite>::read(&mut v)?), @@ -128,6 +133,13 @@ impl ReadWrite for Part { b"va_pbr_transmission" => { s.va_pbr_transmission = Some(<_ as ReadWrite>::read(&mut v)?) } + b"tex_normal" => s.tex_normal = Some(<_ as ReadWrite>::read(&mut v)?), + b"tex_pbr_roughness" => s.tex_pbr_roughness = Some(<_ as ReadWrite>::read(&mut v)?), + b"tex_pbr_metallic" => s.tex_pbr_metallic = Some(<_ as ReadWrite>::read(&mut v)?), + b"tex_pbr_albedo" => s.tex_pbr_albedo = Some(<_ as ReadWrite>::read(&mut v)?), + b"tex_pbr_transmission" => { + s.tex_pbr_transmission = Some(<_ as ReadWrite>::read(&mut v)?) + } x => warn!("unknown part key: {:?}", String::from_utf8_lossy(x)), } } @@ -149,6 +161,12 @@ fn read_kv(r: &mut &[u8]) -> Result<(Vec<u8>, Vec<u8>)> { Ok((key, value)) } +fn write_kv_opt(w: &mut dyn Write, key: &[u8], value: &Option<impl ReadWrite>) -> Result<()> { + if let Some(v) = value { + write_kv(w, key, &v.write_alloc())?; + } + Ok(()) +} fn write_kv(w: &mut dyn Write, key: &[u8], value: &[u8]) -> Result<()> { w.write_all(&(key.len() as u16).to_be_bytes())?; w.write_all(&(value.len() as u16).to_be_bytes())?; @@ -157,35 +175,6 @@ fn write_kv(w: &mut dyn Write, key: &[u8], value: &[u8]) -> Result<()> { Ok(()) } -impl ReadWrite for Attribute { - fn write(&self, w: &mut dyn Write) -> Result<()> { - match self { - Attribute::Constant(v) => { - w.write_all(&[0x01])?; - w.write_all(&v.to_be_bytes())?; - } - Attribute::Vertex(resource) => { - w.write_all(&[0x02])?; - resource.write(w)?; - } - Attribute::Texture(resource, channel) => { - w.write_all(&[0x03])?; - resource.write(w)?; - channel.write(w)?; - } - } - Ok(()) - } - fn read(r: &mut dyn Read) -> Result<Self> { - Ok(match u8::read(r)? { - 0x01 => Self::Constant(f32::read(r)?), - 0x02 => Self::Vertex(Resource::read(r)?), - 0x03 => Self::Texture(Resource::read(r)?, u8::read(r)?), - _ => bail!("unknown attribute tag"), - }) - } -} - impl ReadWrite for u8 { fn write(&self, w: &mut dyn Write) -> Result<()> { w.write_all(&[*self])?; diff --git a/world/Cargo.toml b/world/Cargo.toml index bdfc1f1..540b54b 100644 --- a/world/Cargo.toml +++ b/world/Cargo.toml @@ -10,4 +10,5 @@ env_logger = "0.11.6" gltf = { version = "1.4.1", features = ["extras", "names"] } log = "0.4.22" weareshared = { path = "../shared" } -rand = "0.9.0-beta.1"
\ No newline at end of file +rand = "0.9.0-beta.1" +image = "0.25.5" diff --git a/world/src/main.rs b/world/src/main.rs index 033d176..7bcd021 100644 --- a/world/src/main.rs +++ b/world/src/main.rs @@ -1,6 +1,7 @@ #![feature(iter_array_chunks)] use anyhow::Result; use clap::Parser; +use log::info; use rand::random; use std::{ io::Write, @@ -12,7 +13,7 @@ use std::{ use weareshared::{ Affine3A, Vec3A, packets::{Data, Object, Packet, ReadWrite}, - resources::{Attribute, AttributeArray, IndexArray, Part, Prefab}, + resources::{AttributeArray, IndexArray, Part, Prefab}, store::ResourceStore, vec3a, }; @@ -73,38 +74,34 @@ fn main() -> Result<()> { .array_chunks::<3>() .collect::<Vec<_>>(); - let mut albedo = None; + let mut tex_pbr_albedo = None; if let Some(tex) = p.material().pbr_metallic_roughness().base_color_texture() { let s = tex.texture().source().source(); if let gltf::image::Source::View { view, mime_type } = s { - let buf = &buffers[view.buffer().index()]; - albedo = Some(store.set(&buf.0)?); + info!("albedo texture is of type {mime_type:?}"); + let buf = &buffers[view.buffer().index()].0 + [view.offset()..view.offset() + view.length()]; + tex_pbr_albedo = Some(store.set(buf)?); } } let part = store.set( &Part { va_position: Some([ - Attribute::Vertex(store.set(&AttributeArray(pos_x).write_alloc())?), - Attribute::Vertex(store.set(&AttributeArray(pos_y).write_alloc())?), - Attribute::Vertex(store.set(&AttributeArray(pos_z).write_alloc())?), + store.set(&AttributeArray(pos_x).write_alloc())?, + store.set(&AttributeArray(pos_y).write_alloc())?, + store.set(&AttributeArray(pos_z).write_alloc())?, ]), va_normal: Some([ - Attribute::Vertex(store.set(&AttributeArray(norm_x).write_alloc())?), - Attribute::Vertex(store.set(&AttributeArray(norm_y).write_alloc())?), - Attribute::Vertex(store.set(&AttributeArray(norm_z).write_alloc())?), + store.set(&AttributeArray(norm_x).write_alloc())?, + store.set(&AttributeArray(norm_y).write_alloc())?, + store.set(&AttributeArray(norm_z).write_alloc())?, ]), va_texcoord: Some([ - Attribute::Vertex(store.set(&AttributeArray(uv_x).write_alloc())?), - Attribute::Vertex(store.set(&AttributeArray(uv_y).write_alloc())?), + store.set(&AttributeArray(uv_x).write_alloc())?, + store.set(&AttributeArray(uv_y).write_alloc())?, ]), - va_pbr_albedo: albedo.map(|a| { - [ - Attribute::Texture(a, 0), - Attribute::Texture(a, 1), - Attribute::Texture(a, 2), - ] - }), + tex_pbr_albedo, index: Some(store.set(&IndexArray(index).write_alloc())?), ..Part::default() } |