summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-01-07 12:25:37 +0100
committermetamuffin <metamuffin@disroot.org>2025-01-07 12:25:37 +0100
commitd81eebe423fd3e00df5ff035ec24fe7fb37f2c62 (patch)
treee96dddf8e179f47dc030729d6f725c30dfa372d9
parent31ae23b7eb8cd0b688be07ae6cb4b5a96ee02a68 (diff)
downloadweareserver-d81eebe423fd3e00df5ff035ec24fe7fb37f2c62.tar
weareserver-d81eebe423fd3e00df5ff035ec24fe7fb37f2c62.tar.bz2
weareserver-d81eebe423fd3e00df5ff035ec24fe7fb37f2c62.tar.zst
albedo texture works
-rw-r--r--Cargo.lock502
-rw-r--r--client/Cargo.toml1
-rw-r--r--client/src/renderer.rs15
-rw-r--r--client/src/scene_prepare.rs286
-rw-r--r--client/src/scene_render.rs109
-rw-r--r--client/src/shader.wgsl4
-rw-r--r--client/src/state.rs3
-rw-r--r--client/src/window.rs2
-rw-r--r--shared/src/packets.rs27
-rw-r--r--shared/src/resources.rs119
-rw-r--r--world/Cargo.toml3
-rw-r--r--world/src/main.rs35
12 files changed, 886 insertions, 220 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 54d9881..1d8744a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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()
}