Compare commits
2 Commits
3e713b13a8
...
11bc0b30d2
| Author | SHA1 | Date | |
|---|---|---|---|
| 11bc0b30d2 | |||
| 1b2c1a387a |
|
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.18)
|
cmake_minimum_required(VERSION 3.18)
|
||||||
|
|
||||||
project(PROJECT-NAME VERSION 1.0.0 LANGUAGES CXX)
|
project(particle_matter VERSION 1.0.0 LANGUAGES CXX)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
|
||||||
196
Cargo.lock
generated
196
Cargo.lock
generated
|
|
@ -2,27 +2,6 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "PROJECT-NAME"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"glam",
|
|
||||||
"pollster",
|
|
||||||
"wgpu",
|
|
||||||
"winit",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "PROJECT-NAME-impl"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"PROJECT-NAME",
|
|
||||||
"glam",
|
|
||||||
"pollster",
|
|
||||||
"raw-window-handle",
|
|
||||||
"wgpu",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ab_glyph"
|
name = "ab_glyph"
|
||||||
version = "0.2.32"
|
version = "0.2.32"
|
||||||
|
|
@ -52,6 +31,12 @@ dependencies = [
|
||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "allocator-api2"
|
||||||
|
version = "0.2.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android-activity"
|
name = "android-activity"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
|
|
@ -526,6 +511,9 @@ name = "glam"
|
||||||
version = "0.30.10"
|
version = "0.30.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "19fc433e8437a212d1b6f1e68c7824af3aed907da60afa994e7f542d18d12aa9"
|
checksum = "19fc433e8437a212d1b6f1e68c7824af3aed907da60afa994e7f542d18d12aa9"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glow"
|
name = "glow"
|
||||||
|
|
@ -548,34 +536,17 @@ dependencies = [
|
||||||
"gl_generator",
|
"gl_generator",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gpu-alloc"
|
|
||||||
version = "0.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 2.10.0",
|
|
||||||
"gpu-alloc-types",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "gpu-alloc-types"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags 2.10.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gpu-allocator"
|
name = "gpu-allocator"
|
||||||
version = "0.27.0"
|
version = "0.28.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd"
|
checksum = "51255ea7cfaadb6c5f1528d43e92a82acb2b96c43365989a28b2d44ee38f8795"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"ash",
|
||||||
|
"hashbrown 0.16.1",
|
||||||
"log",
|
"log",
|
||||||
"presser",
|
"presser",
|
||||||
"thiserror 1.0.69",
|
"thiserror 2.0.18",
|
||||||
"windows",
|
"windows",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -626,6 +597,8 @@ version = "0.16.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"allocator-api2",
|
||||||
|
"equivalent",
|
||||||
"foldhash 0.2.0",
|
"foldhash 0.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -802,9 +775,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "metal"
|
name = "metal"
|
||||||
version = "0.32.0"
|
version = "0.33.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "00c15a6f673ff72ddcc22394663290f870fb224c1bfce55734a75c414150e605"
|
checksum = "c7047791b5bc903b8cd963014b355f71dc9864a9a0b727057676c1dcae5cbc15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.10.0",
|
"bitflags 2.10.0",
|
||||||
"block",
|
"block",
|
||||||
|
|
@ -817,9 +790,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "naga"
|
name = "naga"
|
||||||
version = "27.0.3"
|
version = "28.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "066cf25f0e8b11ee0df221219010f213ad429855f57c494f995590c861a9a7d8"
|
checksum = "618f667225063219ddfc61251087db8a9aec3c3f0950c916b614e403486f1135"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bit-set",
|
"bit-set",
|
||||||
|
|
@ -1172,6 +1145,28 @@ dependencies = [
|
||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "particle_matter"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
"glam",
|
||||||
|
"pollster",
|
||||||
|
"wgpu",
|
||||||
|
"winit",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "particle_matter-impl"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"glam",
|
||||||
|
"particle_matter",
|
||||||
|
"pollster",
|
||||||
|
"raw-window-handle",
|
||||||
|
"wgpu",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste"
|
name = "paste"
|
||||||
version = "1.0.15"
|
version = "1.0.15"
|
||||||
|
|
@ -1910,12 +1905,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu"
|
name = "wgpu"
|
||||||
version = "27.0.1"
|
version = "28.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bfe68bac7cde125de7a731c3400723cadaaf1703795ad3f4805f187459cd7a77"
|
checksum = "f9cb534d5ffd109c7d1135f34cdae29e60eab94855a625dcfe1705f8bc7ad79f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bitflags 2.10.0",
|
"bitflags 2.10.0",
|
||||||
|
"bytemuck",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cfg_aliases",
|
"cfg_aliases",
|
||||||
"document-features",
|
"document-features",
|
||||||
|
|
@ -1939,9 +1935,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-core"
|
name = "wgpu-core"
|
||||||
version = "27.0.3"
|
version = "28.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "27a75de515543b1897b26119f93731b385a19aea165a1ec5f0e3acecc229cae7"
|
checksum = "8bb4c8b5db5f00e56f1f08869d870a0dff7c8bc7ebc01091fec140b0cf0211a9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bit-set",
|
"bit-set",
|
||||||
|
|
@ -1971,36 +1967,36 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-core-deps-apple"
|
name = "wgpu-core-deps-apple"
|
||||||
version = "27.0.0"
|
version = "28.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0772ae958e9be0c729561d5e3fd9a19679bcdfb945b8b1a1969d9bfe8056d233"
|
checksum = "87b7b696b918f337c486bf93142454080a32a37832ba8a31e4f48221890047da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wgpu-hal",
|
"wgpu-hal",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-core-deps-emscripten"
|
name = "wgpu-core-deps-emscripten"
|
||||||
version = "27.0.0"
|
version = "28.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b06ac3444a95b0813ecfd81ddb2774b66220b264b3e2031152a4a29fda4da6b5"
|
checksum = "34b251c331f84feac147de3c4aa3aa45112622a95dd7ee1b74384fa0458dbd79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wgpu-hal",
|
"wgpu-hal",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-core-deps-windows-linux-android"
|
name = "wgpu-core-deps-windows-linux-android"
|
||||||
version = "27.0.0"
|
version = "28.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71197027d61a71748e4120f05a9242b2ad142e3c01f8c1b47707945a879a03c3"
|
checksum = "68ca976e72b2c9964eb243e281f6ce7f14a514e409920920dcda12ae40febaae"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wgpu-hal",
|
"wgpu-hal",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-hal"
|
name = "wgpu-hal"
|
||||||
version = "27.0.4"
|
version = "28.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b21cb61c57ee198bc4aff71aeadff4cbb80b927beb912506af9c780d64313ce"
|
checksum = "293080d77fdd14d6b08a67c5487dfddbf874534bb7921526db56a7b75d7e3bef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android_system_properties",
|
"android_system_properties",
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
|
|
@ -2014,7 +2010,6 @@ dependencies = [
|
||||||
"core-graphics-types 0.2.0",
|
"core-graphics-types 0.2.0",
|
||||||
"glow",
|
"glow",
|
||||||
"glutin_wgl_sys",
|
"glutin_wgl_sys",
|
||||||
"gpu-alloc",
|
|
||||||
"gpu-allocator",
|
"gpu-allocator",
|
||||||
"gpu-descriptor",
|
"gpu-descriptor",
|
||||||
"hashbrown 0.16.1",
|
"hashbrown 0.16.1",
|
||||||
|
|
@ -2047,15 +2042,14 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wgpu-types"
|
name = "wgpu-types"
|
||||||
version = "27.0.1"
|
version = "28.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "afdcf84c395990db737f2dd91628706cb31e86d72e53482320d368e52b5da5eb"
|
checksum = "e18308757e594ed2cd27dddbb16a139c42a683819d32a2e0b1b0167552f5840c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.10.0",
|
"bitflags 2.10.0",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"thiserror 2.0.18",
|
|
||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2070,32 +2064,54 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows"
|
name = "windows"
|
||||||
version = "0.58.0"
|
version = "0.62.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
|
checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
|
||||||
|
dependencies = [
|
||||||
|
"windows-collections",
|
||||||
|
"windows-core",
|
||||||
|
"windows-future",
|
||||||
|
"windows-numerics",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-collections"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-core",
|
"windows-core",
|
||||||
"windows-targets 0.52.6",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-core"
|
name = "windows-core"
|
||||||
version = "0.58.0"
|
version = "0.62.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
|
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-implement",
|
"windows-implement",
|
||||||
"windows-interface",
|
"windows-interface",
|
||||||
|
"windows-link",
|
||||||
"windows-result",
|
"windows-result",
|
||||||
"windows-strings",
|
"windows-strings",
|
||||||
"windows-targets 0.52.6",
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-future"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb"
|
||||||
|
dependencies = [
|
||||||
|
"windows-core",
|
||||||
|
"windows-link",
|
||||||
|
"windows-threading",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-implement"
|
name = "windows-implement"
|
||||||
version = "0.58.0"
|
version = "0.60.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
|
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -2104,9 +2120,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-interface"
|
name = "windows-interface"
|
||||||
version = "0.58.0"
|
version = "0.59.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
|
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
@ -2120,22 +2136,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-result"
|
name = "windows-numerics"
|
||||||
version = "0.2.0"
|
version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
|
checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets 0.52.6",
|
"windows-core",
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-strings"
|
name = "windows-strings"
|
||||||
version = "0.1.0"
|
version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
|
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-result",
|
"windows-link",
|
||||||
"windows-targets 0.52.6",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2205,6 +2230,15 @@ dependencies = [
|
||||||
"windows_x86_64_msvc 0.52.6",
|
"windows_x86_64_msvc 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-threading"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_gnullvm"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
members = ["ui"]
|
members = ["ui"]
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "PROJECT-NAME"
|
name = "particle_matter"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
|
|
@ -18,7 +18,8 @@ debug = false
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
glam = { version = "0.30.9" }
|
bytemuck = "1.24.0"
|
||||||
|
glam = { version = "0.30.9", features = ["bytemuck"] }
|
||||||
pollster = "0.4.0"
|
pollster = "0.4.0"
|
||||||
wgpu = "27.0.1"
|
wgpu = "28.0.0"
|
||||||
winit = "0.30.12"
|
winit = "0.30.12"
|
||||||
|
|
|
||||||
41
src/lib.rs
41
src/lib.rs
|
|
@ -1,9 +1,10 @@
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
use glam::{UVec2, Vec4};
|
use glam::{UVec2, Vec4, vec2};
|
||||||
|
|
||||||
const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth16Unorm;
|
use crate::render::{DEPTH_FORMAT, OUTPUT_FORMAT};
|
||||||
const OUTPUT_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb;
|
|
||||||
|
mod render;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
@ -23,6 +24,8 @@ pub struct Core {
|
||||||
surface: wgpu::Surface<'static>,
|
surface: wgpu::Surface<'static>,
|
||||||
|
|
||||||
depth: wgpu::Texture,
|
depth: wgpu::Texture,
|
||||||
|
pipeline: render::ParticlePipeline,
|
||||||
|
particle: render::ParticleMesh,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Core {
|
impl Core {
|
||||||
|
|
@ -34,6 +37,8 @@ impl Core {
|
||||||
} = gpu;
|
} = gpu;
|
||||||
|
|
||||||
let depth = Self::create_depth_buffer(&device, pixel_size);
|
let depth = Self::create_depth_buffer(&device, pixel_size);
|
||||||
|
let pipeline = render::ParticlePipeline::new(&device);
|
||||||
|
let particle = render::ParticleMesh::new(&device, 17);
|
||||||
queue.submit([]); // flush buffer updates
|
queue.submit([]); // flush buffer updates
|
||||||
|
|
||||||
Self::configure_surface(&surface, &device, pixel_size);
|
Self::configure_surface(&surface, &device, pixel_size);
|
||||||
|
|
@ -43,6 +48,8 @@ impl Core {
|
||||||
queue,
|
queue,
|
||||||
surface,
|
surface,
|
||||||
depth,
|
depth,
|
||||||
|
pipeline,
|
||||||
|
particle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,7 +60,12 @@ impl Core {
|
||||||
let h = size.height as f32;
|
let h = size.height as f32;
|
||||||
w / h
|
w / h
|
||||||
};
|
};
|
||||||
self.queue.submit([]); // flush buffer updates
|
let look = render::LookParams {
|
||||||
|
scale: vec2(0.01 / aspect, 0.01),
|
||||||
|
};
|
||||||
|
|
||||||
|
let particles = vec![vec2(0., 0.), vec2(20., 0.), vec2(0., 10.)];
|
||||||
|
let particles = render::ParticleSet::new(&self.device, particles.as_slice());
|
||||||
|
|
||||||
let view = output.create_view(&wgpu::TextureViewDescriptor::default());
|
let view = output.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
let depth_view = self
|
let depth_view = self
|
||||||
|
|
@ -77,17 +89,13 @@ impl Core {
|
||||||
store: wgpu::StoreOp::Store,
|
store: wgpu::StoreOp::Store,
|
||||||
},
|
},
|
||||||
})],
|
})],
|
||||||
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
|
depth_stencil_attachment: None,
|
||||||
view: &depth_view,
|
|
||||||
depth_ops: Some(wgpu::Operations {
|
|
||||||
load: wgpu::LoadOp::Clear(1.),
|
|
||||||
store: wgpu::StoreOp::Discard,
|
|
||||||
}),
|
|
||||||
stencil_ops: None,
|
|
||||||
}),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.pipeline
|
||||||
|
.render(&mut pass, &look, &self.particle, &particles);
|
||||||
|
|
||||||
drop(pass);
|
drop(pass);
|
||||||
self.queue.submit(std::iter::once(encoder.finish()));
|
self.queue.submit(std::iter::once(encoder.finish()));
|
||||||
}
|
}
|
||||||
|
|
@ -158,7 +166,14 @@ pub async fn init_gpu_inner<E: Error + 'static>(
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let (device, queue) = adapter
|
let (device, queue) = adapter
|
||||||
.request_device(&wgpu::DeviceDescriptor::default())
|
.request_device(&wgpu::DeviceDescriptor {
|
||||||
|
required_features: wgpu::Features::IMMEDIATES,
|
||||||
|
required_limits: wgpu::Limits {
|
||||||
|
max_immediate_size: 64,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Ok(Gpu {
|
Ok(Gpu {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use PROJECT_NAME::{Core, RedrawArgs, init_gpu_inner};
|
|
||||||
use glam::{uvec2, vec4};
|
use glam::{uvec2, vec4};
|
||||||
|
use particle_matter::{Core, RedrawArgs, init_gpu_inner};
|
||||||
use winit::{
|
use winit::{
|
||||||
application::ApplicationHandler,
|
application::ApplicationHandler,
|
||||||
event::WindowEvent,
|
event::WindowEvent,
|
||||||
|
|
@ -9,7 +9,7 @@ use winit::{
|
||||||
window::Window,
|
window::Window,
|
||||||
};
|
};
|
||||||
|
|
||||||
const TITLE: &str = "PROJECT NAME";
|
const TITLE: &str = "Particle Matter";
|
||||||
|
|
||||||
struct MainWindow {
|
struct MainWindow {
|
||||||
window: Arc<Window>,
|
window: Arc<Window>,
|
||||||
|
|
|
||||||
24
src/particle.wgsl
Normal file
24
src/particle.wgsl
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
struct LookParams {
|
||||||
|
scale: vec2f,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Varying {
|
||||||
|
@builtin(position) screen: vec4f,
|
||||||
|
@location(0) color: vec4f,
|
||||||
|
}
|
||||||
|
|
||||||
|
var<immediate> look: LookParams;
|
||||||
|
|
||||||
|
@vertex
|
||||||
|
fn on_vertex(
|
||||||
|
@location(0) pos: vec2f,
|
||||||
|
@location(1) off: vec2f,
|
||||||
|
) -> Varying {
|
||||||
|
let vpos = pos + off;
|
||||||
|
return Varying(vec4f(look.scale * vpos, 0., 1.), vec4f(0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@fragment
|
||||||
|
fn on_fragment(in: Varying) -> @location(0) vec4f {
|
||||||
|
return in.color;
|
||||||
|
}
|
||||||
146
src/render.rs
Normal file
146
src/render.rs
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
use bytemuck::{Pod, Zeroable, cast_slice};
|
||||||
|
use glam::{Vec2, vec2};
|
||||||
|
use wgpu::util::DeviceExt as _;
|
||||||
|
|
||||||
|
pub const OUTPUT_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Bgra8UnormSrgb;
|
||||||
|
pub const DEPTH_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Depth24Plus;
|
||||||
|
|
||||||
|
static PARTICLE_SHADER: &str = include_str!("particle.wgsl");
|
||||||
|
|
||||||
|
pub struct ParticlePipeline {
|
||||||
|
pipeline: wgpu::RenderPipeline,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct LookParams {
|
||||||
|
pub scale: Vec2,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ParticleMesh {
|
||||||
|
vertex_buffer: wgpu::Buffer,
|
||||||
|
vertex_count: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ParticleSet {
|
||||||
|
vertex_buffer: wgpu::Buffer,
|
||||||
|
vertex_count: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParticleMesh {
|
||||||
|
pub fn new(device: &wgpu::Device, n: u32) -> Self {
|
||||||
|
assert!(n >= 3);
|
||||||
|
assert!(n < 1000);
|
||||||
|
let mut vertices: Vec<Vec2> = Vec::with_capacity(n as usize);
|
||||||
|
for k in 0..n {
|
||||||
|
let k2 = (k / 2) as i32;
|
||||||
|
let k3 = match k % 2 {
|
||||||
|
0 => k2,
|
||||||
|
1 => -1 - k2,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
let phi = 2. * std::f32::consts::PI * (k3 as f32) / (n as f32);
|
||||||
|
let (y, x) = phi.sin_cos();
|
||||||
|
vertices.push(vec2(x, y));
|
||||||
|
}
|
||||||
|
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: None,
|
||||||
|
usage: wgpu::BufferUsages::VERTEX,
|
||||||
|
contents: cast_slice(vertices.as_slice()),
|
||||||
|
});
|
||||||
|
Self {
|
||||||
|
vertex_buffer,
|
||||||
|
vertex_count: n,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParticleSet {
|
||||||
|
pub fn new(device: &wgpu::Device, positions: &[Vec2]) -> Self {
|
||||||
|
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: None,
|
||||||
|
usage: wgpu::BufferUsages::VERTEX,
|
||||||
|
contents: cast_slice(positions),
|
||||||
|
});
|
||||||
|
Self {
|
||||||
|
vertex_buffer,
|
||||||
|
vertex_count: positions.len().try_into().unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParticlePipeline {
|
||||||
|
pub fn new(device: &wgpu::Device) -> Self {
|
||||||
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
|
label: None,
|
||||||
|
source: wgpu::ShaderSource::Wgsl(PARTICLE_SHADER.into()),
|
||||||
|
});
|
||||||
|
let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
|
label: None,
|
||||||
|
bind_group_layouts: &[],
|
||||||
|
immediate_size: 8,
|
||||||
|
});
|
||||||
|
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
label: None,
|
||||||
|
layout: Some(&layout),
|
||||||
|
vertex: wgpu::VertexState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: None,
|
||||||
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
|
buffers: &[
|
||||||
|
wgpu::VertexBufferLayout {
|
||||||
|
array_stride: size_of::<Vec2>() as u64,
|
||||||
|
step_mode: wgpu::VertexStepMode::Instance,
|
||||||
|
attributes: &[wgpu::VertexAttribute {
|
||||||
|
shader_location: 0,
|
||||||
|
offset: 0,
|
||||||
|
format: wgpu::VertexFormat::Float32x2,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
wgpu::VertexBufferLayout {
|
||||||
|
array_stride: size_of::<Vec2>() as u64,
|
||||||
|
step_mode: wgpu::VertexStepMode::Vertex,
|
||||||
|
attributes: &[wgpu::VertexAttribute {
|
||||||
|
shader_location: 1,
|
||||||
|
offset: 0,
|
||||||
|
format: wgpu::VertexFormat::Float32x2,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
primitive: wgpu::PrimitiveState {
|
||||||
|
topology: wgpu::PrimitiveTopology::TriangleStrip,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
depth_stencil: None,
|
||||||
|
multisample: wgpu::MultisampleState::default(),
|
||||||
|
fragment: Some(wgpu::FragmentState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: None,
|
||||||
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
|
targets: &[Some(wgpu::ColorTargetState {
|
||||||
|
format: OUTPUT_FORMAT,
|
||||||
|
blend: Some(wgpu::BlendState::REPLACE),
|
||||||
|
write_mask: wgpu::ColorWrites::ALL,
|
||||||
|
})],
|
||||||
|
}),
|
||||||
|
multiview_mask: None,
|
||||||
|
cache: None,
|
||||||
|
});
|
||||||
|
Self { pipeline }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render<'a>(
|
||||||
|
&self,
|
||||||
|
pass: &mut wgpu::RenderPass,
|
||||||
|
params: &LookParams,
|
||||||
|
mesh: &ParticleMesh,
|
||||||
|
particles: &ParticleSet,
|
||||||
|
) {
|
||||||
|
pass.set_pipeline(&self.pipeline);
|
||||||
|
pass.set_immediates(0, bytemuck::bytes_of(params));
|
||||||
|
pass.set_vertex_buffer(0, particles.vertex_buffer.slice(..));
|
||||||
|
pass.set_vertex_buffer(1, mesh.vertex_buffer.slice(..));
|
||||||
|
pass.draw(0..mesh.vertex_count, 0..particles.vertex_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
include(impl.cmake)
|
include(impl.cmake)
|
||||||
|
|
||||||
qt_add_executable(PROJECT-NAME
|
qt_add_executable(particle_matter
|
||||||
src/api.cxx
|
src/api.cxx
|
||||||
src/main.cxx
|
src/main.cxx
|
||||||
src/main_window.cxx
|
src/main_window.cxx
|
||||||
|
|
@ -8,7 +8,7 @@ qt_add_executable(PROJECT-NAME
|
||||||
src/viewport.cxx
|
src/viewport.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(PROJECT-NAME PRIVATE Qt6::Gui Qt6::Widgets)
|
target_link_libraries(particle_matter PRIVATE Qt6::Gui Qt6::Widgets)
|
||||||
target_link_libraries(PROJECT-NAME PRIVATE KF6::WidgetsAddons)
|
target_link_libraries(particle_matter PRIVATE KF6::WidgetsAddons)
|
||||||
target_link_libraries(PROJECT-NAME PRIVATE PROJECT_NAME_impl)
|
target_link_libraries(particle_matter PRIVATE particle_matter_impl)
|
||||||
target_include_directories(PROJECT-NAME PRIVATE src)
|
target_include_directories(particle_matter PRIVATE src)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "PROJECT-NAME-impl"
|
name = "particle_matter-impl"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
|
|
@ -7,9 +7,9 @@ edition = "2024"
|
||||||
crate-type = ["staticlib"]
|
crate-type = ["staticlib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
PROJECT-NAME = {path = "../"}
|
particle_matter = {path = "../"}
|
||||||
|
|
||||||
glam = { version = "0.30" }
|
glam = { version = "0.30" }
|
||||||
pollster = "0.4.0"
|
pollster = "0.4.0"
|
||||||
raw-window-handle = "0.6.2"
|
raw-window-handle = "0.6.2"
|
||||||
wgpu = "27.0.1"
|
wgpu = "28.0.0"
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
set(impl_basename "${CARGO_TARGET_DIR}/release/libPROJECT_NAME_impl")
|
set(impl_basename "${CARGO_TARGET_DIR}/release/libparticle_matter_impl")
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${impl_basename}.a
|
OUTPUT ${impl_basename}.a
|
||||||
COMMAND env CARGO_TARGET_DIR=${CARGO_TARGET_DIR} ${CARGO} build --release --package PROJECT-NAME-impl
|
COMMAND env CARGO_TARGET_DIR=${CARGO_TARGET_DIR} ${CARGO} build --release --package particle_matter-impl
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
DEPFILE ${impl_basename}.d
|
DEPFILE ${impl_basename}.d
|
||||||
USES_TERMINAL
|
USES_TERMINAL
|
||||||
|
|
@ -15,8 +15,8 @@ add_custom_target(build_impl
|
||||||
DEPENDS ${impl_basename}.a
|
DEPENDS ${impl_basename}.a
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(PROJECT_NAME_impl STATIC IMPORTED)
|
add_library(particle_matter_impl STATIC IMPORTED)
|
||||||
|
|
||||||
set_target_properties(PROJECT_NAME_impl PROPERTIES
|
set_target_properties(particle_matter_impl PROPERTIES
|
||||||
IMPORTED_LOCATION ${impl_basename}.a
|
IMPORTED_LOCATION ${impl_basename}.a
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{ffi::c_void, num::NonZero, ptr::NonNull};
|
use std::{ffi::c_void, num::NonZero, ptr::NonNull};
|
||||||
|
|
||||||
use PROJECT_NAME::{Core, RedrawArgs, init_gpu_inner};
|
|
||||||
use glam::{UVec2, uvec2};
|
use glam::{UVec2, uvec2};
|
||||||
|
use particle_matter::{Core, RedrawArgs, init_gpu_inner};
|
||||||
use raw_window_handle::{RawDisplayHandle, RawWindowHandle, XcbDisplayHandle, XcbWindowHandle};
|
use raw_window_handle::{RawDisplayHandle, RawWindowHandle, XcbDisplayHandle, XcbWindowHandle};
|
||||||
|
|
||||||
unsafe fn create_viewport(
|
unsafe fn create_viewport(
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
auto w = new PROJECTNAME;
|
auto w = new ParticleMatter;
|
||||||
w->show();
|
w->show();
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,16 @@
|
||||||
|
|
||||||
#include "ui_main_window.h"
|
#include "ui_main_window.h"
|
||||||
|
|
||||||
PROJECTNAME::PROJECTNAME(QWidget* parent)
|
ParticleMatter::ParticleMatter(QWidget* parent)
|
||||||
: QMainWindow(parent),
|
: QMainWindow(parent),
|
||||||
m_ui(new Ui::MainWindow) {
|
m_ui(new Ui::MainWindow) {
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
updateView();
|
updateView();
|
||||||
}
|
}
|
||||||
|
|
||||||
PROJECTNAME::~PROJECTNAME() = default;
|
ParticleMatter::~ParticleMatter() = default;
|
||||||
|
|
||||||
void PROJECTNAME::updateView() {
|
void ParticleMatter::updateView() {
|
||||||
const auto color = m_ui->inBackground->color();
|
const auto color = m_ui->inBackground->color();
|
||||||
RedrawArgs args{
|
RedrawArgs args{
|
||||||
.background = { color.redF(), color.greenF(), color.blueF(), 1.00 },
|
.background = { color.redF(), color.greenF(), color.blueF(), 1.00 },
|
||||||
|
|
@ -19,7 +19,7 @@ void PROJECTNAME::updateView() {
|
||||||
m_ui->viewport->setView(args);
|
m_ui->viewport->setView(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PROJECTNAME::updateViewIf(bool update) {
|
void ParticleMatter::updateViewIf(bool update) {
|
||||||
if (update)
|
if (update)
|
||||||
updateView();
|
updateView();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,12 @@ namespace Ui {
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PROJECTNAME : public QMainWindow {
|
class ParticleMatter : public QMainWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PROJECTNAME(QWidget* parent = nullptr);
|
explicit ParticleMatter(QWidget* parent = nullptr);
|
||||||
~PROJECTNAME() override;
|
~ParticleMatter() override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateView();
|
void updateView();
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>PROJECT NAME</string>
|
<string>Particle Matter</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
|
@ -51,8 +51,8 @@
|
||||||
<widget class="KColorCombo" name="inBackground">
|
<widget class="KColorCombo" name="inBackground">
|
||||||
<property name="color">
|
<property name="color">
|
||||||
<color>
|
<color>
|
||||||
<red>25</red>
|
<red>0</red>
|
||||||
<green>220</green>
|
<green>0</green>
|
||||||
<blue>0</blue>
|
<blue>0</blue>
|
||||||
</color>
|
</color>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user