sync
This commit is contained in:
parent
4caf348587
commit
6f1891f492
535
Cargo.lock
generated
535
Cargo.lock
generated
@ -93,6 +93,12 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aligned-vec"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1"
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.20"
|
||||
@ -114,6 +120,29 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
|
||||
|
||||
[[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 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.9"
|
||||
@ -159,6 +188,29 @@ version = "1.4.0"
|
||||
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 = "backtrace"
|
||||
version = "0.3.74"
|
||||
@ -195,6 +247,12 @@ version = "0.8.0"
|
||||
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"
|
||||
@ -207,6 +265,12 @@ version = "2.6.0"
|
||||
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"
|
||||
@ -222,6 +286,12 @@ dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[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"
|
||||
@ -254,6 +324,12 @@ version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder-lite"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.8.0"
|
||||
@ -266,9 +342,21 @@ version = "1.1.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[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"
|
||||
@ -335,6 +423,12 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "const_panic"
|
||||
version = "0.2.10"
|
||||
@ -457,6 +551,12 @@ version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[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.1.6"
|
||||
@ -554,6 +654,38 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||
name = "element_bridge"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "encase"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0a05902cf601ed11d564128448097b98ebe3c6574bd7b6a653a3d56d54aa020"
|
||||
dependencies = [
|
||||
"const_panic",
|
||||
"encase_derive",
|
||||
"glam",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encase_derive"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "181d475b694e2dd56ae919ce7699d344d1fd259292d590c723a50d1189a2ea85"
|
||||
dependencies = [
|
||||
"encase_derive_impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encase_derive_impl"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f97b51c5cc57ef7c5f7a0c57c250251c49ee4c28f819f87ac32f4aceabc36792"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
@ -570,6 +702,21 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[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.6"
|
||||
@ -764,6 +911,16 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[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 = "gimli"
|
||||
version = "0.31.1"
|
||||
@ -862,6 +1019,16 @@ dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
]
|
||||
|
||||
[[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.14.5"
|
||||
@ -878,6 +1045,12 @@ version = "0.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.9"
|
||||
@ -928,12 +1101,51 @@ dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.25.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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 = "imagesize"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284"
|
||||
|
||||
[[package]]
|
||||
name = "imgref"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.6.0"
|
||||
@ -944,6 +1156,17 @@ dependencies = [
|
||||
"hashbrown 0.15.1",
|
||||
]
|
||||
|
||||
[[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 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.11.0"
|
||||
@ -953,6 +1176,15 @@ dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.11"
|
||||
@ -965,6 +1197,21 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[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.72"
|
||||
@ -1007,12 +1254,28 @@ version = "1.5.0"
|
||||
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.162"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
|
||||
|
||||
[[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.7.4"
|
||||
@ -1071,6 +1334,15 @@ version = "0.4.22"
|
||||
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 = "makepad-android-state"
|
||||
version = "0.1.0"
|
||||
@ -1358,6 +1630,16 @@ dependencies = [
|
||||
"rawpointer",
|
||||
]
|
||||
|
||||
[[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"
|
||||
@ -1447,10 +1729,13 @@ name = "mp_elements"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"encase",
|
||||
"flume",
|
||||
"glam",
|
||||
"image",
|
||||
"mp_core",
|
||||
"pollster",
|
||||
"quick_cache",
|
||||
"regex",
|
||||
"wgpu",
|
||||
]
|
||||
@ -1582,6 +1867,12 @@ dependencies = [
|
||||
"jni-sys",
|
||||
]
|
||||
|
||||
[[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"
|
||||
@ -1592,6 +1883,12 @@ dependencies = [
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "noop_proc_macro"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
@ -1602,6 +1899,16 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[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-complex"
|
||||
version = "0.4.6"
|
||||
@ -1611,6 +1918,17 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.46"
|
||||
@ -1620,6 +1938,17 @@ 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"
|
||||
@ -1778,6 +2107,15 @@ dependencies = [
|
||||
"portable-atomic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "presser"
|
||||
version = "0.3.1"
|
||||
@ -1798,6 +2136,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 2.0.87",
|
||||
]
|
||||
|
||||
[[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_cache"
|
||||
@ -1827,12 +2193,92 @@ dependencies = [
|
||||
"abi_stable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "range-alloc"
|
||||
version = "0.1.3"
|
||||
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",
|
||||
"rand_chacha",
|
||||
"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.5.2"
|
||||
@ -2147,6 +2593,15 @@ version = "0.3.7"
|
||||
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 = "simplecss"
|
||||
version = "0.2.1"
|
||||
@ -2261,6 +2716,25 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[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"
|
||||
@ -2300,6 +2774,17 @@ dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[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"
|
||||
@ -2560,12 +3045,29 @@ dependencies = [
|
||||
"xmlwriter",
|
||||
]
|
||||
|
||||
[[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 = "valuable"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[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"
|
||||
@ -2578,7 +3080,7 @@ version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c73a36bc44e3039f51fbee93e39f41225f6b17b380eb70cc2aab942df06b34dd"
|
||||
dependencies = [
|
||||
"itertools",
|
||||
"itertools 0.11.0",
|
||||
"nom",
|
||||
]
|
||||
|
||||
@ -2675,6 +3177,12 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082"
|
||||
|
||||
[[package]]
|
||||
name = "wfd"
|
||||
version = "0.1.7"
|
||||
@ -3135,6 +3643,7 @@ version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
@ -3148,3 +3657,27 @@ dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zune-core"
|
||||
version = "0.4.12"
|
||||
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.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768"
|
||||
dependencies = [
|
||||
"zune-core",
|
||||
]
|
||||
|
||||
@ -11,3 +11,6 @@ wgpu = "23.0.0"
|
||||
mp_core = { path = "../mp_core", version = "*" }
|
||||
flume = "0.11.1"
|
||||
pollster = "0.4.0"
|
||||
quick_cache = "0.6.9"
|
||||
encase = {version="0.10.0",features=["glam"]}
|
||||
image = "0.25.5"
|
||||
|
||||
BIN
mp_elements/image.png
Normal file
BIN
mp_elements/image.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
@ -1,36 +1,43 @@
|
||||
#include "constants.wgsl";
|
||||
#include "colormap.wgsl";
|
||||
// Common Uniforms
|
||||
// common_tools
|
||||
// model_matrix: mat4,
|
||||
// view_matrix: mat4,
|
||||
// proj_matrix: mat4,
|
||||
// camera_position: vec3,
|
||||
// camera_front: vec3,
|
||||
// camera_up: vec3,
|
||||
// light_position: vec3,
|
||||
// light_color: vec3,
|
||||
// light_intensity: float,
|
||||
|
||||
@group(2) @binding(0) var<uniform> params: UniformParams;
|
||||
@group(2) @binding(1) var data_buffer: texture_3d<f32>;
|
||||
// Uniforms
|
||||
@group(1) @binding(0) var<uniform> params: UniformParams;
|
||||
// Data Buffer
|
||||
@group(1) @binding(1) var<storage> data: array<f32>;
|
||||
|
||||
struct UniformParams {
|
||||
origin: vec3f
|
||||
origin: vec4f
|
||||
}
|
||||
|
||||
struct VertexOutput {
|
||||
@location(0) position: vec4f,
|
||||
@location(1) r_range: vec2f,
|
||||
@location(2) idx: vec3f
|
||||
}
|
||||
|
||||
struct UniformParams {
|
||||
// Model-View-Projection matrix
|
||||
mvp: mat4x4f,
|
||||
origin: vec3f
|
||||
@builtin(position) position: vec4f,
|
||||
@location(0) r_range: vec2f,
|
||||
@location(1) idx: u32
|
||||
}
|
||||
|
||||
@vertex
|
||||
fn vertex(
|
||||
@location(0) position: vec3f,
|
||||
@location(1) r_range: vec2f,
|
||||
@location(2) idx: vec3f
|
||||
@location(2) idx: u32
|
||||
) -> VertexOutput {
|
||||
|
||||
var out: VertexOutput;
|
||||
|
||||
// Transform position
|
||||
out.position = params.mvp * vec4f(position, 1.0);
|
||||
// out.position = common_tools.proj_matrix * common_tools.view_matrix * common_tools.model_matrix * vec4f(position, 1.0);
|
||||
out.position = vec4(position, 1.0);
|
||||
out.r_range = r_range;
|
||||
out.idx = idx;
|
||||
|
||||
@ -45,20 +52,21 @@ fn polar_forward(cartesian: vec3f) -> vec3f {
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fragment(input: VertexOutput) -> location(0) vec4f {
|
||||
fn fragment(input: VertexOutput) -> @location(0) vec4f {
|
||||
// Sample data texture
|
||||
let value = textureSample(data_texture, data_sampler, input.idx).r;
|
||||
let ear = polar_forward(input.position);
|
||||
var color = linear_colormap(value);
|
||||
let value = data[input.idx];
|
||||
let ear = polar_forward(input.position.xyz);
|
||||
// var color = linear_colormap(value);
|
||||
var color = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
let r = ear.z;
|
||||
// Valid range
|
||||
let r_range = input.r_range;
|
||||
// let r_range = input.r_range;
|
||||
|
||||
let outside_lower_bound = step(r, r_range.x);
|
||||
let outside_upper_bound = step(r_range.y, r);
|
||||
let is_outside = outside_lower_bound + outside_upper_bound;
|
||||
color.a *= 1.0 - is_outside;
|
||||
// let outside_lower_bound = step(r, r_range.x);
|
||||
// let outside_upper_bound = step(r_range.y, r);
|
||||
// let is_outside = outside_lower_bound + outside_upper_bound;
|
||||
// color.a *= 1.0 - is_outside;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
@ -1,21 +1,26 @@
|
||||
use std::collections::HashMap;
|
||||
use quick_cache::unsync::Cache;
|
||||
use wgpu::util::DeviceExt;
|
||||
|
||||
use crate::elements::{ElementAttach, Elements, ElementsRef};
|
||||
use crate::elements::{Element, ElementAttach, ElementsRef};
|
||||
use crate::elementvec::ElementVec;
|
||||
use wgpu::{Backends, Instance};
|
||||
|
||||
use encase;
|
||||
|
||||
type DB = std::rc::Rc<wgpu::Buffer>;
|
||||
|
||||
const BACKENDS_DEFAULT: u32 = Backends::DX12.bits()
|
||||
| Backends::METAL.bits()
|
||||
| Backends::GL.bits()
|
||||
| Backends::BROWSER_WEBGPU.bits();
|
||||
|
||||
pub struct App {
|
||||
device: wgpu::Device,
|
||||
queue: wgpu::Queue,
|
||||
common_utils: CommonUtils,
|
||||
_texture: wgpu::Texture,
|
||||
_texture_size: wgpu::Extent3d,
|
||||
texture_view: wgpu::TextureView,
|
||||
pipelines: Option<ElementVec>,
|
||||
output: Output,
|
||||
pub pipelines: Option<ElementVec>,
|
||||
pub ctx: Ctx,
|
||||
|
||||
buffer_pool: DataBufferPool,
|
||||
}
|
||||
@ -49,13 +54,14 @@ impl App {
|
||||
let common_utils = CommonUtils::new(&device);
|
||||
|
||||
// Create a new texture. This texture will be used as the output texture for the render pass.
|
||||
let texture_size = wgpu::Extent3d {
|
||||
width: 256,
|
||||
height: 256,
|
||||
depth_or_array_layers: 1,
|
||||
};
|
||||
let texture = device.create_texture(&wgpu::TextureDescriptor {
|
||||
label: Some("output texture"),
|
||||
size: wgpu::Extent3d {
|
||||
width: 800,
|
||||
height: 600,
|
||||
depth_or_array_layers: 1,
|
||||
},
|
||||
size: texture_size,
|
||||
mip_level_count: 1,
|
||||
sample_count: 1,
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
@ -70,25 +76,29 @@ impl App {
|
||||
// Buffer pool
|
||||
let buffer_pool = DataBufferPool::new();
|
||||
|
||||
let ctx = Ctx::new(device, queue, common_utils);
|
||||
|
||||
let output = Output::new(&ctx.device);
|
||||
|
||||
Self {
|
||||
device,
|
||||
queue,
|
||||
common_utils,
|
||||
pipelines: None,
|
||||
_texture: texture,
|
||||
_texture_size: texture_size,
|
||||
texture_view,
|
||||
buffer_pool,
|
||||
output,
|
||||
ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new context struct. This struct contains references to the device, queue, bind group layout, and bind group.
|
||||
pub fn ctx(&self) -> Ctx {
|
||||
Ctx::new(self)
|
||||
pub fn ctx(&self) -> &Ctx {
|
||||
&self.ctx
|
||||
}
|
||||
|
||||
// Initialize the app. This method creates the pipelines and initializes the elements.
|
||||
pub async fn init(&mut self) {
|
||||
self.pipelines = Some(ElementVec::init(&Ctx::new(self)));
|
||||
self.pipelines = Some(ElementVec::init(&self.ctx));
|
||||
}
|
||||
|
||||
// Get a reference to the pipelines.
|
||||
@ -97,12 +107,13 @@ impl App {
|
||||
}
|
||||
|
||||
pub fn common_utils_mut(&mut self) -> &mut CommonUtils {
|
||||
&mut self.common_utils
|
||||
&mut self.ctx.common_tools
|
||||
}
|
||||
|
||||
// Draw the elements in the draw list.
|
||||
pub fn draw(&self, draw_list: DrawList) {
|
||||
pub async fn draw(&self, draw_list: DrawList<'_, '_>) {
|
||||
let mut encoder = self
|
||||
.ctx
|
||||
.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
label: Some("draw_command_encoder"),
|
||||
@ -124,7 +135,7 @@ impl App {
|
||||
let mut render_pass = encoder.begin_render_pass(&render_pass_desc);
|
||||
|
||||
// Set the common utils bind group.
|
||||
let common_utils = &self.common_utils.bind_group;
|
||||
let common_utils = &self.ctx.common_tools.bind_group;
|
||||
|
||||
// Draw each element in the draw list.
|
||||
for (attach, element) in draw_list.elements {
|
||||
@ -146,29 +157,42 @@ impl App {
|
||||
// Draw the element.
|
||||
element.draw(attach, &mut render_pass);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
self.queue.submit(Some(encoder.finish()));
|
||||
// output
|
||||
self.output.output(&mut encoder, &self._texture, self._texture_size, &self.ctx);
|
||||
self.ctx.queue.submit(Some(encoder.finish()));
|
||||
|
||||
self.output.get_data(&self.ctx).await;
|
||||
}
|
||||
|
||||
pub fn load_data<'a, T>(&mut self, element: &T, data: &T::Data) -> ElementAttach
|
||||
where
|
||||
T: Element,
|
||||
{
|
||||
let buffer_pool = &mut self.buffer_pool;
|
||||
let ctx = &self.ctx;
|
||||
element.load_data(&ctx, data, buffer_pool)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Ctx<'a> {
|
||||
pub device: &'a wgpu::Device,
|
||||
pub queue: &'a wgpu::Queue,
|
||||
pub common_tools_bind_group_layout: &'a wgpu::BindGroupLayout,
|
||||
pub common_tools_bind_group: &'a wgpu::BindGroup,
|
||||
pub struct Ctx {
|
||||
pub device: wgpu::Device,
|
||||
pub queue: wgpu::Queue,
|
||||
pub common_tools: CommonUtils,
|
||||
}
|
||||
|
||||
impl<'a> Ctx<'a> {
|
||||
impl Ctx {
|
||||
pub fn bind_group_layout(&self) -> Vec<wgpu::BindGroupLayout> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
pub fn new(app: &'a App) -> Self {
|
||||
fn new(device: wgpu::Device, queue: wgpu::Queue, common: CommonUtils) -> Self {
|
||||
Self {
|
||||
device: &app.device,
|
||||
queue: &app.queue,
|
||||
common_tools_bind_group_layout: &app.common_utils.bind_group_layout,
|
||||
common_tools_bind_group: &app.common_utils.bind_group,
|
||||
device,
|
||||
queue,
|
||||
common_tools: common,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -187,8 +211,9 @@ impl<'b, 'a: 'b> DrawList<'b, 'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
#[repr(C)]
|
||||
// #[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable, Default)]
|
||||
// #[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, encase::ShaderType, Default)]
|
||||
pub struct CommonUniform {
|
||||
pub model_matrix: glam::Mat4,
|
||||
pub view_matrix: glam::Mat4,
|
||||
@ -201,6 +226,14 @@ pub struct CommonUniform {
|
||||
pub light_intensity: f32,
|
||||
}
|
||||
|
||||
impl CommonUniform {
|
||||
fn as_slice(&self) -> encase::internal::Result<Vec<u8>> {
|
||||
let mut buffer = encase::UniformBuffer::new(Vec::new());
|
||||
buffer.write(self)?;
|
||||
Ok(buffer.into_inner())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CommonUtils {
|
||||
pub bind_group_layout: wgpu::BindGroupLayout,
|
||||
pub bind_group: wgpu::BindGroup,
|
||||
@ -223,11 +256,12 @@ impl CommonUtils {
|
||||
}],
|
||||
});
|
||||
|
||||
let buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
let common_uniform = CommonUniform::default();
|
||||
|
||||
let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("common_utils_buffer"),
|
||||
size: std::mem::size_of::<CommonUniform>() as u64,
|
||||
contents: &common_uniform.as_slice().unwrap(),
|
||||
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::UNIFORM,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
|
||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
@ -248,25 +282,122 @@ impl CommonUtils {
|
||||
}
|
||||
|
||||
pub struct DataBufferPool {
|
||||
buffers: HashMap<BufferKey, wgpu::Buffer>,
|
||||
// buffers: HashMap<BufferKey, wgpu::Buffer>,
|
||||
buffers: Cache<BufferKey, DB>,
|
||||
}
|
||||
|
||||
impl DataBufferPool {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
buffers: HashMap::new(),
|
||||
buffers: Cache::new(10),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_or_create_buffer(&mut self) {}
|
||||
pub fn get_or_create_buffer<F>(&mut self, key: BufferKey, f: F) -> Option<&DB>
|
||||
where
|
||||
F: FnOnce() -> wgpu::Buffer,
|
||||
{
|
||||
let buffer = self
|
||||
.buffers
|
||||
.get_or_insert_with(&key, || {
|
||||
Ok::<std::rc::Rc<wgpu::Buffer>, ()>(std::rc::Rc::new(f()))
|
||||
})
|
||||
.unwrap();
|
||||
buffer
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||
pub struct BufferKey {
|
||||
pub size: u64,
|
||||
pub id: u64,
|
||||
pub from: String,
|
||||
}
|
||||
|
||||
impl BufferKey {
|
||||
pub fn new(from: String) -> Self {
|
||||
Self { id: 0, from }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Output {
|
||||
output_buffer: wgpu::Buffer,
|
||||
}
|
||||
|
||||
impl Output {
|
||||
pub fn new(device: &wgpu::Device) -> Self {
|
||||
let u32_size = std::mem::size_of::<u32>() as u32;
|
||||
|
||||
let output_buffer_size = (u32_size * 256 * 256) as wgpu::BufferAddress;
|
||||
let output_buffer_desc = wgpu::BufferDescriptor {
|
||||
size: output_buffer_size,
|
||||
usage: wgpu::BufferUsages::COPY_DST
|
||||
// MAP_READ 告诉 wpgu 我们要在 cpu 端读取此缓冲区
|
||||
| wgpu::BufferUsages::MAP_READ,
|
||||
label: None,
|
||||
mapped_at_creation: false,
|
||||
};
|
||||
let output_buffer = device.create_buffer(&output_buffer_desc);
|
||||
|
||||
Self { output_buffer }
|
||||
}
|
||||
|
||||
pub fn output(
|
||||
&self,
|
||||
encoder: &mut wgpu::CommandEncoder,
|
||||
texture: &wgpu::Texture,
|
||||
texture_size: wgpu::Extent3d,
|
||||
ctx: &Ctx,
|
||||
) {
|
||||
let u32_size = std::mem::size_of::<u32>() as u32;
|
||||
|
||||
encoder.copy_texture_to_buffer(
|
||||
wgpu::ImageCopyTexture {
|
||||
aspect: wgpu::TextureAspect::All,
|
||||
texture: &texture,
|
||||
mip_level: 0,
|
||||
origin: wgpu::Origin3d::ZERO,
|
||||
},
|
||||
wgpu::ImageCopyBuffer {
|
||||
buffer: &self.output_buffer,
|
||||
layout: wgpu::ImageDataLayout {
|
||||
offset: 0,
|
||||
bytes_per_row: Some(u32_size * 256),
|
||||
rows_per_image: Some(256),
|
||||
},
|
||||
},
|
||||
texture_size,
|
||||
);
|
||||
}
|
||||
|
||||
pub async fn get_data(&self,ctx: &Ctx) {
|
||||
let device = &ctx.device;
|
||||
// 需要对映射变量设置范围,以便我们能够解除缓冲区的映射
|
||||
let buffer_slice = self.output_buffer.slice(..);
|
||||
|
||||
// 注意:我们必须在 await future 之前先创建映射,然后再调用 device.poll()。
|
||||
// 否则,应用程序将停止响应。
|
||||
let (tx, rx) = flume::bounded(1);
|
||||
buffer_slice.map_async(wgpu::MapMode::Read, move |result| {
|
||||
tx.send(result).unwrap();
|
||||
});
|
||||
device.poll(wgpu::Maintain::Wait).panic_on_timeout();
|
||||
if let Ok(Ok(())) = rx.recv_async().await {
|
||||
let data = buffer_slice.get_mapped_range();
|
||||
|
||||
use image::{ImageBuffer, Rgba};
|
||||
let buffer =
|
||||
ImageBuffer::<Rgba<u8>, _>::from_raw(256,256, data).unwrap();
|
||||
buffer.save("image.png").unwrap();
|
||||
println!("保存图片成功!");
|
||||
|
||||
// 解除缓冲区映射
|
||||
self.output_buffer.unmap();
|
||||
} else {
|
||||
panic!("从 gpu 读取数据失败!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod test {
|
||||
use mp_core::{PluginManager, RadarGridData};
|
||||
|
||||
@ -275,39 +406,37 @@ mod test {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn test_app() {
|
||||
let plugin_manager = PluginManager::new("/Users/tsuki/projects/mp/loaders").unwrap();
|
||||
let plugin_manager =
|
||||
PluginManager::new(r#"C:\Users\qwin7\projects\radarmp\loaders"#).unwrap();
|
||||
|
||||
let data = plugin_manager.try_load_data(
|
||||
"/Users/tsuki/Desktop/Z_RADR_I_X5775_20230726180000_O_DOR-XPD-CAP-FMT.BIN.zip",
|
||||
// "/Users/tsuki/Desktop/Z_RADR_I_X5775_20230726180000_O_DOR-XPD-CAP-FMT.BIN.zip",
|
||||
r#"C:\Users\qwin7\Downloads\ZJSXAA_20230113070200_R.dat.gz"#,
|
||||
);
|
||||
|
||||
pollster::block_on(async {
|
||||
let mut app = App::instant().await;
|
||||
app.init().await;
|
||||
|
||||
let pipelines = app.pipelines();
|
||||
let ctx = app.ctx();
|
||||
|
||||
let pipelines = app.pipelines.as_ref().unwrap();
|
||||
let ppi = pipelines.ppi();
|
||||
let ctx = &app.ctx;
|
||||
let buffer_pool = &mut app.buffer_pool;
|
||||
|
||||
if let Ok(data) = data {
|
||||
let first_block = data.first().unwrap();
|
||||
|
||||
// Convert the first block into a PPI struct.
|
||||
if let Ok(data) = first_block.try_into() {
|
||||
let buffer_pool = &mut app.buffer_pool;
|
||||
// Reused buffer is None, so a new attachment is created.
|
||||
let attachment = ppi.new_attachment(&ctx, buffer_pool);
|
||||
|
||||
// Load the data into the attachment.
|
||||
ppi.load_data(&ctx, data, &attachment);
|
||||
let attachment = ppi.load_data(&ctx, data, buffer_pool);
|
||||
|
||||
// Create a new draw list and push the attachment into it.
|
||||
|
||||
let mut draw_list = DrawList::new();
|
||||
draw_list.push(ppi, &attachment);
|
||||
|
||||
// Draw the elements in the draw list.
|
||||
app.draw(draw_list);
|
||||
app.draw(draw_list).await;
|
||||
}
|
||||
} else {
|
||||
panic!("Failed to load data");
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
pub mod ppi;
|
||||
use crate::app::{Ctx, DataBufferPool};
|
||||
use crate::app::{BufferKey, Ctx, DataBufferPool};
|
||||
pub use ppi::PPI;
|
||||
use std::any::Any;
|
||||
use wgpu::util::DeviceExt;
|
||||
@ -54,6 +54,7 @@ macro_rules! elements {
|
||||
$(ElementsRef::$element_name(element) => element.draw(attach, render_pass),)+
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
@ -66,7 +67,7 @@ pub trait Element {
|
||||
|
||||
fn new(ctx: &Ctx) -> Self;
|
||||
|
||||
fn new_attachment<'a>(&self, ctx: &Ctx, buffer_pool: &'a mut DataBufferPool) -> ElementAttach;
|
||||
// fn new_attachment<'a>(&self, ctx: &Ctx) -> ElementAttach;
|
||||
|
||||
// Bake the data into vertices and indices
|
||||
fn bake(&self, data: &Self::Data) -> (Vec<Self::Vertex>, Option<Vec<u32>>);
|
||||
@ -79,7 +80,12 @@ pub trait Element {
|
||||
|
||||
fn draw(&self, attach: &ElementAttach, render_pass: &mut wgpu::RenderPass);
|
||||
|
||||
fn load_data(&self, ctx: &Ctx, data: &Self::Data, attach: &ElementAttach);
|
||||
fn load_data(
|
||||
&self,
|
||||
ctx: &Ctx,
|
||||
data: &Self::Data,
|
||||
buffer_pool: &mut DataBufferPool,
|
||||
) -> ElementAttach;
|
||||
}
|
||||
|
||||
pub struct ElementAttach {
|
||||
@ -88,6 +94,7 @@ pub struct ElementAttach {
|
||||
pub num_indices: u32,
|
||||
pub uniform_buffer: Option<wgpu::Buffer>,
|
||||
pub bind_group: Vec<(u32, wgpu::BindGroup)>,
|
||||
pub data_buffer_key: Option<BufferKey>,
|
||||
}
|
||||
|
||||
impl ElementAttach {
|
||||
@ -95,7 +102,7 @@ impl ElementAttach {
|
||||
where
|
||||
T: bytemuck::Zeroable + bytemuck::Pod,
|
||||
{
|
||||
let device = ctx.device;
|
||||
let device = &ctx.device;
|
||||
}
|
||||
|
||||
pub fn bind(&self, render_pass: &mut wgpu::RenderPass) {
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
use std::{ops::Sub, result};
|
||||
use std::{ops::Sub, result, vec};
|
||||
|
||||
use crate::{
|
||||
app::{Ctx, DataBufferPool},
|
||||
app::{BufferKey, Ctx, DataBufferPool},
|
||||
utils::merge_shader,
|
||||
};
|
||||
use bytemuck;
|
||||
use glam::Vec3;
|
||||
use glam::{Vec3, Vec4};
|
||||
use mp_core::{data::CoordType, RadarGridData};
|
||||
use wgpu::util::DeviceExt;
|
||||
|
||||
use super::{Element, ElementAttach};
|
||||
|
||||
@ -22,7 +23,7 @@ pub struct PPI {
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
pub struct PPIUniform {
|
||||
origin: Vec3,
|
||||
origin: Vec4,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@ -30,7 +31,7 @@ pub struct PPIUniform {
|
||||
pub struct PPIVertex {
|
||||
position: Vec3,
|
||||
r_ranges: [f32; 2],
|
||||
idx: [u32; 3],
|
||||
idx: u32,
|
||||
}
|
||||
|
||||
impl PPIVertex {
|
||||
@ -52,7 +53,7 @@ impl PPIVertex {
|
||||
wgpu::VertexAttribute {
|
||||
offset: std::mem::size_of::<[f32; 2]>() as wgpu::BufferAddress,
|
||||
shader_location: 2,
|
||||
format: wgpu::VertexFormat::Uint32x3,
|
||||
format: wgpu::VertexFormat::Uint32,
|
||||
},
|
||||
],
|
||||
}
|
||||
@ -65,7 +66,7 @@ impl Element for PPI {
|
||||
type Data = RadarGridData;
|
||||
|
||||
fn new(ctx: &Ctx) -> Self {
|
||||
let device = ctx.device;
|
||||
let device = &ctx.device;
|
||||
// Group Layout
|
||||
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: Some("PPI Bind Group Layout"),
|
||||
@ -102,7 +103,7 @@ impl Element for PPI {
|
||||
label: Some("PPI Render Pipeline Layout"),
|
||||
bind_group_layouts: &[
|
||||
// common_tools
|
||||
&ctx.common_tools_bind_group_layout,
|
||||
&ctx.common_tools.bind_group_layout,
|
||||
// ppi
|
||||
&bind_group_layout,
|
||||
],
|
||||
@ -124,7 +125,7 @@ impl Element for PPI {
|
||||
compilation_options: Default::default(),
|
||||
entry_point: Some("fragment"),
|
||||
targets: &[Some(wgpu::ColorTargetState {
|
||||
format: wgpu::TextureFormat::Bgra8UnormSrgb,
|
||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||
blend: None,
|
||||
write_mask: wgpu::ColorWrites::ALL,
|
||||
})],
|
||||
@ -155,65 +156,6 @@ impl Element for PPI {
|
||||
}
|
||||
}
|
||||
|
||||
fn new_attachment<'a>(&self, ctx: &Ctx, buffer_pool: &'a mut DataBufferPool) -> ElementAttach {
|
||||
let device = ctx.device;
|
||||
|
||||
// Buffers
|
||||
|
||||
let data_buffer = buffer_pool.get_or_create_buffer();
|
||||
// let data_buffer = if let Some(reused) = reused_buffer {
|
||||
// reused[0]
|
||||
// } else {
|
||||
// &Self::create_data_buffer(device)
|
||||
// };
|
||||
|
||||
let uniform_buffer = Self::create_uniform_buffer(device);
|
||||
|
||||
// Bind Group
|
||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
layout: &self.bind_group_layout,
|
||||
entries: &[
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: uniform_buffer.as_entire_binding(),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: data_buffer.as_entire_binding(),
|
||||
},
|
||||
],
|
||||
label: Some("PPI Bind Group"),
|
||||
});
|
||||
|
||||
// Vertex Buffer
|
||||
let vertex_buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: Some("PPI Vertex Buffer"),
|
||||
mapped_at_creation: false,
|
||||
size: std::mem::size_of::<PPIVertex>() as wgpu::BufferAddress * EMAXNUM * AMAXNUM,
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
|
||||
// Index Buffer
|
||||
let index_buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: Some("PPI Index Buffer"),
|
||||
mapped_at_creation: false,
|
||||
size: EMAXNUM
|
||||
* AMAXNUM
|
||||
* RMAXNUM
|
||||
* 6
|
||||
* std::mem::size_of::<u32>() as wgpu::BufferAddress,
|
||||
usage: wgpu::BufferUsages::INDEX,
|
||||
});
|
||||
|
||||
ElementAttach {
|
||||
vertex_buffer,
|
||||
index_buffer: Some(index_buffer),
|
||||
num_indices: 0,
|
||||
uniform_buffer: Some(uniform_buffer),
|
||||
bind_group: vec![(1, bind_group)],
|
||||
}
|
||||
}
|
||||
|
||||
fn bake(&self, data: &Self::Data) -> (Vec<Self::Vertex>, Option<Vec<u32>>) {
|
||||
let coord_typ = data.coord_type().unwrap();
|
||||
|
||||
@ -240,34 +182,83 @@ impl Element for PPI {
|
||||
render_pass.draw_indexed(0..attach.num_indices, 0, 0..1);
|
||||
}
|
||||
|
||||
fn load_data(&self, ctx: &Ctx, data: &Self::Data, attach: &ElementAttach) {
|
||||
fn load_data(
|
||||
&self,
|
||||
ctx: &Ctx,
|
||||
data: &Self::Data,
|
||||
buffer_pool: &mut DataBufferPool,
|
||||
) -> ElementAttach {
|
||||
let (vertex, index) = self.bake(data);
|
||||
let queue = ctx.queue;
|
||||
let device = &ctx.device;
|
||||
|
||||
// Update Vertex Buffer
|
||||
let vertex_buffer = &attach.vertex_buffer;
|
||||
queue.write_buffer(vertex_buffer, 0, bytemuck::cast_slice(&vertex));
|
||||
let uniform_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("PPI Uniform Buffer"),
|
||||
contents: bytemuck::cast_slice(&[PPIUniform {
|
||||
origin: Vec4::new(0.0, 0.0, 0.0, 0.0),
|
||||
}]),
|
||||
usage: wgpu::BufferUsages::COPY_SRC | wgpu::BufferUsages::UNIFORM,
|
||||
});
|
||||
|
||||
// Update Index Buffer
|
||||
if let Some(indices) = index {
|
||||
let index_buffer = attach.index_buffer.as_ref().unwrap();
|
||||
queue.write_buffer(index_buffer, 0, bytemuck::cast_slice(&indices));
|
||||
}
|
||||
// Vertex Buffer
|
||||
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("PPI Vertex Buffer"),
|
||||
contents: bytemuck::cast_slice(&vertex),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
|
||||
// Index Buffer
|
||||
let num_indices = index.as_ref().unwrap().len() as u32;
|
||||
let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("PPI Index Buffer"),
|
||||
contents: bytemuck::cast_slice(&index.unwrap()),
|
||||
usage: wgpu::BufferUsages::INDEX,
|
||||
});
|
||||
|
||||
// Load Data
|
||||
let data_array = data.get_data();
|
||||
let data_array_f32 = data_array.cast_to::<f32>();
|
||||
queue.write_buffer(
|
||||
data_buffer,
|
||||
0,
|
||||
bytemuck::cast_slice(data_array_f32.as_slice().unwrap()),
|
||||
);
|
||||
|
||||
let key = self.generate_key(data);
|
||||
let buffer = buffer_pool.get_or_create_buffer(key.clone(), || {
|
||||
device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("PPI Texture Buffer"),
|
||||
contents: bytemuck::cast_slice(data_array_f32.as_slice().unwrap()),
|
||||
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::STORAGE,
|
||||
})
|
||||
});
|
||||
let data_buffer = buffer.unwrap();
|
||||
|
||||
// Bind Group
|
||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
layout: &self.bind_group_layout,
|
||||
entries: &[
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: uniform_buffer.as_entire_binding(),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: data_buffer.as_entire_binding(),
|
||||
},
|
||||
],
|
||||
label: Some("PPI Bind Group"),
|
||||
});
|
||||
|
||||
ElementAttach {
|
||||
vertex_buffer: vertex_buffer,
|
||||
index_buffer: Some(index_buffer),
|
||||
num_indices,
|
||||
uniform_buffer: Some(uniform_buffer),
|
||||
bind_group: vec![(1, bind_group)],
|
||||
data_buffer_key: Some(key),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PPI {
|
||||
fn init_shader(device: &wgpu::Device) -> wgpu::ShaderModule {
|
||||
let shader_str = merge_shader("../../shaders/ppi.wgsl");
|
||||
let shader_str =
|
||||
merge_shader(r#"C:\Users\qwin7\projects\radarmp\mp_elements\shaders\ppi.wgsl"#);
|
||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||
label: Some("PPI Shader Module"),
|
||||
source: wgpu::ShaderSource::Wgsl(shader_str.into()),
|
||||
@ -278,7 +269,7 @@ impl PPI {
|
||||
fn create_uniform_buffer(device: &wgpu::Device) -> wgpu::Buffer {
|
||||
let buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: Some("PPI Uniform Buffer"),
|
||||
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::STORAGE,
|
||||
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::UNIFORM,
|
||||
size: 0,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
@ -286,15 +277,13 @@ impl PPI {
|
||||
buffer
|
||||
}
|
||||
|
||||
fn create_data_buffer(device: &wgpu::Device) -> wgpu::Buffer {
|
||||
let buffer = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: Some("PPI Texture Buffer"),
|
||||
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::STORAGE,
|
||||
size: 0,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
|
||||
buffer
|
||||
fn generate_key(&self, data: &RadarGridData) -> BufferKey {
|
||||
let key_name = format!(
|
||||
"ppi_{}_{}",
|
||||
data.info.value_name,
|
||||
data.info.datetime.unwrap().timestamp()
|
||||
);
|
||||
BufferKey::new(key_name)
|
||||
}
|
||||
|
||||
fn bake_vi(e: f64, a: &Vec<f64>, r: &Vec<f64>) -> (Vec<PPIVertex>, Vec<u32>) {
|
||||
@ -312,7 +301,7 @@ impl PPI {
|
||||
for (a_idx, _a) in sorted_azimuth.into_iter().enumerate() {
|
||||
for (r_idx, _r) in r.iter().enumerate() {
|
||||
let r_ranges = [*_r as f32 - r_step_f32, *_r as f32 + r_step_f32];
|
||||
let idx = [0, a_idx as u32, r_idx as u32];
|
||||
let idx = (a_idx * r.len() + r_idx) as u32;
|
||||
// Left Top
|
||||
let lt = polar_to_cartesian(*_r + r_step, _a - azi_step, e);
|
||||
vertexs.push(PPIVertex {
|
||||
|
||||
@ -5,15 +5,22 @@ pub(crate) fn merge_shader<'a>(shader: &'a str) -> String {
|
||||
const TOOLS: &'static str = r#"// This is a tool that merges the shader code with the shader code from the shader module.
|
||||
|
||||
struct UniformCommonTools {
|
||||
model_matrix: mat4,
|
||||
view_matrix: mat4,
|
||||
proj_matrix: mat4,
|
||||
camera_position: vec3,
|
||||
camera_front: vec3,
|
||||
camera_up: vec3,
|
||||
light_position: vec3,
|
||||
light_color: vec3,
|
||||
light_intensity: float,
|
||||
model_matrix: mat4x4f,
|
||||
view_matrix: mat4x4f,
|
||||
proj_matrix: mat4x4f,
|
||||
camera_x: f32,
|
||||
camera_y: f32,
|
||||
camera_z: f32,
|
||||
camera_target_x: f32,
|
||||
camera_target_y: f32,
|
||||
camera_target_z: f32,
|
||||
camera_up_x: f32,
|
||||
camera_up_y: f32,
|
||||
camera_up_z: f32,
|
||||
|
||||
// camera_position: vec3f,
|
||||
// camera_front: vec3f,
|
||||
// camera_up: vec3f,
|
||||
}
|
||||
|
||||
@group(0) @binding(0) var<uniform> common_tools: UniformCommonTools;
|
||||
@ -25,7 +32,8 @@ struct UniformCommonTools {
|
||||
let base = match path.canonicalize() {
|
||||
Ok(path) => path.parent().unwrap().to_owned(),
|
||||
Err(e) => {
|
||||
panic!("Failed to canonicalize path: {}", e);
|
||||
// panic!("Failed to canonicalize path: {}", e);
|
||||
PathBuf::from(r#"C:\Users\qwin7\projects\radarmp\mp_elements\shaders"#)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user