diff --git a/.cursor/mcp.json b/.cursor/mcp.json new file mode 100644 index 0000000..86d37b4 --- /dev/null +++ b/.cursor/mcp.json @@ -0,0 +1,10 @@ +{ + "mcpServers": { + "run-program": { + "command": "cargo", + "args": [ + "run" + ] + } + } +} diff --git a/Cargo.lock b/Cargo.lock index ffb6291..e69aec8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,20 +18,14 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - [[package]] name = "ahash" -version = "0.8.12" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom 0.3.3", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -46,12 +40,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "aligned-vec" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" - [[package]] name = "android-activity" version = "0.6.0" @@ -59,7 +47,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", - "bitflags 2.9.1", + "bitflags 2.9.0", "cc", "cesu8", "jni", @@ -70,7 +58,7 @@ dependencies = [ "ndk-context", "ndk-sys", "num_enum", - "thiserror 1.0.69", + "thiserror", ] [[package]] @@ -80,46 +68,95 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" [[package]] -name = "anyhow" -version = "1.0.98" +name = "anstream" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" - -[[package]] -name = "arbitrary" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" - -[[package]] -name = "arboard" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1df21f715862ede32a0c525ce2ca4d52626bb0007f8c18b87a384503ac33e70" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ - "clipboard-win", - "image", - "log", - "objc2 0.6.1", - "objc2-app-kit 0.3.1", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-foundation 0.3.1", - "parking_lot", - "percent-encoding", - "windows-sys 0.59.0", - "x11rb", + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", ] [[package]] -name = "arg_enum_proc_macro" -version = "0.3.4" +name = "anstyle" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +dependencies = [ + "anstyle", + "once_cell", + "windows-sys 0.59.0", +] + +[[package]] +name = "any_vec" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6ac04794a7749710e3c7f3c93222e3d04692993b69876d69393efd2565401a" + +[[package]] +name = "anyhow" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" + +[[package]] +name = "apecs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6df7760d4baebb17003dcf99134d8e3a63f487e146d58911f0bcd27afb185d1c" +dependencies = [ + "any_vec", + "apecs-derive", + "async-channel", + "itertools", + "log", + "moongraph", + "parking_lot", + "rayon", + "smallvec", + "snafu 0.8.5", +] + +[[package]] +name = "apecs-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0f3ddfd31fd5276fb8039b75dc4d284c21213757a969e480c6ef8fde494f3b" +dependencies = [ + "moongraph-macros-syntax", "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -149,6 +186,17 @@ dependencies = [ "libloading", ] +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + [[package]] name = "atomic-waker" version = "1.1.2" @@ -161,35 +209,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" -[[package]] -name = "av1-grain" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3efb2ca85bc610acfa917b5aaa36f3fcbebed5b3182d7f877b02531c4b80c8" -dependencies = [ - "anyhow", - "arrayvec", - "log", - "nom", - "num-rational", - "v_frame", -] - -[[package]] -name = "avif-serialize" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98922d6a4cfbcb08820c69d8eeccc05bb1f29bfa06b4f5b1dbfe9a868bd7608e" -dependencies = [ - "arrayvec", -] - -[[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" @@ -198,15 +217,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" - -[[package]] -name = "bitstream-io" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "block2" @@ -218,10 +231,15 @@ dependencies = [ ] [[package]] -name = "built" -version = "0.7.7" +name = "broomdog" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ed6191a7e78c36abdb16ab65341eefd73d64d303fffccdbb00d51e4205967b" +checksum = "52ec65645d8167b03c07e049f114a878a11ab889f20c071d6f7b30bf88fbe5af" +dependencies = [ + "log", + "rustc-hash", + "snafu 0.8.5", +] [[package]] name = "bumpalo" @@ -231,30 +249,24 @@ checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "bytemuck" -version = "1.23.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c" +checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.9.3" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" +checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] -[[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.10.1" @@ -267,12 +279,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "log", "polling", "rustix", "slab", - "thiserror 1.0.69", + "thiserror", ] [[package]] @@ -289,9 +301,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.23" +version = "1.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4ac86a9e5bc1e2b3449ab9d7d3a6a405e3d1bb28d7b9be8614f55846ae3766" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" dependencies = [ "jobserver", "libc", @@ -304,16 +316,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" -[[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" @@ -326,15 +328,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" -[[package]] -name = "clipboard-win" -version = "5.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" -dependencies = [ - "error-code", -] - [[package]] name = "cmake" version = "0.1.54" @@ -345,10 +338,10 @@ dependencies = [ ] [[package]] -name = "color_quant" -version = "1.1.0" +name = "colorchoice" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "combine" @@ -379,16 +372,6 @@ dependencies = [ "libc", ] -[[package]] -name = "core-foundation" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -402,7 +385,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", - "core-foundation 0.9.4", + "core-foundation", "core-graphics-types", "foreign-types", "libc", @@ -415,19 +398,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", - "core-foundation 0.9.4", + "core-foundation", "libc", ] -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if", -] - [[package]] name = "crossbeam-deque" version = "0.8.6" @@ -474,33 +448,23 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" +[[package]] +name = "dagga" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cf0d7dcd307c9c5d81277737c35d1faf08af9e2cb262966a01c91021686b68" +dependencies = [ + "log", + "rustc-hash", + "snafu 0.7.5", +] + [[package]] name = "dispatch" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" -[[package]] -name = "dispatch2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" -dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "dlib" version = "0.5.2" @@ -510,6 +474,12 @@ dependencies = [ "libloading", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "downcast-rs" version = "1.2.1" @@ -518,68 +488,9 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dpi" -version = "0.1.2" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" - -[[package]] -name = "ecolor" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc4feb366740ded31a004a0e4452fbf84e80ef432ecf8314c485210229672fd1" -dependencies = [ - "bytemuck", - "emath", -] - -[[package]] -name = "egui" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd34cec49ab55d85ebf70139cb1ccd29c977ef6b6ba4fe85489d6877ee9ef3" -dependencies = [ - "ahash", - "bitflags 2.9.1", - "emath", - "epaint", - "log", - "nohash-hasher", - "profiling", -] - -[[package]] -name = "egui-winit" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d9dfbb78fe4eb9c3a39ad528b90ee5915c252e77bbab9d4ebc576541ab67e13" -dependencies = [ - "ahash", - "arboard", - "bytemuck", - "egui", - "log", - "profiling", - "raw-window-handle", - "smithay-clipboard", - "web-time", - "webbrowser", - "winit", -] - -[[package]] -name = "egui_winit_vulkano" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6abd5e69939cd416853fc3ec69c0e08721b175d03b508d5574849885c7e85a6" -dependencies = [ - "ahash", - "egui", - "egui-winit", - "image", - "vulkano", - "vulkano-shaders", - "winit", -] +checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" [[package]] name = "either" @@ -588,37 +499,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] -name = "emath" -version = "0.31.1" +name = "env_filter" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e4cadcff7a5353ba72b7fea76bf2122b5ebdbc68e8155aa56dfdea90083fe1b" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" dependencies = [ - "bytemuck", -] - -[[package]] -name = "epaint" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fcc0f5a7c613afd2dee5e4b30c3e6acafb8ad6f0edb06068811f708a67c562" -dependencies = [ - "ab_glyph", - "ahash", - "bytemuck", - "ecolor", - "emath", - "epaint_default_fonts", "log", - "nohash-hasher", - "parking_lot", - "profiling", + "regex", ] [[package]] -name = "epaint_default_fonts" -version = "0.31.1" +name = "env_logger" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7e7a64c02cf7a5b51e745a9e45f60660a286f151c238b9d397b3e923f5082f" +checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", +] [[package]] name = "equivalent" @@ -628,59 +529,25 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.12" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", "windows-sys 0.59.0", ] [[package]] -name = "error-code" -version = "3.3.2" +name = "event-listener" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59" - -[[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" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" -dependencies = [ - "simd-adler32", -] - -[[package]] -name = "flate2" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" -dependencies = [ - "crc32fast", - "miniz_oxide", -] +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "foldhash" -version = "0.1.5" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" [[package]] name = "foreign-types" @@ -700,7 +567,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -710,27 +577,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] -name = "form_urlencoded" -version = "1.2.1" +name = "futures-core" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "generator" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d18470a76cb7f8ff746cf1f7470914f900252ec36bbc40b569d74b1258446827" -dependencies = [ - "cc", - "cfg-if", - "libc", - "log", - "rustversion", - "windows", -] +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "gethostname" @@ -744,48 +594,26 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasi 0.14.2+wasi-0.2.4", -] - -[[package]] -name = "gif" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" -dependencies = [ - "color_quant", - "weezl", + "wasi", ] [[package]] name = "glam" -version = "0.30.3" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b46b9ca4690308844c644e7c634d68792467260e051c8543e0c7871662b3ba7" +checksum = "17fcdf9683c406c2fc4d124afd29c0d595e22210d633cbdb8695ba9935ab1dc6" [[package]] name = "half" -version = "2.6.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1" dependencies = [ "bytemuck", "cfg-if", @@ -794,9 +622,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.3" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "heck" @@ -804,199 +632,33 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -[[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.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" -[[package]] -name = "home" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "icu_collections" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" - -[[package]] -name = "icu_properties" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "potential_utf", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" - -[[package]] -name = "icu_provider" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" -dependencies = [ - "displaydoc", - "icu_locale_core", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "idna" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "image" -version = "0.25.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" -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.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b77d01e822461baa8409e156015a1d91735549f0f2c17691bd2d996bef238f7f" -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.9.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", "hashbrown", ] [[package]] -name = "interpolate_name" -version = "0.2.4" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" -version = "0.12.1" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ "either", ] @@ -1007,6 +669,30 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "jiff" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d699bc6dfc879fb1bf9bdff0d4c56f0884fc6f0d0eb0fba397a6d00cd9a6b85e" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", +] + +[[package]] +name = "jiff-static" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d16e75759ee0aa64c57a56acbf43916987b20c77373cb7e808979e02b93c9f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "jni" version = "0.21.1" @@ -1018,7 +704,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror 1.0.69", + "thiserror", "walkdir", "windows-sys 0.45.0", ] @@ -1031,20 +717,13 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.33" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ - "getrandom 0.3.3", "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.77" @@ -1055,39 +734,17 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "lazy_static" -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.172" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" - -[[package]] -name = "libfuzzer-sys" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf78f52d400cf2d84a3a973a78a592b4adc535739e0a5597a0da6f0c357adc75" -dependencies = [ - "arbitrary", - "cc", -] +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "libloading" -version = "0.8.7" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a793df0d7afeac54f95b471d3af7f0d4fb975699f972341a4b76988d49cdf0c" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", "windows-targets 0.52.6", @@ -1099,9 +756,9 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "libc", - "redox_syscall 0.5.12", + "redox_syscall 0.5.10", ] [[package]] @@ -1110,12 +767,6 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" -[[package]] -name = "litemap" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" - [[package]] name = "lock_api" version = "0.4.12" @@ -1128,50 +779,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.27" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" - -[[package]] -name = "loom" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" -dependencies = [ - "cfg-if", - "generator", - "scoped-tls", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "loop9" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" -dependencies = [ - "imgref", -] - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "maybe-rayon" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" -dependencies = [ - "cfg-if", - "rayon", -] +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" [[package]] name = "memchr" @@ -1195,13 +805,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] -name = "miniz_oxide" -version = "0.8.8" +name = "moongraph" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +checksum = "c5a4b09eb96a84205062b48ec5469c8c35c128167e838aa73dc620c4411af598" dependencies = [ - "adler2", - "simd-adler32", + "broomdog", + "dagga", + "log", + "rayon", + "snafu 0.8.5", +] + +[[package]] +name = "moongraph-macros-syntax" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08112087acc92cc28fb5d8f7bda1307123ecc9a275ed4835f1c03f1a8dd02c1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] @@ -1210,13 +834,13 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "jni-sys", "log", "ndk-sys", "num_enum", "raw-window-handle", - "thiserror 1.0.69", + "thiserror", ] [[package]] @@ -1234,18 +858,6 @@ 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 = "nohash-hasher" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" - [[package]] name = "nom" version = "7.1.3" @@ -1256,72 +868,6 @@ 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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "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-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[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" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - [[package]] name = "num_enum" version = "0.7.3" @@ -1340,7 +886,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -1361,9 +907,9 @@ dependencies = [ [[package]] name = "objc2" -version = "0.6.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88c6597e14493ab2e44ce58f2fdecf095a51f12ca57bec060a11c57332520551" +checksum = "3531f65190d9cff863b77a99857e74c314dd16bf56c538c4b57c7cbc3f3a6e59" dependencies = [ "objc2-encode", ] @@ -1374,7 +920,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "block2", "libc", "objc2 0.5.2", @@ -1384,25 +930,13 @@ dependencies = [ "objc2-quartz-core 0.2.2", ] -[[package]] -name = "objc2-app-kit" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" -dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", - "objc2-core-graphics", - "objc2-foundation 0.3.1", -] - [[package]] name = "objc2-cloud-kit" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "block2", "objc2 0.5.2", "objc2-core-location", @@ -1426,7 +960,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "block2", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -1434,26 +968,12 @@ dependencies = [ [[package]] name = "objc2-core-foundation" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +checksum = "daeaf60f25471d26948a1c2f840e3f7d86f4109e3af4e8e4b5cd70c39690d925" dependencies = [ - "bitflags 2.9.1", - "dispatch2", - "objc2 0.6.1", -] - -[[package]] -name = "objc2-core-graphics" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" -dependencies = [ - "bitflags 2.9.1", - "dispatch2", - "objc2 0.6.1", - "objc2-core-foundation", - "objc2-io-surface", + "bitflags 2.9.0", + "objc2 0.6.0", ] [[package]] @@ -1492,7 +1012,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "block2", "dispatch", "libc", @@ -1501,23 +1021,12 @@ dependencies = [ [[package]] name = "objc2-foundation" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" +checksum = "3a21c6c9014b82c39515db5b396f91645182611c97d24637cf56ac01e5f8d998" dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-io-surface" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c" -dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", + "bitflags 2.9.0", + "objc2 0.6.0", "objc2-core-foundation", ] @@ -1529,7 +1038,7 @@ checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" dependencies = [ "block2", "objc2 0.5.2", - "objc2-app-kit 0.2.2", + "objc2-app-kit", "objc2-foundation 0.2.2", ] @@ -1539,7 +1048,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "block2", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -1547,13 +1056,13 @@ dependencies = [ [[package]] name = "objc2-metal" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f246c183239540aab1782457b35ab2040d4259175bd1d0c58e46ada7b47a874" +checksum = "01c41bc8b0e50ea7a5304a56f25e0066f526e99641b46fd7b9ad4421dd35bff6" dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", - "objc2-foundation 0.3.1", + "bitflags 2.9.0", + "objc2 0.6.0", + "objc2-foundation 0.3.0", ] [[package]] @@ -1562,7 +1071,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "block2", "objc2 0.5.2", "objc2-foundation 0.2.2", @@ -1571,15 +1080,15 @@ dependencies = [ [[package]] name = "objc2-quartz-core" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ffb6a0cd5f182dc964334388560b12a57f7b74b3e2dec5e2722aa2dfb2ccd5" +checksum = "6fb3794501bb1bee12f08dcad8c61f2a5875791ad1c6f47faa71a0f033f20071" dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", + "bitflags 2.9.0", + "objc2 0.6.0", "objc2-core-foundation", - "objc2-foundation 0.3.1", - "objc2-metal 0.3.1", + "objc2-foundation 0.3.0", + "objc2-metal 0.3.0", ] [[package]] @@ -1598,7 +1107,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "block2", "objc2 0.5.2", "objc2-cloud-kit", @@ -1630,7 +1139,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "block2", "objc2 0.5.2", "objc2-core-location", @@ -1639,9 +1148,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" [[package]] name = "orbclient" @@ -1652,12 +1161,6 @@ dependencies = [ "libredox", ] -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "owned_ttf_parser" version = "0.25.0" @@ -1685,17 +1188,11 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.12", + "redox_syscall 0.5.10", "smallvec", "windows-targets 0.52.6", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "percent-encoding" version = "2.3.1" @@ -1719,7 +1216,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -1734,19 +1231,6 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" -[[package]] -name = "png" -version = "0.17.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" -dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - [[package]] name = "polling" version = "3.7.4" @@ -1763,21 +1247,18 @@ dependencies = [ ] [[package]] -name = "potential_utf" -version = "0.1.2" +name = "portable-atomic" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" -dependencies = [ - "zerovec", -] +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" [[package]] -name = "ppv-lite86" -version = "0.2.21" +name = "portable-atomic-util" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" dependencies = [ - "zerocopy", + "portable-atomic", ] [[package]] @@ -1791,52 +1272,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] -[[package]] -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" -version = "0.37.5" +version = "0.37.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" +checksum = "165859e9e55f79d67b96c5d96f4e88b6f2695a1972849c15a6a3f5c59fc2c003" dependencies = [ "memchr", ] @@ -1850,121 +1297,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "r-efi" -version = "5.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" - -[[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.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", -] - -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" -dependencies = [ - "getrandom 0.3.3", -] - -[[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", - "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 1.0.69", - "v_frame", - "wasm-bindgen", -] - -[[package]] -name = "ravif" -version = "0.11.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6a5f31fcf7500f9401fea858ea4ab5525c99f2322cfcee732c0e6c74208c0c6" -dependencies = [ - "avif-serialize", - "imgref", - "loop9", - "quick-error", - "rav1e", - "rayon", - "rgb", -] - [[package]] name = "raw-window-handle" version = "0.6.2" @@ -1977,10 +1309,10 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40d213455a5f1dc59214213c7330e074ddf8114c9a42411eb890c767357ce135" dependencies = [ - "objc2 0.6.1", + "objc2 0.6.0", "objc2-core-foundation", - "objc2-foundation 0.3.1", - "objc2-quartz-core 0.3.1", + "objc2-foundation 0.3.0", + "objc2-quartz-core 0.3.0", ] [[package]] @@ -2014,11 +1346,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.12" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", ] [[package]] @@ -2029,17 +1361,8 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] @@ -2050,27 +1373,15 @@ checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax", ] -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "regex-syntax" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" -[[package]] -name = "rgb" -version = "0.8.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" - [[package]] name = "roxmltree" version = "0.14.1" @@ -2085,28 +1396,28 @@ name = "rust_vulkan_test" version = "0.1.0" dependencies = [ "anyhow", - "egui_winit_vulkano", + "apecs", + "env_logger", "glam", - "image", - "rand 0.9.1", - "thiserror 2.0.12", - "tracing", - "tracing-log", - "tracing-subscriber", - "tracing-tracy", + "log", "vulkano", "vulkano-shaders", - "vulkano-util", "winit", ] +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustix" version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys", @@ -2176,7 +1487,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -2191,15 +1502,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" -dependencies = [ - "serde", -] - [[package]] name = "shaderc" version = "0.8.3" @@ -2221,36 +1523,12 @@ dependencies = [ "roxmltree", ] -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "simd-adler32" -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 = "slab" version = "0.4.9" @@ -2268,9 +1546,9 @@ checksum = "9db491c0d4152a069911a0fbdaca959691bf0b9d7110d98a7ed1c8e59b79ab30" [[package]] name = "smallvec" -version = "1.15.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "smithay-client-toolkit" @@ -2278,7 +1556,7 @@ version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "calloop", "calloop-wayland-source", "cursor-icon", @@ -2286,7 +1564,7 @@ dependencies = [ "log", "memmap2", "rustix", - "thiserror 1.0.69", + "thiserror", "wayland-backend", "wayland-client", "wayland-csd-frame", @@ -2297,17 +1575,6 @@ dependencies = [ "xkeysym", ] -[[package]] -name = "smithay-clipboard" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc8216eec463674a0e90f29e0ae41a4db573ec5b56b1c6c1c71615d249b6d846" -dependencies = [ - "libc", - "smithay-client-toolkit", - "wayland-backend", -] - [[package]] name = "smol_str" version = "0.2.2" @@ -2318,10 +1585,47 @@ dependencies = [ ] [[package]] -name = "stable_deref_trait" -version = "1.2.0" +name = "snafu" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "e4de37ad025c587a29e8f3f5605c00f70b98715ef90b9061a815b9e59e9042d6" +dependencies = [ + "doc-comment", + "snafu-derive 0.7.5", +] + +[[package]] +name = "snafu" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019" +dependencies = [ + "snafu-derive 0.8.5", +] + +[[package]] +name = "snafu-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990079665f075b699031e9c08fd3ab99be5029b96f3b78dc0709e8f77e4efebf" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "snafu-derive" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.100", +] [[package]] name = "strict-num" @@ -2331,9 +1635,9 @@ checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" [[package]] name = "syn" -version = "2.0.101" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -2341,51 +1645,23 @@ dependencies = [ ] [[package]] -name = "synstructure" -version = "0.13.2" +name = "syn" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", - "syn", + "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 0.5.0", - "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 = "thiserror" version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl 1.0.69", -] - -[[package]] -name = "thiserror" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" -dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl", ] [[package]] @@ -2396,18 +1672,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -2420,17 +1685,6 @@ 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" @@ -2456,46 +1710,19 @@ dependencies = [ "strict-num", ] -[[package]] -name = "tinystr" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "toml" -version = "0.8.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - [[package]] name = "toml_datetime" -version = "0.6.9" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" -dependencies = [ - "serde", -] +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" -version = "0.22.26" +version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ "indexmap", - "serde", - "serde_spanned", "toml_datetime", "winnow", ] @@ -2507,91 +1734,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", - "tracing-attributes", "tracing-core", ] -[[package]] -name = "tracing-attributes" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "tracing-core" version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "tracing-tracy" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eaa1852afa96e0fe9e44caa53dc0bd2d9d05e0f2611ce09f97f8677af56e4ba" -dependencies = [ - "tracing-core", - "tracing-subscriber", - "tracy-client", -] - -[[package]] -name = "tracy-client" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d90a2c01305b02b76fdd89ac8608bae27e173c829a35f7d76a345ab5d33836db" -dependencies = [ - "loom", - "once_cell", - "tracy-client-sys", -] - -[[package]] -name = "tracy-client-sys" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69fff37da548239c3bf9e64a12193d261e8b22b660991c6fd2df057c168f435f" -dependencies = [ - "cc", - "windows-targets 0.52.6", -] [[package]] name = "ttf-parser" @@ -2612,44 +1762,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] -name = "url" -version = "2.5.4" +name = "utf8parse" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[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.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" - -[[package]] -name = "version-compare" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "version_check" @@ -2677,7 +1793,7 @@ dependencies = [ "crossbeam-queue", "foldhash", "half", - "heck 0.4.1", + "heck", "indexmap", "libloading", "nom", @@ -2707,7 +1823,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 2.0.100", ] [[package]] @@ -2717,25 +1833,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bf501461be7cef2893c0e62c50945add9763cc482051d29053f6157089d5ea9" dependencies = [ "foldhash", - "heck 0.4.1", + "heck", "proc-macro2", "quote", "shaderc", - "syn", + "syn 2.0.100", "vulkano", ] -[[package]] -name = "vulkano-util" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dc54fd5e14a0e01c7282f9b5d9c6e133745e1df3228b0352366e34c83bb6b" -dependencies = [ - "foldhash", - "vulkano", - "winit", -] - [[package]] name = "walkdir" version = "2.5.0" @@ -2752,15 +1857,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" -dependencies = [ - "wit-bindgen-rt", -] - [[package]] name = "wasm-bindgen" version = "0.2.100" @@ -2783,7 +1879,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn", + "syn 2.0.100", "wasm-bindgen-shared", ] @@ -2818,7 +1914,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.100", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2834,9 +1930,9 @@ dependencies = [ [[package]] name = "wayland-backend" -version = "0.3.10" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121" +checksum = "b7208998eaa3870dad37ec8836979581506e0c5c64c20c9e79e9d2a10d6f47bf" dependencies = [ "cc", "downcast-rs", @@ -2848,11 +1944,11 @@ dependencies = [ [[package]] name = "wayland-client" -version = "0.31.10" +version = "0.31.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978fa7c67b0847dbd6a9f350ca2569174974cd4082737054dbb7fbb79d7d9a61" +checksum = "c2120de3d33638aaef5b9f4472bff75f07c56379cf76ea320bd3a3d65ecaf73f" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "rustix", "wayland-backend", "wayland-scanner", @@ -2864,16 +1960,16 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "cursor-icon", "wayland-backend", ] [[package]] name = "wayland-cursor" -version = "0.31.10" +version = "0.31.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a65317158dec28d00416cb16705934070aef4f8393353d41126c54264ae0f182" +checksum = "a93029cbb6650748881a00e4922b076092a6a08c11e7fbdb923f064b23968c5d" dependencies = [ "rustix", "wayland-client", @@ -2882,11 +1978,11 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.32.8" +version = "0.32.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "779075454e1e9a521794fed15886323ea0feda3f8b0fc1390f5398141310422a" +checksum = "0781cf46869b37e36928f7b432273c0995aa8aed9552c556fb18754420541efc" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -2894,11 +1990,11 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.3.8" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fd38cdad69b56ace413c6bcc1fbf5acc5e2ef4af9d5f8f1f9570c0c83eae175" +checksum = "7ccaacc76703fefd6763022ac565b590fcade92202492381c95b2edfdf7d46b3" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -2907,11 +2003,11 @@ dependencies = [ [[package]] name = "wayland-protocols-wlr" -version = "0.3.8" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cb6cdc73399c0e06504c437fe3cf886f25568dd5454473d565085b36d6a8bbf" +checksum = "248a02e6f595aad796561fa82d25601bd2c8c3b145b1c7453fc8f94c1a58f8b2" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -2961,45 +2057,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webbrowser" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5df295f8451142f1856b1bd86a606dfe9587d439bc036e319c827700dbd555e" -dependencies = [ - "core-foundation 0.10.0", - "home", - "jni", - "log", - "ndk-context", - "objc2 0.6.1", - "objc2-foundation 0.3.1", - "url", - "web-sys", -] - -[[package]] -name = "weezl" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - [[package]] name = "winapi-util" version = "0.1.9" @@ -3009,114 +2066,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.61.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419" -dependencies = [ - "windows-collections", - "windows-core", - "windows-future", - "windows-link", - "windows-numerics", -] - -[[package]] -name = "windows-collections" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" -dependencies = [ - "windows-core", -] - -[[package]] -name = "windows-core" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-future" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" -dependencies = [ - "windows-core", - "windows-link", - "windows-threading", -] - -[[package]] -name = "windows-implement" -version = "0.60.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-interface" -version = "0.59.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "windows-link" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" - -[[package]] -name = "windows-numerics" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" -dependencies = [ - "windows-core", - "windows-link", -] - -[[package]] -name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link", -] - [[package]] name = "windows-sys" version = "0.45.0" @@ -3190,15 +2139,6 @@ dependencies = [ "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows-threading" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" -dependencies = [ - "windows-link", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -3333,20 +2273,20 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winit" -version = "0.30.10" +version = "0.30.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d05bd8908e14618c9609471db04007e644fd9cce6529756046cfc577f9155e" +checksum = "a809eacf18c8eca8b6635091543f02a5a06ddf3dad846398795460e6e0ae3cc0" dependencies = [ "ahash", "android-activity", "atomic-waker", - "bitflags 2.9.1", + "bitflags 2.9.0", "block2", "bytemuck", "calloop", "cfg_aliases", "concurrent-queue", - "core-foundation 0.9.4", + "core-foundation", "core-graphics", "cursor-icon", "dpi", @@ -3355,7 +2295,7 @@ dependencies = [ "memmap2", "ndk", "objc2 0.5.2", - "objc2-app-kit 0.2.2", + "objc2-app-kit", "objc2-foundation 0.2.2", "objc2-ui-kit", "orbclient", @@ -3385,28 +2325,13 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.10" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" dependencies = [ "memchr", ] -[[package]] -name = "wit-bindgen-rt" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.1", -] - -[[package]] -name = "writeable" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" - [[package]] name = "x11-dl" version = "2.21.0" @@ -3451,7 +2376,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "dlib", "log", "once_cell", @@ -3466,9 +2391,9 @@ checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xml-rs" -version = "0.8.26" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda" +checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4" [[package]] name = "xmlparser" @@ -3476,124 +2401,22 @@ version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" -[[package]] -name = "yoke" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - [[package]] name = "zerocopy" -version = "0.8.25" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.25" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerotrie" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[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.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028" -dependencies = [ - "zune-core", + "syn 2.0.100", ] diff --git a/Cargo.toml b/Cargo.toml index af26232..ba7eb9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,24 +7,17 @@ publish = false [dependencies] anyhow = "1.0" -thiserror = "2.0" winit = { version = "0.30", features = ["rwh_06"] } vulkano = "0.35" vulkano-shaders = "0.35" -vulkano-util = "0.35" -egui_winit_vulkano = { version = "0.28" } - -image = { version = "0.25", features = ["png", "jpeg"] } # Math glam = { version = "0.30" } -# Log and tracing -tracing = "0.1" -tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] } -tracing-log = "0.2" -tracing-tracy = "0.11" +# ECS +apecs = "0.8" -# Random -rand = "0.9" +# Log and tracing +log = "0.4" +env_logger = "0.11.5" diff --git a/README.md b/README.md deleted file mode 100644 index c271fd8..0000000 --- a/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Project - -## Notes - -1. Run renderdoc on wayland: - -```console -WAYLAND_DISPLAY= QT_QPA_PLATFORM=xcb qrenderdoc -``` -> Not supported yet https://github.com/baldurk/renderdoc/issues/853 - -2. [Difference Between OpenGL and Vulkan](./docs/OPENGL_VULKAN_DIFF.md) - -## Usefull links - -- https://vulkan-tutorial.com/fr/Introduction -- https://github.com/bwasty/vulkan-tutorial-rs diff --git a/docs/OPENGL_VULKAN_DIFF.md b/docs/OPENGL_VULKAN_DIFF.md deleted file mode 100644 index 93d0855..0000000 --- a/docs/OPENGL_VULKAN_DIFF.md +++ /dev/null @@ -1,11 +0,0 @@ -# Difference between Vulkan and OpenGL - -Viewport: - -- Y axis is flipped like D3D -- Clipped Z axis is not [-1; 1] but [0; 1] - -![normalized viewport coordinates](./images/normalized_device_coordinates.svg) -![coord_sys](./images/coord_sys.png) - -See: [Vulkan Tutorial (Vertex step)](https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipeline_basics/Shader_modules) and [VK_KHR_maintenance1 (Allow negative height)](https://registry.khronos.org/vulkan/specs/latest/man/html/VK_KHR_maintenance1.html#_description) diff --git a/docs/images/coord_sys.png b/docs/images/coord_sys.png deleted file mode 100644 index 6d195f6..0000000 Binary files a/docs/images/coord_sys.png and /dev/null differ diff --git a/docs/images/normalized_device_coordinates.svg b/docs/images/normalized_device_coordinates.svg deleted file mode 100644 index 970c9f4..0000000 --- a/docs/images/normalized_device_coordinates.svg +++ /dev/null @@ -1,219 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - Framebuffer coordinates - (0, 0) - (1920, 0) - (0, 1080) - (1920, 1080) - - (960, 540) - - Normalized device coordinates - (-1, -1) - (1, -1) - (-1, 1) - (1, 1) - - (0, 0) - - diff --git a/flake.lock b/flake.lock index 4f4cf7e..2853bb7 100644 --- a/flake.lock +++ b/flake.lock @@ -44,11 +44,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1747312588, - "narHash": "sha256-MmJvj6mlWzeRwKGLcwmZpKaOPZ5nJb/6al5CXqJsgjo=", + "lastModified": 1742546557, + "narHash": "sha256-QyhimDBaDBtMfRc7kyL28vo+HTwXRPq3hz+BgSJDotw=", "owner": "nixos", "repo": "nixpkgs", - "rev": "b1bebd0fe266bbd1820019612ead889e96a8fa2d", + "rev": "bfa9810ff7104a17555ab68ebdeafb6705f129b1", "type": "github" }, "original": { @@ -73,11 +73,11 @@ ] }, "locked": { - "lastModified": 1747363019, - "narHash": "sha256-N4dwkRBmpOosa4gfFkFf/LTD8oOcNkAyvZ07JvRDEf0=", + "lastModified": 1742524367, + "narHash": "sha256-KzTwk/5ETJavJZYV1DEWdCx05M4duFCxCpRbQSKWpng=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "0e624f2b1972a34be1a9b35290ed18ea4b419b6f", + "rev": "70bf752d176b2ce07417e346d85486acea9040ef", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 645ade4..565976b 100644 --- a/flake.nix +++ b/flake.nix @@ -31,15 +31,18 @@ cargo = rust; }); - buildInputs = with pkgs; [ vulkan-headers vulkan-loader vulkan-validation-layers renderdoc tracy ] - ++ pkgs.lib.optionals pkgs.stdenv.hostPlatform.isLinux (with pkgs; [ - stdenv.cc.cc.lib + renderdoc = pkgs.renderdoc.overrideAttrs (oldAttrs: { + cmakeFlags = oldAttrs.cmakeFlags ++ [ + (pkgs.lib.cmakeBool "ENABLE_UNSUPPORTED_EXPERIMENTAL_POSSIBLY_BROKEN_WAYLAND" true) + ]; + }); + buildInputs = with pkgs; [ vulkan-headers vulkan-loader vulkan-validation-layers renderdoc ] + ++ pkgs.lib.optionals pkgs.stdenv.hostPlatform.isLinux (with pkgs; [ # Wayland libxkbcommon wayland libGL - # Xorg xorg.libX11 xorg.libXcursor @@ -57,7 +60,7 @@ mkCustomShell = { packages ? [ ] }: pkgs.mkShell { nativeBuildInputs = [ - pkgs.renderdoc + renderdoc (rust.override { extensions = [ "rust-src" "rust-analyzer" ]; }) ] ++ nativeBuildInputs; @@ -65,8 +68,8 @@ ++ packages; LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs; - VK_LAYER_PATH = "${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d"; - RUST_LOG = "debug,rust_vulkan_test=trace"; + VK_LAYER_PATH = "${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d:${renderdoc}/share/vulkan/implicit_layer.d"; + RUST_LOG = "info,rust_vulkan_test=trace"; }; in { @@ -77,7 +80,7 @@ packages = { default = rustPlatform.buildRustPackage { - pname = "vulkan_test"; + pname = "rust_ash_test"; version = "0.1.0"; src = self; diff --git a/res/shaders/vertex.frag b/res/shaders/vertex.frag index 67831a9..720d192 100644 --- a/res/shaders/vertex.frag +++ b/res/shaders/vertex.frag @@ -1,12 +1,9 @@ #version 450 -layout (location = 0) in vec2 tex_coords; +layout (location = 0) in vec3 color; layout (location = 0) out vec4 f_color; -layout(set = 1, binding = 0) uniform sampler mySampler; -layout(set = 1, binding = 1) uniform texture2D myTexture; - void main() { - f_color = texture(sampler2D(myTexture, mySampler), tex_coords); -} + f_color = vec4(color, 1.0); +} \ No newline at end of file diff --git a/res/shaders/vertex.vert b/res/shaders/vertex.vert index 8c1df7c..65b0acf 100644 --- a/res/shaders/vertex.vert +++ b/res/shaders/vertex.vert @@ -1,20 +1 @@ -#version 450 - -layout (location = 0) in vec3 position; -layout (location = 1) in vec2 uv; -layout (location = 2) in mat4 model; - -layout (location = 0) out vec2 fragUv; - -layout (set = 0, binding = 0) uniform MVP { - mat4 world; - mat4 view; - mat4 projection; -} uniforms; - -void main() { - mat4 worldview = uniforms.view * uniforms.world; - vec4 modelPosition = model * vec4(position, 1.0); - gl_Position = uniforms.projection * worldview * modelPosition; - fragUv = uv; -} +#version 450 layout (location = 0) in vec2 position; layout (location = 1) in vec3 color; layout (location = 0) out vec3 fragColor; layout (set = 0, binding = 0) uniform MVPData { mat4 world; mat4 view; mat4 projection; } uniforms; void main() { mat4 worldview = uniforms.view * uniforms.world; gl_Position = uniforms.projection * worldview * vec4(position, 0.0, 1.0); fragColor = color; } \ No newline at end of file diff --git a/res/textures/wooden-crate.jpg b/res/textures/wooden-crate.jpg deleted file mode 100644 index d1c8734..0000000 Binary files a/res/textures/wooden-crate.jpg and /dev/null differ diff --git a/rust-toolchain.toml b/rust-toolchain.toml index b8889a3..00822fd 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "1.87.0" +channel = "1.85.1" diff --git a/src/core/app/context.rs b/src/core/app/context.rs deleted file mode 100644 index 80b602e..0000000 --- a/src/core/app/context.rs +++ /dev/null @@ -1,186 +0,0 @@ -use std::{ - cell::RefCell, - rc::Rc, - sync::{Arc, RwLock}, -}; - -use egui_winit_vulkano::Gui; -use vulkano::{ - command_buffer::allocator::StandardCommandBufferAllocator, - descriptor_set::allocator::StandardDescriptorSetAllocator, - device::{Device, Queue}, - instance::Instance, - memory::allocator::StandardMemoryAllocator, -}; -use vulkano_util::{renderer::VulkanoWindowRenderer, window::VulkanoWindows}; -use winit::{event_loop::EventLoopProxy, monitor::MonitorHandle, window::WindowId}; - -use crate::core::{input::InputManager, render::vulkan_context::VulkanContext, timer::Timer}; - -use super::user_event::UserEvent; - -/// Contexte d'application unifié avec Arc> pour la mutabilité partagée -#[derive(Clone)] -pub struct WindowContext { - // Données Vulkan (immutables) - pub vulkan_context: Arc, - pub device: Arc, - pub instance: Arc, - pub graphics_queue: Arc, - pub compute_queue: Arc, - pub transfer_queue: Option>, - pub memory_allocator: Arc, - pub command_buffer_allocator: Arc, - pub descriptor_set_allocator: Arc, - pub event_loop_proxy: EventLoopProxy, - pub window_id: WindowId, - - // Données mutables partagées avec Arc> - pub vulkano_windows: Rc>, - pub input_manager: Arc>, - pub timer: Arc>, - pub gui: Rc>, -} - -impl WindowContext { - pub fn new( - vulkan_context: Arc, - vulkano_windows: Rc>, - input_manager: Arc>, - timer: Arc>, - gui: Rc>, - event_loop_proxy: EventLoopProxy, - window_id: WindowId, - ) -> Self { - let vulkano_context_inner = vulkan_context.vulkano_context(); - - Self { - // Données Vulkan - vulkan_context: vulkan_context.clone(), - device: vulkano_context_inner.device().clone(), - instance: vulkano_context_inner.instance().clone(), - graphics_queue: vulkano_context_inner.graphics_queue().clone(), - compute_queue: vulkano_context_inner.compute_queue().clone(), - transfer_queue: vulkano_context_inner.transfer_queue().cloned(), - memory_allocator: vulkano_context_inner.memory_allocator().clone(), - command_buffer_allocator: vulkan_context.command_buffer_allocator().clone(), - descriptor_set_allocator: vulkan_context.descriptor_set_allocator().clone(), - event_loop_proxy, - window_id, - - // Données mutables partagées - vulkano_windows, - input_manager, - timer, - gui, - } - } - - /// Extrait les résolutions d'un moniteur donné - fn extract_resolutions_from_monitor(monitor: MonitorHandle) -> Vec<(u32, u32)> { - let video_modes: Vec<_> = monitor.video_modes().collect(); - - let resolutions: Vec<(u32, u32)> = video_modes - .into_iter() - .map(|mode| { - let size = mode.size(); - (size.width, size.height) - }) - .collect(); - - tracing::trace!( - "Modes vidéo trouvés pour {:?}: {:?}", - monitor.name(), - resolutions - ); - resolutions - } - - /// Récupère les résolutions disponibles - pub fn get_available_resolutions(&self) -> Vec<(u32, u32)> { - self.with_renderer(|renderer| { - renderer - .window() - .current_monitor() - .map(Self::extract_resolutions_from_monitor) - .unwrap_or_default() - }) - } - - /// Récupère le delta time actuel depuis le timer - pub fn get_delta_time(&self) -> f32 { - self.with_timer(|timer| timer.delta_time()) - } - - /// Récupère la taille de la fenêtre depuis le renderer - pub fn get_window_size(&self) -> [f32; 2] { - self.with_renderer(|renderer| renderer.window_size()) - } - - /// Récupère l'aspect ratio depuis le renderer - pub fn get_aspect_ratio(&self) -> f32 { - self.with_renderer(|renderer| renderer.aspect_ratio()) - } - - pub fn with_renderer(&self, f: F) -> T - where - F: FnOnce(&VulkanoWindowRenderer) -> T, - { - let vulkano_windows = self.vulkano_windows.borrow_mut(); - let renderer = vulkano_windows - .get_renderer(self.window_id) - .expect("Failed to get renderer"); - f(renderer) - } - - /// Méthode utilitaire pour accéder au renderer de manière thread-safe - pub fn with_renderer_mut(&mut self, f: F) -> T - where - F: FnOnce(&mut VulkanoWindowRenderer) -> T, - { - let mut vulkano_windows = self.vulkano_windows.borrow_mut(); - let renderer = vulkano_windows - .get_renderer_mut(self.window_id) - .expect("Failed to get renderer"); - f(renderer) - } - - /// Méthode utilitaire pour accéder au gui de manière thread-safe - pub fn with_gui(&self, f: F) -> T - where - F: FnOnce(&Gui) -> T, - { - let gui = self.gui.borrow(); - f(&gui) - } - - /// Méthode utilitaire pour accéder au gui de manière thread-safe - pub fn with_gui_mut(&mut self, f: F) -> T - where - F: FnOnce(&mut Gui) -> T, - { - let mut gui = self.gui.borrow_mut(); - f(&mut gui) - } - - /// Méthode utilitaire pour accéder à l'input manager de manière thread-safe - pub fn with_input_manager(&self, f: F) -> T - where - F: FnOnce(&InputManager) -> T, - { - let input_manager = self - .input_manager - .read() - .expect("Failed to lock input_manager"); - f(&input_manager) - } - - /// Méthode utilitaire pour accéder au timer de manière thread-safe - pub fn with_timer(&self, f: F) -> T - where - F: FnOnce(&Timer) -> T, - { - let timer = self.timer.read().expect("Failed to lock timer"); - f(&timer) - } -} diff --git a/src/core/app/mod.rs b/src/core/app/mod.rs deleted file mode 100644 index 81fb0a3..0000000 --- a/src/core/app/mod.rs +++ /dev/null @@ -1,260 +0,0 @@ -use std::cell::RefCell; -use std::collections::HashMap; -use std::rc::Rc; -use std::sync::{Arc, RwLock}; - -use super::render::vulkan_context::VulkanContext; -use crate::core::input::InputManager; -use crate::core::scene::manager::SceneManager; -use crate::core::timer::Timer; -use crate::game::scenes::main_scene::MainScene; -use egui_winit_vulkano::{Gui, GuiConfig}; -use user_event::UserEvent; -use vulkano::format::Format; -use vulkano::image::ImageUsage; -use vulkano::swapchain::PresentMode; -use vulkano_util::context::VulkanoContext; -use vulkano_util::window::{VulkanoWindows, WindowDescriptor}; -use winit::application::ApplicationHandler; -use winit::event::WindowEvent; -use winit::event_loop::{ActiveEventLoop, EventLoopProxy}; -use winit::window::WindowId; - -use self::context::WindowContext; - -pub mod context; -pub mod user_event; - -pub const DEPTH_IMAGE_ID: usize = 0; - -pub struct App { - vulkan_context: Arc, - vulkano_windows: Rc>, - gui: HashMap>>, - scene_manager: HashMap, - input_manager: Arc>, - timer: Arc>, - event_loop_proxy: EventLoopProxy, - - // Context d'application partagé par fenêtre - architecture unifiée - app_contexts: HashMap>>, -} - -impl App { - pub fn new( - vulkano_context: VulkanoContext, - input_manager: InputManager, - event_loop_proxy: EventLoopProxy, - ) -> Self { - Self { - vulkan_context: Arc::new(VulkanContext::new(vulkano_context)), - vulkano_windows: Rc::new(RefCell::new(VulkanoWindows::default())), - gui: HashMap::new(), - input_manager: Arc::new(RwLock::new(input_manager)), - scene_manager: HashMap::new(), - timer: Arc::new(RwLock::new(Timer::new())), - event_loop_proxy, - app_contexts: HashMap::new(), - } - } -} - -impl ApplicationHandler for App { - fn resumed(&mut self, event_loop: &ActiveEventLoop) { - let mut vulkano_windows = self.vulkano_windows.borrow_mut(); - let window_id = vulkano_windows.create_window( - event_loop, - self.vulkan_context.vulkano_context(), - &WindowDescriptor { - title: "Rust ASH Test".to_string(), - width: 800.0, - height: 600.0, - present_mode: PresentMode::Fifo, - cursor_visible: false, - cursor_locked: true, - ..Default::default() - }, - |_| {}, - ); - - let renderer = vulkano_windows.get_renderer_mut(window_id).unwrap(); - renderer.add_additional_image_view( - DEPTH_IMAGE_ID, - Format::D16_UNORM, - ImageUsage::DEPTH_STENCIL_ATTACHMENT, - ); - - let gui = { - Gui::new( - event_loop, - renderer.surface(), - renderer.graphics_queue(), - renderer.swapchain_format(), - GuiConfig { - is_overlay: true, - allow_srgb_render_target: true, - ..Default::default() - }, - ) - }; - self.gui.insert(window_id, Rc::new(RefCell::new(gui))); - - let mut scene_manager = SceneManager::new(); - scene_manager.load_scene(Box::new(MainScene::default())); - - self.scene_manager.insert(window_id, scene_manager); - - let app_context = Rc::new(RefCell::new(WindowContext::new( - self.vulkan_context.clone(), - self.vulkano_windows.clone(), - self.input_manager.clone(), - self.timer.clone(), - self.gui.get(&window_id).unwrap().clone(), - self.event_loop_proxy.clone(), - window_id, - ))); - self.app_contexts.insert(window_id, app_context); - } - - fn device_event( - &mut self, - _event_loop: &ActiveEventLoop, - _device_id: winit::event::DeviceId, - event: winit::event::DeviceEvent, - ) { - let mut input_manager = self.input_manager.write().unwrap(); - input_manager.process_device_event(&event); - } - - fn window_event(&mut self, event_loop: &ActiveEventLoop, id: WindowId, event: WindowEvent) { - { - let gui = self.gui.get_mut(&id).unwrap(); - let mut gui = gui.borrow_mut(); - if !gui.update(&event) { - let mut input_manager = self.input_manager.write().unwrap(); - input_manager.process_window_event(&event); - } - } - - match event { - WindowEvent::CloseRequested => { - tracing::debug!("The close button was pressed; stopping"); - event_loop.exit(); - } - WindowEvent::Resized(_) | WindowEvent::ScaleFactorChanged { .. } => { - let mut vulkano_windows = self.vulkano_windows.borrow_mut(); - vulkano_windows.get_renderer_mut(id).unwrap().resize(); - } - WindowEvent::RedrawRequested => { - let _frame_span = tracing::info_span!("frame").entered(); - - { - let _input_span = tracing::debug_span!("input_update").entered(); - let mut input_manager = self - .input_manager - .write() - .expect("Failed to lock input manager"); - input_manager.update(); - } - { - let _timer_span = tracing::debug_span!("timer_update").entered(); - let mut timer = self.timer.write().expect("Failed to lock timer"); - timer.update(); - } - - // Créer ou mettre à jour le contexte d'application - let window_context = self.app_contexts.get(&id).unwrap().clone(); - let scene_manager = self.scene_manager.get_mut(&id).unwrap(); - - // Utiliser le contexte partagé pour les scènes - { - let mut context = window_context.borrow_mut(); - - { - let _scene_span = - tracing::info_span!("scene_loading_if_not_loaded").entered(); - scene_manager - .load_scene_if_not_loaded(&mut context) - .unwrap(); - } - - if let Some(scene) = scene_manager.current_scene_mut() { - { - let _update_span = tracing::debug_span!("scene_update").entered(); - scene.update(&mut context).unwrap(); - } - - let acquire_future = { - let _acquire_span = tracing::debug_span!("acquire_swapchain").entered(); - context.with_renderer_mut(|renderer| { - renderer.acquire(None, |_| {}).unwrap() - }) - }; - - let acquire_future = { - let _render_span = tracing::debug_span!("scene_render").entered(); - scene.render(acquire_future, &mut context).unwrap() - }; - - { - let _present_span = tracing::debug_span!("present_frame").entered(); - context.with_renderer_mut(|renderer| { - renderer.present(acquire_future, true); - }); - } - } else { - tracing::warn!("No current scene found for update!"); - } - } - - { - let _gui_span = tracing::debug_span!("request_redraw").entered(); - let mut window_context = window_context.borrow_mut(); - window_context.with_renderer_mut(|renderer| { - renderer.window().request_redraw(); - }); - } - } - _ => {} - } - } - - fn user_event(&mut self, event_loop: &ActiveEventLoop, event: UserEvent) { - match event { - UserEvent::CursorGrabMode(window_id, grab) => { - let vulkano_windows = self.vulkano_windows.borrow(); - let window = vulkano_windows.get_window(window_id).unwrap(); - if let Err(e) = window.set_cursor_grab(grab) { - tracing::error!("Failed to set cursor grab: {}", e); - } - } - UserEvent::CursorVisible(window_id, visible) => { - let vulkano_windows = self.vulkano_windows.borrow(); - let window = vulkano_windows.get_window(window_id).unwrap(); - window.set_cursor_visible(visible); - } - UserEvent::ChangeScene(window_id, scene) => { - if let Some(scene_manager) = self.scene_manager.get_mut(&window_id) { - scene_manager.load_scene(scene); - } - } - UserEvent::ChangeResolution(window_id, width, height) => { - let mut vulkano_windows = self.vulkano_windows.borrow_mut(); - let window = vulkano_windows.get_window(window_id).unwrap(); - let _ = window.request_inner_size(winit::dpi::LogicalSize::new(width, height)); - let renderer = vulkano_windows.get_renderer_mut(window_id).unwrap(); - renderer.resize(); - tracing::trace!( - "Resolution changed to {}x{} for window {:?}", - width, - height, - window_id - ); - } - UserEvent::Exit(window_id) => { - tracing::trace!("Exit requested for window {:?}", window_id); - event_loop.exit(); - } - } - } -} diff --git a/src/core/app/user_event.rs b/src/core/app/user_event.rs deleted file mode 100644 index 21b70f1..0000000 --- a/src/core/app/user_event.rs +++ /dev/null @@ -1,11 +0,0 @@ -use winit::window::{CursorGrabMode, WindowId}; - -use crate::core::scene::Scene; - -pub enum UserEvent { - CursorGrabMode(WindowId, CursorGrabMode), - CursorVisible(WindowId, bool), - ChangeScene(WindowId, Box), - ChangeResolution(WindowId, f32, f32), - Exit(WindowId), -} diff --git a/src/core/input/cache.rs b/src/core/input/cache.rs deleted file mode 100644 index b9d562c..0000000 --- a/src/core/input/cache.rs +++ /dev/null @@ -1,86 +0,0 @@ -use std::{ - collections::HashMap, - hash::Hash, - ops::{Add, AddAssign, Sub}, -}; - -use winit::event::ElementState; - -pub struct CachedElementState { - cache: HashMap, -} - -impl Default for CachedElementState { - fn default() -> Self { - Self { - cache: HashMap::new(), - } - } -} - -impl CachedElementState { - pub fn set_key_state(&mut self, key: K, state: ElementState) -> Option { - let key_state = self.cache.get(&key); - let new_key_state = match key_state { - Some(old) => match state { - ElementState::Pressed => match old { - ElementState::Released => Some(ElementState::Pressed), - ElementState::Pressed => None, - }, - ElementState::Released => match old { - ElementState::Released => None, - ElementState::Pressed => Some(ElementState::Released), - }, - }, - None => match state { - ElementState::Pressed => Some(ElementState::Pressed), - ElementState::Released => Some(ElementState::Released), - }, - }; - if let Some(new_key_state) = new_key_state { - self.cache.insert(key, new_key_state); - } - new_key_state - } -} - -#[derive(Default)] -pub struct CachedMovement -where - T: Sub + Add + Default + Copy, -{ - pub old_value: Option, - pub value: T, -} - -impl CachedMovement -where - T: Sub + Add + Default + Copy, -{ - pub fn set_value(&mut self, value: T) { - self.value = value; - } - - pub fn reset(&mut self) -> T { - match self.old_value.as_ref() { - Some(old_value) => { - let diff = self.value - *old_value; - self.old_value = Some(self.value); - diff - } - None => { - self.old_value = Some(self.value); - T::default() - } - } - } -} - -impl AddAssign for CachedMovement -where - T: Add + Sub + Default + Copy, -{ - fn add_assign(&mut self, rhs: T) { - self.value = self.value + rhs; - } -} diff --git a/src/core/input/mod.rs b/src/core/input/mod.rs deleted file mode 100644 index f4a1642..0000000 --- a/src/core/input/mod.rs +++ /dev/null @@ -1,97 +0,0 @@ -use std::collections::HashMap; - -use cache::{CachedElementState, CachedMovement}; -use virtual_input::VirtualInput; -use winit::{ - event::{DeviceEvent, MouseButton, MouseScrollDelta, WindowEvent}, - keyboard::PhysicalKey, -}; - -mod cache; -mod virtual_binding; -mod virtual_input; -mod virtual_state; -pub use virtual_binding::{AxisDirection, VirtualBinding}; - -#[derive(Default)] -pub struct InputManager { - keys_state: CachedElementState, - mouse_buttons_state: CachedElementState, - mouse_position_delta: CachedMovement, - mouse_wheel_delta: CachedMovement, - virtual_input: VirtualInput, -} - -impl std::fmt::Debug for InputManager { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("InputManager") - .field("virtual_input", &self.virtual_input) - .finish() - } -} - -impl InputManager { - pub fn new(input_mapping: HashMap>) -> Self { - let mut input_manager = InputManager::default(); - for (value_name, bindings) in input_mapping { - input_manager.add_virtual_bindings(value_name, bindings); - } - input_manager - } - - pub fn process_device_event(&mut self, event: &DeviceEvent) { - if let DeviceEvent::MouseMotion { delta, .. } = event { - self.mouse_position_delta += glam::Vec2::new(delta.0 as f32, delta.1 as f32); - } - } - - pub fn process_window_event(&mut self, event: &WindowEvent) { - match event { - WindowEvent::AxisMotion { axis, value, .. } => { - self.virtual_input.update_axis_binding(*axis, *value as f32); - } - WindowEvent::KeyboardInput { event, .. } => { - let new_key_state = self - .keys_state - .set_key_state(event.physical_key, event.state); - if let Some(new_key_state) = new_key_state { - self.virtual_input - .update_key_binding(event.physical_key, new_key_state); - } - } - WindowEvent::MouseInput { button, state, .. } => { - let new_mouse_button_state = - self.mouse_buttons_state.set_key_state(*button, *state); - if let Some(new_mouse_button_state) = new_mouse_button_state { - self.virtual_input - .update_mouse_button_binding(*button, new_mouse_button_state); - } - } - WindowEvent::MouseWheel { delta, .. } => { - self.mouse_wheel_delta += match delta { - MouseScrollDelta::PixelDelta(position) => { - glam::Vec2::new(position.x as f32, position.y as f32) - } - MouseScrollDelta::LineDelta(x, y) => glam::Vec2::new(*x, *y), - }; - } - _ => {} - } - } - - /// Updates deltas before running update - pub fn update(&mut self) { - self.virtual_input - .update_mouse_move_binding(&self.mouse_position_delta.reset()); - self.virtual_input - .update_mouse_wheel_binding(&self.mouse_wheel_delta.reset()); - } - - pub fn get_virtual_input_state(&self, value_name: &str) -> f32 { - self.virtual_input.get_state(value_name) - } - - fn add_virtual_bindings(&mut self, value_name: String, bindings: Vec) { - self.virtual_input.add_bindings(value_name, bindings); - } -} diff --git a/src/core/input/virtual_binding.rs b/src/core/input/virtual_binding.rs deleted file mode 100644 index c11dd48..0000000 --- a/src/core/input/virtual_binding.rs +++ /dev/null @@ -1,30 +0,0 @@ -use winit::{ - event::{AxisId, MouseButton}, - keyboard::PhysicalKey, -}; - -#[derive(Clone)] -pub enum AxisDirection { - Normal, - Invert, -} - -impl From<&AxisDirection> for f32 { - fn from(direction: &AxisDirection) -> Self { - match direction { - AxisDirection::Normal => 1.0, - AxisDirection::Invert => -1.0, - } - } -} - -#[derive(Clone)] -pub enum VirtualBinding { - Keyboard(PhysicalKey, AxisDirection), - Axis(AxisId, AxisDirection, f32), // f32 deadzone - MouseX(AxisDirection), - MouseY(AxisDirection), - MouseWheelX(AxisDirection), - MouseWheelY(AxisDirection), - MouseButton(MouseButton, AxisDirection), -} diff --git a/src/core/input/virtual_input.rs b/src/core/input/virtual_input.rs deleted file mode 100644 index 999baed..0000000 --- a/src/core/input/virtual_input.rs +++ /dev/null @@ -1,150 +0,0 @@ -use std::{ - collections::HashMap, - sync::{Arc, RwLock}, -}; - -use winit::{ - event::{AxisId, ElementState, MouseButton}, - keyboard::PhysicalKey, -}; - -use super::{ - virtual_binding::VirtualBinding, - virtual_state::{VirtualBindingState, VirtualInputState}, -}; - -#[derive(Default)] -pub struct VirtualInput { - // Global states - states: HashMap>>, - - // Per kind of input states to keep complexity low during state updates - states_by_key: HashMap>>>, - mouse_move_states: Vec>>, - mouse_wheel_states: Vec>>, - mouse_button_states: HashMap>>>, - axis_states: HashMap>>>, -} - -impl std::fmt::Debug for VirtualInput { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut debug = f.debug_struct("VirtualInput"); - - for (name, state) in &self.states { - let value = state.read().expect("Poisoned lock for debug").value; - debug.field(name, &value); - } - - debug.finish() - } -} - -impl VirtualInput { - pub fn get_state(&self, value_name: &str) -> f32 { - self.states - .get(value_name) - .map(|state| state.read().expect("Poisoned lock for get state").value) - .unwrap_or(0.0) - } - - pub fn add_bindings(&mut self, value_name: String, new_bindings: Vec) { - let state = self - .states - .entry(value_name) - .or_insert(Arc::new(RwLock::new(VirtualInputState { - value: 0.0, - bindings: Vec::new(), - }))); - - for binding in &new_bindings { - match binding { - VirtualBinding::Keyboard(key, _) => { - self.states_by_key - .entry(*key) - .or_default() - .push(state.clone()); - } - VirtualBinding::MouseX(_) | VirtualBinding::MouseY(_) => { - self.mouse_move_states.push(state.clone()); - } - VirtualBinding::MouseButton(button, _) => { - self.mouse_button_states - .entry(*button) - .or_default() - .push(state.clone()); - } - VirtualBinding::MouseWheelX(_) | VirtualBinding::MouseWheelY(_) => { - self.mouse_wheel_states.push(state.clone()); - } - VirtualBinding::Axis(axis, _, _) => { - self.axis_states - .entry(*axis) - .or_default() - .push(state.clone()); - } - } - } - - state - .write() - .expect("Poisoned lock for add bindings") - .bindings - .extend(new_bindings.iter().map(|b| VirtualBindingState { - value: 0.0, - binding: b.clone(), - })); - } - - pub(super) fn update_key_binding(&mut self, key: PhysicalKey, key_state: ElementState) { - let states = self.states_by_key.get_mut(&key); - - if let Some(states) = states { - for state in states { - let mut state = state.write().expect("Poisoned lock for key update"); - state.update_from_key(key, key_state); - } - } - } - - pub(super) fn update_mouse_move_binding(&mut self, delta: &glam::Vec2) { - for state in &mut self.mouse_move_states { - let mut state = state.write().expect("Poisoned lock for mouse move update"); - state.update_from_mouse(delta); - } - } - - pub(super) fn update_mouse_wheel_binding(&mut self, delta: &glam::Vec2) { - for state in &mut self.mouse_wheel_states { - let mut state = state.write().expect("Poisoned lock for mouse wheel update"); - state.update_from_mouse_wheel(delta); - } - } - - pub(super) fn update_mouse_button_binding( - &mut self, - button: MouseButton, - button_state: ElementState, - ) { - let states = self.mouse_button_states.get_mut(&button); - - if let Some(states) = states { - for state in states { - let mut state = state - .write() - .expect("Poisoned lock for mouse button update"); - state.update_from_mouse_button(button, button_state); - } - } - } - - pub(super) fn update_axis_binding(&mut self, axis: AxisId, axis_state: f32) { - let states = self.axis_states.get_mut(&axis); - - if let Some(states) = states { - for state in states { - let mut state = state.write().expect("Poisoned lock for axis update"); - state.update_from_axis(axis, axis_state); - } - } - } -} diff --git a/src/core/input/virtual_state.rs b/src/core/input/virtual_state.rs deleted file mode 100644 index 2cfd098..0000000 --- a/src/core/input/virtual_state.rs +++ /dev/null @@ -1,105 +0,0 @@ -use winit::{ - event::{AxisId, ElementState, MouseButton}, - keyboard::PhysicalKey, -}; - -use super::virtual_binding::VirtualBinding; - -pub struct VirtualBindingState { - pub value: f32, - pub binding: VirtualBinding, -} - -pub struct VirtualInputState { - pub value: f32, - pub bindings: Vec, -} - -impl VirtualInputState { - pub fn update_from_key(&mut self, key: PhysicalKey, key_state: ElementState) { - let mut new_value = 0.0; - for binding in &mut self.bindings { - if let VirtualBinding::Keyboard(binding_key, direction) = &binding.binding { - if binding_key == &key { - if key_state == ElementState::Pressed { - binding.value += f32::from(direction); - } else { - binding.value = 0.0; - } - } - } - new_value += binding.value; - } - self.value = new_value; - } - - pub fn update_from_mouse(&mut self, delta: &glam::Vec2) { - let mut new_value = 0.0; - for binding in &mut self.bindings { - match &binding.binding { - VirtualBinding::MouseX(direction) => { - binding.value = f32::from(direction) * delta.x; - } - VirtualBinding::MouseY(direction) => { - binding.value = f32::from(direction) * delta.y; - } - _ => {} - } - new_value += binding.value; - } - self.value = new_value; - } - - pub fn update_from_mouse_wheel(&mut self, delta: &glam::Vec2) { - let mut new_value = 0.0; - for binding in &mut self.bindings { - match &binding.binding { - VirtualBinding::MouseWheelX(direction) => { - binding.value = f32::from(direction) * delta.x; - } - VirtualBinding::MouseWheelY(direction) => { - binding.value = f32::from(direction) * delta.y; - } - _ => {} - } - new_value += binding.value; - } - self.value = new_value; - } - - pub fn update_from_mouse_button(&mut self, button: MouseButton, button_state: ElementState) { - let mut new_value = 0.0; - for binding in &mut self.bindings { - if let VirtualBinding::MouseButton(binding_button, direction) = &binding.binding { - if binding_button == &button { - if button_state == ElementState::Pressed { - binding.value = f32::from(direction); - } else { - binding.value = 0.0; - } - } - } - new_value += binding.value; - } - self.value = new_value; - } - - pub fn update_from_axis(&mut self, axis: AxisId, axis_state: f32) { - let mut new_value = 0.0; - for binding in &mut self.bindings { - if let VirtualBinding::Axis(binding_axis, direction, deadzone) = &binding.binding { - if binding_axis == &axis { - binding.value = - f32::from(direction) * process_axis_deadzone(axis_state, *deadzone); - } - } - new_value += binding.value; - } - self.value = new_value; - } -} - -#[inline] -fn process_axis_deadzone(value: f32, deadzone: f32) -> f32 { - if value.abs() < deadzone { 0.0 } else { value } -} diff --git a/src/core/mod.rs b/src/core/mod.rs deleted file mode 100644 index 237496d..0000000 --- a/src/core/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod app; -pub mod input; -pub mod render; -pub mod scene; -pub mod timer; diff --git a/src/core/render/material_manager.rs b/src/core/render/material_manager.rs deleted file mode 100644 index 008ad07..0000000 --- a/src/core/render/material_manager.rs +++ /dev/null @@ -1,246 +0,0 @@ -use std::{ - any::TypeId, - error::Error, - sync::{Arc, RwLock, RwLockReadGuard}, -}; - -use vulkano::{device::Device, format::Format, memory::allocator::StandardMemoryAllocator}; - -pub trait Pipeline { - fn load( - &mut self, - device: &Device, - memory_allocator: &StandardMemoryAllocator, - swapchain_format: Format, - depth_format: Format, - ) -> Result<(), Box>; -} - -pub trait Material { - fn pipeline_type_id() -> TypeId - where - Self: Sized; - - fn load( - &mut self, - device: &Device, - memory_allocator: &StandardMemoryAllocator, - ) -> Result<(), Box>; -} - -pub enum MaterialState { - Loading, - Loaded, -} - -pub enum MaterialError { - PipelineNotFound, -} - -pub struct MaterialManager { - device: Arc, - memory_allocator: Arc, - swapchain_format: Format, - depth_format: Format, - - pipelines_id: Arc>>, - pipelines_state: Arc>>>>, - pipelines: Arc>>>>, - - materials_id: Arc>>, - materials_pipeline_id: Arc>>, - materials_pipeline: Arc>>>>, - materials_pipeline_state: Arc>>>>, - materials_state: Arc>>>>, - materials: Arc>>>>, -} - -impl MaterialManager { - pub fn new( - device: Arc, - memory_allocator: Arc, - swapchain_format: Format, - depth_format: Format, - ) -> Self { - Self { - device, - memory_allocator, - swapchain_format, - depth_format, - pipelines_id: Arc::new(RwLock::new(Vec::new())), - pipelines_state: Arc::new(RwLock::new(Vec::new())), - pipelines: Arc::new(RwLock::new(Vec::new())), - materials_id: Arc::new(RwLock::new(Vec::new())), - materials_pipeline_id: Arc::new(RwLock::new(Vec::new())), - materials_pipeline: Arc::new(RwLock::new(Vec::new())), - materials_pipeline_state: Arc::new(RwLock::new(Vec::new())), - materials_state: Arc::new(RwLock::new(Vec::new())), - materials: Arc::new(RwLock::new(Vec::new())), - } - } - - pub fn add_pipeline(&self) { - let type_id = TypeId::of::

(); - let pipeline = Arc::new(RwLock::new(P::default())); - - let mut pipelines_id = self.pipelines_id.write().unwrap(); - let mut pipelines_state = self.pipelines_state.write().unwrap(); - let mut pipelines = self.pipelines.write().unwrap(); - - pipelines_id.push(type_id); - pipelines_state.push(Arc::new(RwLock::new(MaterialState::Loading))); - pipelines.push(pipeline.clone()); - } - - pub fn add_material(&self) -> Result<(), MaterialError> { - let pipeline_id = M::pipeline_type_id(); - - let pipeline_result = { - let pipelines_id = self.pipelines_id.read().unwrap(); - let pipelines_state = self.pipelines_state.read().unwrap(); - let pipelines = self.pipelines.read().unwrap(); - - pipelines_id - .iter() - .zip(pipelines.iter()) - .zip(pipelines_state.iter()) - .find(|((id, _), _)| *id == &pipeline_id) - .map(|((_, pipeline), state)| (pipeline.clone(), state.clone())) - }; - - let (pipeline, pipeline_state) = match pipeline_result { - Some(pipeline) => pipeline, - None => { - tracing::error!( - "Pipeline with id {pipeline_id:?} not found, please add it before adding a material" - ); - return Err(MaterialError::PipelineNotFound); - } - }; - - let type_id = TypeId::of::(); - - let mut materials_id = self.materials_id.write().unwrap(); - let mut materials_pipeline_id = self.materials_pipeline_id.write().unwrap(); - let mut materials_pipeline = self.materials_pipeline.write().unwrap(); - let mut materials_pipeline_state = self.materials_pipeline_state.write().unwrap(); - let mut materials_state = self.materials_state.write().unwrap(); - let mut materials = self.materials.write().unwrap(); - - materials_id.push(type_id); - materials_pipeline_id.push(pipeline_id); - materials_pipeline.push(pipeline); - materials_pipeline_state.push(pipeline_state); - materials_state.push(Arc::new(RwLock::new(MaterialState::Loading))); - materials.push(Arc::new(RwLock::new(M::default()))); - - Ok(()) - } - - pub fn update_swapchain_format(&mut self, swapchain_format: Format) { - if self.swapchain_format == swapchain_format { - return; - } - - self.swapchain_format = swapchain_format; - self.mark_all_pipelines_as_loading(); - } - - fn mark_all_pipelines_as_loading(&self) { - let pipelines_state = self.pipelines_state.write().unwrap(); - - for state in pipelines_state.iter() { - let mut state = state.write().unwrap(); - *state = MaterialState::Loading; - } - } - - fn load_pipelines(&self) { - let pipelines_state = self.pipelines_state.read().unwrap(); - let pipelines = self.pipelines.read().unwrap(); - - let iter = pipelines_state - .iter() - .zip(pipelines.iter()) - .filter(|(state, _)| { - let state = state.read().unwrap(); - matches!(*state, MaterialState::Loading) - }); - - for (state, pipeline) in iter { - let mut pipeline = pipeline.write().unwrap(); - let result = pipeline.load( - &self.device, - &self.memory_allocator, - self.swapchain_format, - self.depth_format, - ); - - match result { - Ok(_) => { - let mut state = state.write().unwrap(); - *state = MaterialState::Loaded; - } - Err(e) => { - tracing::error!("Failed to load pipeline: {e}"); - } - } - } - } - - fn load_materials(&self) { - let materials_state = self.materials_state.read().unwrap(); - let materials = self.materials.read().unwrap(); - - let iter = materials_state - .iter() - .zip(materials.iter()) - .filter(|(state, _)| { - let state = state.read().unwrap(); - matches!(*state, MaterialState::Loading) - }); - - for (state, material) in iter { - let mut material = material.write().unwrap(); - let result = material.load(&self.device, &self.memory_allocator); - - match result { - Ok(_) => { - let mut state = state.write().unwrap(); - *state = MaterialState::Loaded; - } - Err(e) => { - tracing::error!("Failed to load material: {e}"); - } - } - } - } - - fn render_materials(&self, f: F) - where - F: Fn(RwLockReadGuard<'_, dyn Material>, RwLockReadGuard<'_, dyn Pipeline>), - { - let materials = self.materials.read().unwrap(); - let materials_state = self.materials_state.read().unwrap(); - let materials_pipeline = self.materials_pipeline.read().unwrap(); - let materials_pipeline_state = self.materials_pipeline_state.read().unwrap(); - - materials - .iter() - .zip(materials_state.iter()) - .zip(materials_pipeline.iter()) - .zip(materials_pipeline_state.iter()) - .filter(|(((_, material_state), _), pipeline_state)| { - let material_state = material_state.read().unwrap(); - let pipeline_state = pipeline_state.read().unwrap(); - matches!(*material_state, MaterialState::Loaded) - && matches!(*pipeline_state, MaterialState::Loaded) - }) - .for_each(|(((material, _), pipeline), _)| { - let material = material.read().unwrap(); - let pipeline = pipeline.read().unwrap(); - - f(material, pipeline); - }); - } -} diff --git a/src/core/render/mod.rs b/src/core/render/mod.rs deleted file mode 100644 index ec7ac54..0000000 --- a/src/core/render/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod material_manager; -pub mod primitives; -pub mod render_pass_manager; -pub mod texture; -pub mod vulkan_context; diff --git a/src/core/render/primitives/camera.rs b/src/core/render/primitives/camera.rs deleted file mode 100644 index f27622a..0000000 --- a/src/core/render/primitives/camera.rs +++ /dev/null @@ -1,122 +0,0 @@ -use std::{f32::consts::FRAC_PI_2, sync::Arc}; - -use glam::{Mat4, Vec3, Vec4}; -use vulkano::{ - Validated, - buffer::{AllocateBufferError, Subbuffer}, - memory::allocator::StandardMemoryAllocator, -}; - -use crate::core::{input::InputManager, timer::Timer}; - -use super::mvp::Mvp; - -// See docs/OPENGL_VULKAN_DIFF.md -const OPENGL_TO_VULKAN_Y_AXIS_FLIP: Mat4 = Mat4 { - x_axis: Vec4::new(1.0, 0.0, 0.0, 0.0), - y_axis: Vec4::new(0.0, -1.0, 0.0, 0.0), - z_axis: Vec4::new(0.0, 0.0, 1.0, 0.0), - w_axis: Vec4::new(0.0, 0.0, 0.0, 1.0), -}; - -#[derive(Default)] -pub struct Camera3D { - projection: Mat4, - - position: Vec3, - rotation: Vec3, - aspect_ratio: f32, - fov: f32, - near: f32, - far: f32, -} - -impl Camera3D { - pub fn new(aspect_ratio: f32, fov: f32, near: f32, far: f32) -> Self { - Self { - projection: Mat4::perspective_rh(fov, aspect_ratio, near, far), - position: Vec3::ZERO, - rotation: Vec3::ZERO, - aspect_ratio, - fov, - near, - far, - } - } - - pub fn update( - &mut self, - input_manager: &InputManager, - timer: &Timer, - movement_speed: f32, - camera_sensitivity: f32, - window_aspect_ratio: f32, - ) { - // Process camera rotation - let camera_delta = camera_sensitivity * timer.delta_time(); - self.rotation += Vec3::new( - (input_manager.get_virtual_input_state("mouse_y") * camera_delta).to_radians(), - (input_manager.get_virtual_input_state("mouse_x") * camera_delta).to_radians(), - 0.0, - ); - - if self.rotation.x > FRAC_PI_2 { - self.rotation = Vec3::new(FRAC_PI_2, self.rotation.y, 0.0); - } - - if self.rotation.x < -FRAC_PI_2 { - self.rotation = Vec3::new(-FRAC_PI_2, self.rotation.y, 0.0); - } - - let movement_delta = movement_speed * timer.delta_time(); - - let (yaw_sin, yaw_cos) = self.rotation.y.sin_cos(); - let forward = Vec3::new(yaw_cos, 0.0, yaw_sin).normalize(); - let right = Vec3::new(-yaw_sin, 0.0, yaw_cos).normalize(); - - let tx = input_manager.get_virtual_input_state("move_right") * movement_delta; - self.position += tx * right; - - let tz = input_manager.get_virtual_input_state("move_forward") * movement_delta; - self.position += tz * forward; - - if self.aspect_ratio != window_aspect_ratio { - self.aspect_ratio = window_aspect_ratio; - self.projection = - Mat4::perspective_rh(self.fov, self.aspect_ratio, self.near, self.far); - } - } - - pub fn set_projection(&mut self, projection: Mat4) { - self.projection = projection; - } - - pub fn get_position(&self) -> Vec3 { - self.position - } - - pub fn get_rotation(&self) -> Vec3 { - self.rotation - } - - pub fn create_buffer( - &self, - memory_allocator: &Arc, - ) -> Result, Validated> { - let (sin_pitch, cos_pitch) = self.rotation.x.sin_cos(); - let (sin_yaw, cos_yaw) = self.rotation.y.sin_cos(); - - let view_matrix = Mat4::look_to_rh( - self.position, - Vec3::new(cos_pitch * cos_yaw, sin_pitch, cos_pitch * sin_yaw).normalize(), - Vec3::Y, - ); - - Mvp { - model: OPENGL_TO_VULKAN_Y_AXIS_FLIP.to_cols_array_2d(), - view: view_matrix.to_cols_array_2d(), - projection: self.projection.to_cols_array_2d(), - } - .into_buffer(memory_allocator) - } -} diff --git a/src/core/render/primitives/mod.rs b/src/core/render/primitives/mod.rs deleted file mode 100644 index 5ab8266..0000000 --- a/src/core/render/primitives/mod.rs +++ /dev/null @@ -1,25 +0,0 @@ -use std::{collections::BTreeMap, sync::Arc}; - -use vulkano::{ - Validated, VulkanError, - descriptor_set::{ - DescriptorSet, - allocator::StandardDescriptorSetAllocator, - layout::{DescriptorSetLayout, DescriptorSetLayoutBinding}, - }, -}; - -pub mod camera; -pub mod mvp; -pub mod transform; -pub mod vertex; - -pub trait AsBindableDescriptorSet { - fn as_descriptor_set_layout_bindings() -> BTreeMap; - - fn as_descriptor_set( - descriptor_set_allocator: &Arc, - layout: &Arc, - data: &T, - ) -> Result, Validated>; -} diff --git a/src/core/render/primitives/mvp.rs b/src/core/render/primitives/mvp.rs deleted file mode 100644 index d05307e..0000000 --- a/src/core/render/primitives/mvp.rs +++ /dev/null @@ -1,70 +0,0 @@ -use std::collections::BTreeMap; -use std::sync::Arc; - -use vulkano::buffer::{ - AllocateBufferError, Buffer, BufferContents, BufferCreateInfo, BufferUsage, Subbuffer, -}; -use vulkano::descriptor_set::allocator::StandardDescriptorSetAllocator; -use vulkano::descriptor_set::layout::{ - DescriptorSetLayout, DescriptorSetLayoutBinding, DescriptorType, -}; -use vulkano::descriptor_set::{DescriptorSet, WriteDescriptorSet}; -use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}; -use vulkano::shader::ShaderStages; -use vulkano::{Validated, VulkanError}; - -use crate::core::render::primitives::AsBindableDescriptorSet; - -#[derive(BufferContents, Clone, Copy)] -#[repr(C)] -pub struct Mvp { - pub model: [[f32; 4]; 4], - pub view: [[f32; 4]; 4], - pub projection: [[f32; 4]; 4], -} - -impl Mvp { - pub fn into_buffer( - self, - memory_allocator: &Arc, - ) -> Result, Validated> { - Buffer::from_iter( - memory_allocator.clone(), - BufferCreateInfo { - usage: BufferUsage::UNIFORM_BUFFER, - ..Default::default() - }, - AllocationCreateInfo { - memory_type_filter: MemoryTypeFilter::PREFER_DEVICE - | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, - ..Default::default() - }, - [self], - ) - } -} - -impl AsBindableDescriptorSet> for Mvp { - fn as_descriptor_set_layout_bindings() -> BTreeMap { - BTreeMap::::from_iter([( - 0, - DescriptorSetLayoutBinding { - stages: ShaderStages::VERTEX, - ..DescriptorSetLayoutBinding::descriptor_type(DescriptorType::UniformBuffer) - }, - )]) - } - - fn as_descriptor_set( - descriptor_set_allocator: &Arc, - layout: &Arc, - data: &Subbuffer<[Mvp]>, - ) -> Result, Validated> { - DescriptorSet::new( - descriptor_set_allocator.clone(), - layout.clone(), - [WriteDescriptorSet::buffer(0, data.clone())], - [], - ) - } -} diff --git a/src/core/render/primitives/transform.rs b/src/core/render/primitives/transform.rs deleted file mode 100644 index 4d870b0..0000000 --- a/src/core/render/primitives/transform.rs +++ /dev/null @@ -1,81 +0,0 @@ -use std::sync::Arc; - -use glam::{Mat4, Quat, Vec3}; -use vulkano::{ - Validated, - buffer::{ - AllocateBufferError, Buffer, BufferContents, BufferCreateInfo, BufferUsage, Subbuffer, - }, - memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, - pipeline::graphics::vertex_input::Vertex, -}; - -pub struct Transform { - pub position: Vec3, - pub rotation: Quat, - pub scale: Vec3, -} - -#[derive(BufferContents, Vertex)] -#[repr(C)] -pub struct TransformRaw { - #[format(R32G32B32A32_SFLOAT)] - pub model: [[f32; 4]; 4], -} - -impl Default for Transform { - fn default() -> Self { - Self { - position: Vec3::default(), - rotation: Quat::default(), - scale: Vec3::ONE, - } - } -} - -impl Transform { - pub fn rotate(&mut self, rotation: Quat) { - self.rotation *= rotation; - } - - pub fn translate(&mut self, translation: Vec3) { - self.position += translation; - } - - pub fn scale(&mut self, scale: Vec3) { - self.scale *= scale; - } - - pub fn to_raw_tranform(&self) -> TransformRaw { - TransformRaw { - model: (Mat4::from_translation(self.position) - * Mat4::from_quat(self.rotation) - * Mat4::from_scale(self.scale)) - .to_cols_array_2d(), - } - } - - pub fn create_buffer( - memory_allocator: &Arc, - transforms: &[Transform], - ) -> Result, Validated> { - let transform_raws: Vec = - transforms.iter().map(|t| t.to_raw_tranform()).collect(); - - let buffer = Buffer::from_iter( - memory_allocator.clone(), - BufferCreateInfo { - usage: BufferUsage::VERTEX_BUFFER, - ..Default::default() - }, - AllocationCreateInfo { - memory_type_filter: MemoryTypeFilter::PREFER_DEVICE - | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, - ..Default::default() - }, - transform_raws, - )?; - - Ok(buffer) - } -} diff --git a/src/core/render/primitives/vertex.rs b/src/core/render/primitives/vertex.rs deleted file mode 100644 index 166ac44..0000000 --- a/src/core/render/primitives/vertex.rs +++ /dev/null @@ -1,22 +0,0 @@ -use vulkano::buffer::BufferContents; -use vulkano::pipeline::graphics::vertex_input::Vertex; - -#[derive(BufferContents, Vertex)] -#[repr(C)] -pub struct Vertex2D { - #[format(R32G32_SFLOAT)] - pub position: [f32; 2], - - #[format(R32G32_SFLOAT)] - pub uv: [f32; 2], -} - -#[derive(BufferContents, Vertex)] -#[repr(C)] -pub struct Vertex3D { - #[format(R32G32B32_SFLOAT)] - pub position: [f32; 3], - - #[format(R32G32_SFLOAT)] - pub uv: [f32; 2], -} diff --git a/src/core/render/render_pass_manager.rs b/src/core/render/render_pass_manager.rs deleted file mode 100644 index 02c3d7a..0000000 --- a/src/core/render/render_pass_manager.rs +++ /dev/null @@ -1,113 +0,0 @@ -use std::sync::Arc; -use vulkano::{ - command_buffer::{AutoCommandBufferBuilder, RenderingAttachmentInfo, RenderingInfo}, - image::view::ImageView, - pipeline::graphics::viewport::Viewport, - render_pass::{AttachmentLoadOp, AttachmentStoreOp}, -}; - -/// Types de render passes disponibles -#[derive(Debug, Clone)] -pub enum RenderPassType { - Standard, - ShadowMap, - PostProcess, -} - -/// Configuration pour un render pass -#[derive(Debug, Clone)] -pub struct RenderPassConfig { - pub pass_type: RenderPassType, - pub clear_color: Option<[f32; 4]>, - pub clear_depth: Option, - pub load_op: AttachmentLoadOp, - pub store_op: AttachmentStoreOp, -} - -impl Default for RenderPassConfig { - fn default() -> Self { - Self { - pass_type: RenderPassType::Standard, - clear_color: Some([0.0, 0.0, 0.0, 1.0]), - clear_depth: Some(1.0), - load_op: AttachmentLoadOp::Clear, - store_op: AttachmentStoreOp::Store, - } - } -} - -/// Gestionnaire de render passes réutilisable -pub struct RenderPassManager; - -impl RenderPassManager { - /// Commence un render pass standard avec les paramètres donnés - pub fn begin_standard_rendering( - builder: &mut AutoCommandBufferBuilder, - config: &RenderPassConfig, - color_attachment: Arc, - depth_attachment: Option>, - window_size: [f32; 2], - ) -> Result<(), Box> { - let viewport = Viewport { - offset: [0.0, 0.0], - extent: window_size, - depth_range: 0.0..=1.0, - }; - - let mut rendering_info = RenderingInfo { - color_attachments: vec![Some(RenderingAttachmentInfo { - load_op: config.load_op, - store_op: config.store_op, - clear_value: config.clear_color.map(|c| c.into()), - ..RenderingAttachmentInfo::image_view(color_attachment) - })], - depth_attachment: None, - ..Default::default() - }; - - if let Some(depth_view) = depth_attachment { - rendering_info.depth_attachment = Some(RenderingAttachmentInfo { - load_op: AttachmentLoadOp::Clear, - store_op: AttachmentStoreOp::DontCare, - clear_value: config.clear_depth.map(|d| [d].into()), - ..RenderingAttachmentInfo::image_view(depth_view) - }); - } - - builder - .begin_rendering(rendering_info)? - .set_viewport(0, [viewport].into_iter().collect())?; - - Ok(()) - } - - /// Termine le render pass actuel - pub fn end_rendering( - builder: &mut AutoCommandBufferBuilder, - ) -> Result<(), Box> { - builder.end_rendering()?; - Ok(()) - } - - /// Crée une configuration pour un render pass shadow map - pub fn shadow_map_config() -> RenderPassConfig { - RenderPassConfig { - pass_type: RenderPassType::ShadowMap, - clear_color: None, - clear_depth: Some(1.0), - load_op: AttachmentLoadOp::Clear, - store_op: AttachmentStoreOp::Store, - } - } - - /// Crée une configuration pour un render pass de post-processing - pub fn post_process_config() -> RenderPassConfig { - RenderPassConfig { - pass_type: RenderPassType::PostProcess, - clear_color: Some([0.0, 0.0, 0.0, 1.0]), - clear_depth: None, - load_op: AttachmentLoadOp::Load, - store_op: AttachmentStoreOp::Store, - } - } -} diff --git a/src/core/render/texture.rs b/src/core/render/texture.rs deleted file mode 100644 index db0bcc5..0000000 --- a/src/core/render/texture.rs +++ /dev/null @@ -1,168 +0,0 @@ -use std::{collections::BTreeMap, error::Error, sync::Arc}; - -use image::DynamicImage; -use vulkano::{ - Validated, VulkanError, - buffer::{Buffer, BufferCreateInfo, BufferUsage}, - command_buffer::{AutoCommandBufferBuilder, CopyBufferToImageInfo, PrimaryAutoCommandBuffer}, - descriptor_set::{ - DescriptorSet, WriteDescriptorSet, - allocator::StandardDescriptorSetAllocator, - layout::{DescriptorSetLayout, DescriptorSetLayoutBinding, DescriptorType}, - }, - device::Device, - format::Format, - image::{ - Image, ImageCreateInfo, ImageType, ImageUsage, - sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo}, - view::ImageView, - }, - memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, - shader::ShaderStages, -}; - -use crate::core::render::primitives::AsBindableDescriptorSet; - -pub struct Texture { - texture: Arc, - sampler: Arc, -} - -impl Texture { - fn new(texture: Arc, sampler: Arc) -> Self { - Self { texture, sampler } - } - - pub fn from_file( - device: &Arc, - memory_allocator: &Arc, - builder: &mut AutoCommandBufferBuilder, - path: &str, - ) -> Result> { - let _span = tracing::info_span!("texture_load_from_file", path = path); - - let bytes = std::fs::read(path)?; - Self::from_bytes(device, memory_allocator, builder, &bytes) - } - - pub fn from_bytes( - device: &Arc, - memory_allocator: &Arc, - builder: &mut AutoCommandBufferBuilder, - bytes: &[u8], - ) -> Result> { - let image = image::load_from_memory(bytes)?; - Self::from_dynamic_image(device, memory_allocator, builder, image) - } - - pub fn from_dynamic_image( - device: &Arc, - memory_allocator: &Arc, - builder: &mut AutoCommandBufferBuilder, - image: DynamicImage, - ) -> Result> { - let _span = tracing::info_span!("texture_from_dynamic_image"); - - let image_data = image.to_rgba8(); - let image_dimensions = image_data.dimensions(); - let image_data = image_data.into_raw(); - - let upload_buffer = Buffer::new_slice( - memory_allocator.clone(), - BufferCreateInfo { - usage: BufferUsage::TRANSFER_SRC, - ..Default::default() - }, - AllocationCreateInfo { - memory_type_filter: MemoryTypeFilter::PREFER_HOST - | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, - ..Default::default() - }, - image_data.len() as u64, - )?; - - { - let buffer_data = &mut *upload_buffer.write()?; - buffer_data.copy_from_slice(&image_data); - } - - let image = Image::new( - memory_allocator.clone(), - ImageCreateInfo { - image_type: ImageType::Dim2d, - format: Format::R8G8B8A8_SRGB, - extent: [image_dimensions.0, image_dimensions.1, 1], - array_layers: 1, - usage: ImageUsage::TRANSFER_DST | ImageUsage::SAMPLED, - ..Default::default() - }, - AllocationCreateInfo::default(), - )?; - - builder.copy_buffer_to_image(CopyBufferToImageInfo::buffer_image( - upload_buffer, - image.clone(), - ))?; - - let sampler = Sampler::new( - device.clone(), - SamplerCreateInfo { - mag_filter: Filter::Linear, - min_filter: Filter::Linear, - address_mode: [SamplerAddressMode::Repeat; 3], - ..Default::default() - }, - )?; - - let image_view = ImageView::new_default(image)?; - - tracing::trace!("Texture loaded with dimensions {:?}", image_dimensions); - - Ok(Self::new(image_view, sampler)) - } - - pub fn get_texture(&self) -> &Arc { - &self.texture - } - - pub fn get_sampler(&self) -> &Arc { - &self.sampler - } -} - -impl AsBindableDescriptorSet for Texture { - fn as_descriptor_set_layout_bindings() -> BTreeMap { - BTreeMap::::from_iter([ - ( - 0, - DescriptorSetLayoutBinding { - stages: ShaderStages::FRAGMENT, - ..DescriptorSetLayoutBinding::descriptor_type(DescriptorType::Sampler) - }, - ), - ( - 1, - DescriptorSetLayoutBinding { - stages: ShaderStages::FRAGMENT, - ..DescriptorSetLayoutBinding::descriptor_type(DescriptorType::SampledImage) - }, - ), - ]) - } - - fn as_descriptor_set( - descriptor_set_allocator: &Arc, - layout: &Arc, - data: &Texture, - ) -> Result, Validated> { - DescriptorSet::new( - descriptor_set_allocator.clone(), - layout.clone(), - [ - WriteDescriptorSet::sampler(0, data.sampler.clone()), - WriteDescriptorSet::image_view(1, data.texture.clone()), - ], - [], - ) - } -} diff --git a/src/core/render/vulkan_context.rs b/src/core/render/vulkan_context.rs deleted file mode 100644 index 3d91ec3..0000000 --- a/src/core/render/vulkan_context.rs +++ /dev/null @@ -1,45 +0,0 @@ -use std::sync::Arc; - -use vulkano::{ - command_buffer::allocator::StandardCommandBufferAllocator, - descriptor_set::allocator::StandardDescriptorSetAllocator, -}; -use vulkano_util::context::VulkanoContext; - -pub struct VulkanContext { - vulkano_context: VulkanoContext, - command_buffer_allocator: Arc, - descriptor_set_allocator: Arc, -} - -impl VulkanContext { - pub fn new(vulkano_context: VulkanoContext) -> Self { - let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new( - vulkano_context.device().clone(), - Default::default(), - )); - - let descriptor_set_allocator = Arc::new(StandardDescriptorSetAllocator::new( - vulkano_context.device().clone(), - Default::default(), - )); - - Self { - vulkano_context, - command_buffer_allocator, - descriptor_set_allocator, - } - } - - pub fn vulkano_context(&self) -> &VulkanoContext { - &self.vulkano_context - } - - pub fn command_buffer_allocator(&self) -> &Arc { - &self.command_buffer_allocator - } - - pub fn descriptor_set_allocator(&self) -> &Arc { - &self.descriptor_set_allocator - } -} diff --git a/src/core/scene/manager.rs b/src/core/scene/manager.rs deleted file mode 100644 index cf07ebc..0000000 --- a/src/core/scene/manager.rs +++ /dev/null @@ -1,65 +0,0 @@ -use std::error::Error; - -use crate::core::app::context::WindowContext; - -use super::Scene; - -pub struct SceneManager { - scenes: Vec>, - current_scene_index: Option, -} - -impl SceneManager { - pub fn new() -> Self { - Self { - scenes: Vec::new(), - current_scene_index: None, - } - } - - pub fn load_scene(&mut self, scene: Box) { - self.scenes.push(scene); - self.current_scene_index = Some(self.scenes.len() - 1); - } - - pub fn replace_current_scene(&mut self, scene: Box) { - if let Some(index) = self.current_scene_index { - if index < self.scenes.len() { - self.scenes[index].unload(); - self.scenes[index] = scene; - } - } else { - self.load_scene(scene); - } - } - - pub fn current_scene(&self) -> Option<&Box> { - if let Some(index) = self.current_scene_index { - self.scenes.get(index) - } else { - None - } - } - - pub fn current_scene_mut(&mut self) -> Option<&mut Box> { - if let Some(index) = self.current_scene_index { - self.scenes.get_mut(index) - } else { - None - } - } - - pub fn load_scene_if_not_loaded( - &mut self, - app_context: &mut WindowContext, - ) -> Result<(), Box> { - if let Some(scene) = self.current_scene_mut() { - if !scene.loaded() { - scene.load(app_context)?; - } - } else { - tracing::warn!("No scene found in SceneManager!"); - } - Ok(()) - } -} diff --git a/src/core/scene/mod.rs b/src/core/scene/mod.rs deleted file mode 100644 index 5dd8a57..0000000 --- a/src/core/scene/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::error::Error; - -use vulkano::sync::GpuFuture; - -use crate::core::app::context::WindowContext; - -pub mod manager; - -pub trait Scene { - fn loaded(&self) -> bool; - fn load(&mut self, app_context: &mut WindowContext) -> Result<(), Box>; - fn update(&mut self, app_context: &mut WindowContext) -> Result<(), Box>; - fn render( - &mut self, - acquire_future: Box, - app_context: &mut WindowContext, - ) -> Result, Box>; - fn unload(&mut self); -} diff --git a/src/core/timer.rs b/src/core/timer.rs deleted file mode 100644 index 3245a4c..0000000 --- a/src/core/timer.rs +++ /dev/null @@ -1,34 +0,0 @@ -pub struct Timer { - start_time: std::time::Instant, - last_time: std::time::Instant, - current_time: std::time::Instant, - delta_time: f32, -} - -impl Timer { - pub fn new() -> Self { - Self { - start_time: std::time::Instant::now(), - last_time: std::time::Instant::now(), - current_time: std::time::Instant::now(), - delta_time: 0.0, - } - } - - pub fn update(&mut self) { - self.current_time = std::time::Instant::now(); - self.delta_time = self - .current_time - .duration_since(self.last_time) - .as_secs_f32(); - self.last_time = self.current_time; - } - - pub fn delta_time(&self) -> f32 { - self.delta_time - } - - pub fn start_time(&self) -> std::time::Instant { - self.start_time - } -} diff --git a/src/game/assets/mod.rs b/src/game/assets/mod.rs deleted file mode 100644 index d793a66..0000000 --- a/src/game/assets/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod square; diff --git a/src/game/assets/square.rs b/src/game/assets/square.rs deleted file mode 100644 index c4a33ad..0000000 --- a/src/game/assets/square.rs +++ /dev/null @@ -1,231 +0,0 @@ -use std::{collections::BTreeMap, error::Error, sync::Arc}; - -use vulkano::{ - buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer}, - command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer}, - descriptor_set::{ - DescriptorSet, WriteDescriptorSet, - allocator::StandardDescriptorSetAllocator, - layout::{DescriptorSetLayoutBinding, DescriptorSetLayoutCreateInfo, DescriptorType}, - }, - device::Device, - format::Format, - memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}, - pipeline::{ - DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout, - PipelineShaderStageCreateInfo, - graphics::{ - GraphicsPipelineCreateInfo, - color_blend::{ColorBlendAttachmentState, ColorBlendState}, - depth_stencil::{DepthState, DepthStencilState}, - input_assembly::InputAssemblyState, - multisample::MultisampleState, - rasterization::RasterizationState, - subpass::PipelineRenderingCreateInfo, - vertex_input::{Vertex, VertexDefinition}, - viewport::ViewportState, - }, - layout::{PipelineDescriptorSetLayoutCreateInfo, PipelineLayoutCreateFlags}, - }, - shader::ShaderStages, -}; - -use crate::core::render::{ - primitives::{AsBindableDescriptorSet, mvp::Mvp, transform::TransformRaw, vertex::Vertex3D}, - texture::Texture, -}; - -const VERTICES: [Vertex3D; 4] = [ - Vertex3D { - position: [-0.5, -0.5, 0.0], - uv: [0.0, 0.0], - }, - Vertex3D { - position: [-0.5, 0.5, 0.0], - uv: [0.0, 1.0], - }, - Vertex3D { - position: [0.5, -0.5, 0.0], - uv: [1.0, 0.0], - }, - Vertex3D { - position: [0.5, 0.5, 0.0], - uv: [1.0, 1.0], - }, -]; - -const INDICES: [u32; 6] = [0, 2, 1, 2, 3, 1]; - -pub mod shaders { - pub mod vs { - vulkano_shaders::shader! { - ty: "vertex", - path: r"res/shaders/vertex.vert", - generate_structs: false, - } - } - - pub mod fs { - vulkano_shaders::shader! { - ty: "fragment", - path: r"res/shaders/vertex.frag", - generate_structs: false, - } - } -} - -pub struct Square { - vertex_buffer: Subbuffer<[Vertex3D]>, - index_buffer: Subbuffer<[u32]>, - pipeline: Arc, -} - -impl Square { - pub fn new( - device: &Arc, - memory_allocator: &Arc, - swapchain_format: Format, - depth_format: Format, - ) -> Result> { - let vertex_buffer = Buffer::from_iter( - memory_allocator.clone(), - BufferCreateInfo { - usage: BufferUsage::VERTEX_BUFFER, - ..Default::default() - }, - AllocationCreateInfo { - memory_type_filter: MemoryTypeFilter::PREFER_DEVICE - | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, - ..Default::default() - }, - Vec::from_iter(VERTICES), - )?; - let index_buffer = Buffer::from_iter( - memory_allocator.clone(), - BufferCreateInfo { - usage: BufferUsage::INDEX_BUFFER, - ..Default::default() - }, - AllocationCreateInfo { - memory_type_filter: MemoryTypeFilter::PREFER_DEVICE - | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, - ..Default::default() - }, - Vec::from_iter(INDICES), - )?; - - let vs = shaders::vs::load(device.clone())? - .entry_point("main") - .ok_or("Failed find main entry point of vertex shader".to_string())?; - - let fs = shaders::fs::load(device.clone())? - .entry_point("main") - .ok_or("Failed find main entry point of fragment shader".to_string())?; - - let vertex_input_state = - [Vertex3D::per_vertex(), TransformRaw::per_instance()].definition(&vs)?; - - let stages = [ - PipelineShaderStageCreateInfo::new(vs), - PipelineShaderStageCreateInfo::new(fs), - ]; - - let vertex_bindings = Mvp::as_descriptor_set_layout_bindings(); - let texture_bindings = Texture::as_descriptor_set_layout_bindings(); - - let vertex_descriptor_set_layout = DescriptorSetLayoutCreateInfo { - bindings: vertex_bindings, - ..Default::default() - }; - - let fragment_descriptor_set_layout = DescriptorSetLayoutCreateInfo { - bindings: texture_bindings, - ..Default::default() - }; - - let create_info = PipelineDescriptorSetLayoutCreateInfo { - set_layouts: vec![vertex_descriptor_set_layout, fragment_descriptor_set_layout], - flags: PipelineLayoutCreateFlags::default(), - push_constant_ranges: vec![], - } - .into_pipeline_layout_create_info(device.clone())?; - - let layout = PipelineLayout::new(device.clone(), create_info)?; - - let subpass = PipelineRenderingCreateInfo { - color_attachment_formats: vec![Some(swapchain_format)], - depth_attachment_format: Some(depth_format), - ..Default::default() - }; - - let pipeline = GraphicsPipeline::new( - device.clone(), - None, - GraphicsPipelineCreateInfo { - stages: stages.into_iter().collect(), - vertex_input_state: Some(vertex_input_state), - input_assembly_state: Some(InputAssemblyState::default()), - viewport_state: Some(ViewportState::default()), - rasterization_state: Some(RasterizationState::default()), - multisample_state: Some(MultisampleState::default()), - color_blend_state: Some(ColorBlendState::with_attachment_states( - subpass.color_attachment_formats.len() as u32, - ColorBlendAttachmentState::default(), - )), - depth_stencil_state: Some(DepthStencilState { - depth: Some(DepthState::simple()), - ..Default::default() - }), - dynamic_state: [DynamicState::Viewport].into_iter().collect(), - subpass: Some(subpass.into()), - ..GraphicsPipelineCreateInfo::layout(layout) - }, - )?; - - Ok(Self { - vertex_buffer, - index_buffer, - pipeline, - }) - } - - pub fn render( - &self, - command_buffer: &mut AutoCommandBufferBuilder, - descriptor_set_allocator: &Arc, - mvp_uniform: &Subbuffer<[Mvp]>, - transform_uniform: &Subbuffer<[TransformRaw]>, - texture: &Texture, - ) -> Result<(), Box> { - let layouts = self.pipeline.layout().set_layouts(); - - let uniform_descriptor_set = - Mvp::as_descriptor_set(descriptor_set_allocator, &layouts[0], mvp_uniform)?; - - let texture_descriptor_set = - Texture::as_descriptor_set(descriptor_set_allocator, &layouts[1], texture)?; - - command_buffer.bind_pipeline_graphics(self.pipeline.clone())?; - command_buffer.bind_descriptor_sets( - PipelineBindPoint::Graphics, - self.pipeline.layout().clone(), - 0, - vec![uniform_descriptor_set, texture_descriptor_set], - )?; - command_buffer - .bind_vertex_buffers(0, (self.vertex_buffer.clone(), transform_uniform.clone()))?; - command_buffer.bind_index_buffer(self.index_buffer.clone())?; - - unsafe { - command_buffer.draw_indexed( - INDICES.len() as u32, - transform_uniform.len() as u32, - 0, - 0, - 0, - )?; - } - - Ok(()) - } -} diff --git a/src/game/mod.rs b/src/game/mod.rs deleted file mode 100644 index 065e8e4..0000000 --- a/src/game/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod assets; -pub mod scenes; diff --git a/src/game/scenes/main_scene.rs b/src/game/scenes/main_scene.rs deleted file mode 100644 index 37fd4ed..0000000 --- a/src/game/scenes/main_scene.rs +++ /dev/null @@ -1,285 +0,0 @@ -use std::error::Error; - -use super::settings_scene::SettingsScene; -use crate::core::app::DEPTH_IMAGE_ID; -use crate::core::app::context::WindowContext; -use crate::core::app::user_event::UserEvent; -use crate::core::render::primitives::camera::Camera3D; -use crate::core::render::primitives::transform::Transform; -use crate::core::render::render_pass_manager::{RenderPassConfig, RenderPassManager}; -use crate::core::render::texture::Texture; -use crate::core::scene::Scene; -use crate::game::assets::square::Square; -use egui_winit_vulkano::egui; -use glam::EulerRot; -use glam::Quat; -use glam::Vec3; -use vulkano::{ - command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, PrimaryCommandBufferAbstract}, - sync::GpuFuture, -}; -use winit::window::CursorGrabMode; - -pub struct MainSceneState { - square: Square, - instances: Vec, - camera: Camera3D, - texture: Texture, - speed: f32, -} - -#[derive(Default)] -pub struct MainScene { - state: Option, -} - -impl Scene for MainScene { - fn loaded(&self) -> bool { - self.state.is_some() - } - - fn load(&mut self, app_context: &mut WindowContext) -> Result<(), Box> { - let depth_image_view = app_context.with_renderer_mut(|renderer| { - renderer.get_additional_image_view(DEPTH_IMAGE_ID).clone() - }); - - let swapchain_image_view = - app_context.with_renderer(|renderer| renderer.swapchain_image_view().clone()); - - let square = Square::new( - &app_context.device, - &app_context.memory_allocator, - swapchain_image_view.format(), - depth_image_view.format(), - )?; - - let num_instances = 100; - let instance_size = 10.0; - let instance_spacing = 10.0; - let num_instances_per_row = (num_instances as f32 / instance_spacing).ceil() as u32; - let instances: Vec = (0..num_instances) - .map(|i| Transform { - position: Vec3::new( - (i % num_instances_per_row) as f32 * (instance_spacing + instance_size), - 0.0, - (i / num_instances_per_row) as f32 * (instance_spacing + instance_size), - ), - rotation: Quat::from_euler( - EulerRot::XYZ, - 0.0, - rand::random_range(0.0..=360.0), - 0.0, - ), - scale: Vec3::new(instance_size, instance_size, instance_size), - }) - .collect(); - - let texture = { - let mut uploads = AutoCommandBufferBuilder::primary( - app_context.command_buffer_allocator.clone(), - app_context.graphics_queue.queue_family_index(), - CommandBufferUsage::OneTimeSubmit, - )?; - - let texture = Texture::from_file( - &app_context.device, - &app_context.memory_allocator, - &mut uploads, - "res/textures/wooden-crate.jpg", - )?; - - let _ = uploads - .build()? - .execute(app_context.graphics_queue.clone())?; - - texture - }; - - let camera = app_context.with_renderer(|renderer| { - Camera3D::new( - renderer.aspect_ratio(), - std::f32::consts::FRAC_PI_2, - 0.01, - 1000.0, - ) - }); - - self.state = Some(MainSceneState { - square, - instances, - camera, - texture, - speed: 50.0, - }); - - Ok(()) - } - - fn update(&mut self, app_context: &mut WindowContext) -> Result<(), Box> { - let state = self.state.as_mut().unwrap(); - app_context.with_input_manager(|input_manager| { - app_context.with_timer(|timer| { - state.camera.update( - input_manager, - timer, - state.speed, - 10.0, - app_context.get_aspect_ratio(), - ); - }); - }); - - if app_context - .with_input_manager(|input_manager| input_manager.get_virtual_input_state("mouse_left")) - > 0.0 - { - let _ = app_context - .event_loop_proxy - .send_event(UserEvent::CursorVisible(app_context.window_id, false)); - let _ = app_context - .event_loop_proxy - .send_event(UserEvent::CursorGrabMode( - app_context.window_id, - CursorGrabMode::Locked, - )); - } - - if app_context.with_input_manager(|input_manager| { - input_manager.get_virtual_input_state("mouse_right") - }) > 0.0 - { - let _ = app_context - .event_loop_proxy - .send_event(UserEvent::CursorVisible(app_context.window_id, true)); - let _ = app_context - .event_loop_proxy - .send_event(UserEvent::CursorGrabMode( - app_context.window_id, - CursorGrabMode::None, - )); - } - - Ok(()) - } - - fn render( - &mut self, - before_future: Box, - app_context: &mut WindowContext, - ) -> Result, Box> { - let state = self.state.as_ref().ok_or("State not loaded")?; - - let mut builder = AutoCommandBufferBuilder::primary( - app_context.command_buffer_allocator.clone(), - app_context.graphics_queue.queue_family_index(), - CommandBufferUsage::OneTimeSubmit, - )?; - - { - let swapchain_image_view = - app_context.with_renderer(|renderer| renderer.swapchain_image_view().clone()); - let depth_image_view = app_context.with_renderer_mut(|renderer| { - renderer.get_additional_image_view(DEPTH_IMAGE_ID).clone() - }); - let config = RenderPassConfig::default(); - RenderPassManager::begin_standard_rendering( - &mut builder, - &config, - swapchain_image_view, - Some(depth_image_view), - app_context.get_window_size(), - )?; - } - - // Create camera uniform using the actual camera - let camera_uniform = state.camera.create_buffer(&app_context.memory_allocator)?; - - let transform_uniform = - Transform::create_buffer(&app_context.memory_allocator, &state.instances)?; - - state - .square - .render( - &mut builder, - &app_context.descriptor_set_allocator, - &camera_uniform, - &transform_uniform, - &state.texture, - ) - .unwrap(); - - RenderPassManager::end_rendering(&mut builder)?; - - let command_buffer = builder.build()?; - - let render_future = - before_future.then_execute(app_context.graphics_queue.clone(), command_buffer)?; - - let swapchain_image_view = - app_context.with_renderer(|renderer| renderer.swapchain_image_view().clone()); - let input_manager_status = - app_context.with_input_manager(|input_manager| format!("{:#?}", input_manager)); - let event_loop_proxy = app_context.event_loop_proxy.clone(); - let delta_time = app_context.get_delta_time(); - let window_id = app_context.window_id; - let window_size = app_context.get_window_size(); - - let render_future = app_context.with_gui_mut(|gui| { - gui.immediate_ui(|gui| { - let ctx = gui.context(); - egui::TopBottomPanel::top("top_panel").show(&ctx, |ui| { - ui.horizontal(|ui| { - ui.heading("Vulkan Test - Moteur 3D"); - ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| { - if ui.button("Paramètres").clicked() { - let _ = event_loop_proxy.send_event(UserEvent::ChangeScene( - window_id, - Box::new(SettingsScene::default()), - )); - } - if ui.button("Quitter").clicked() { - let _ = event_loop_proxy.send_event(UserEvent::Exit(window_id)); - } - }); - }); - }); - - egui::SidePanel::left("side_panel").show(&ctx, |ui| { - ui.heading("Informations"); - - ui.separator(); - - ui.label(format!("Résolution: {:?}", window_size)); - ui.label(format!("Delta Time: {:.2}ms", delta_time * 1000.0)); - - ui.separator(); - - ui.label("Position caméra:"); - let position = state.camera.get_position(); - ui.label(format!(" X: {:.2}", position[0])); - ui.label(format!(" Y: {:.2}", position[1])); - ui.label(format!(" Z: {:.2}", position[2])); - - ui.separator(); - - ui.label("Rotation caméra:"); - let rotation = state.camera.get_rotation(); - ui.label(format!(" Yaw: {:.2}°", rotation.y.to_degrees())); - ui.label(format!(" Pitch: {:.2}°", rotation.x.to_degrees())); - - ui.separator(); - - ui.label(input_manager_status); - }); - }); - - gui.draw_on_image(render_future, swapchain_image_view.clone()) - }); - - Ok(render_future) - } - - fn unload(&mut self) { - self.state = None; - } -} diff --git a/src/game/scenes/mod.rs b/src/game/scenes/mod.rs deleted file mode 100644 index 516fa6f..0000000 --- a/src/game/scenes/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod main_scene; -pub mod settings_scene; diff --git a/src/game/scenes/settings_scene.rs b/src/game/scenes/settings_scene.rs deleted file mode 100644 index 466652a..0000000 --- a/src/game/scenes/settings_scene.rs +++ /dev/null @@ -1,136 +0,0 @@ -use std::error::Error; - -use crate::core::app::DEPTH_IMAGE_ID; -use crate::core::app::context::WindowContext; -use crate::core::app::user_event::UserEvent; -use crate::core::render::render_pass_manager::{RenderPassConfig, RenderPassManager}; -use crate::core::scene::Scene; -use egui_winit_vulkano::egui; -use vulkano::{ - command_buffer::AutoCommandBufferBuilder, command_buffer::CommandBufferUsage, sync::GpuFuture, -}; - -use super::main_scene::MainScene; - -pub struct SettingsSceneState { - current_resolution: [f32; 2], - available_resolutions: Vec<(u32, u32)>, -} - -#[derive(Default)] -pub struct SettingsScene { - state: Option, -} - -impl Scene for SettingsScene { - fn loaded(&self) -> bool { - self.state.is_some() - } - - fn load(&mut self, app_context: &mut WindowContext) -> Result<(), Box> { - let current_resolution = app_context.get_window_size(); - let available_resolutions = app_context.get_available_resolutions(); - - self.state = Some(SettingsSceneState { - current_resolution, - available_resolutions, - }); - - Ok(()) - } - - fn update(&mut self, _app_context: &mut WindowContext) -> Result<(), Box> { - Ok(()) - } - - fn render( - &mut self, - before_future: Box, - app_context: &mut WindowContext, - ) -> Result, Box> { - let state = self.state.as_ref().ok_or("State not found")?; - - let mut builder = AutoCommandBufferBuilder::primary( - app_context.command_buffer_allocator.clone(), - app_context.graphics_queue.queue_family_index(), - CommandBufferUsage::OneTimeSubmit, - )?; - - // Utiliser le RenderPassManager - { - let swapchain_image_view = - app_context.with_renderer(|renderer| renderer.swapchain_image_view().clone()); - let depth_stencil_image_view = app_context.with_renderer_mut(|renderer| { - renderer.get_additional_image_view(DEPTH_IMAGE_ID).clone() - }); - - let config = RenderPassConfig::default(); - RenderPassManager::begin_standard_rendering( - &mut builder, - &config, - swapchain_image_view, - Some(depth_stencil_image_view), - app_context.get_window_size(), - )?; - } - - // Pas de géométrie dans cette scène - juste un écran de paramètres - RenderPassManager::end_rendering(&mut builder)?; - - let command_buffer = builder.build()?; - - let render_future = - before_future.then_execute(app_context.graphics_queue.clone(), command_buffer)?; - - let swapchain_image_view = - app_context.with_renderer(|renderer| renderer.swapchain_image_view().clone()); - - let event_loop_proxy = app_context.event_loop_proxy.clone(); - let window_id = app_context.window_id; - - let render_future = app_context.with_gui_mut(|gui| { - gui.immediate_ui(|gui| { - let ctx = gui.context(); - - egui::CentralPanel::default().show(&ctx, |ui| { - ui.heading("Paramètres"); - - ui.separator(); - - ui.label(format!( - "Résolution actuelle: {:?}", - state.current_resolution - )); - - ui.separator(); - ui.label("Changer la résolution:"); - - for &(width, height) in &state.available_resolutions { - if ui.button(format!("{}x{}", width, height)).clicked() { - let _ = event_loop_proxy.send_event(UserEvent::ChangeResolution( - window_id, - width as f32, - height as f32, - )); - } - } - - ui.separator(); - - if ui.button("Retour au jeu").clicked() { - let _ = event_loop_proxy.send_event(UserEvent::ChangeScene( - window_id, - Box::new(MainScene::default()), - )); - } - }); - }); - - gui.draw_on_image(render_future, swapchain_image_view.clone()) - }); - - Ok(render_future) - } - - fn unload(&mut self) {} -} diff --git a/src/main.rs b/src/main.rs index 998f725..ac0d7c9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,108 +1,14 @@ -use core::input::{AxisDirection, InputManager, VirtualBinding}; -use std::collections::HashMap; +use winit::event_loop::EventLoop; -use vulkano::device::{DeviceExtensions, DeviceFeatures}; -use vulkano_util::context::{VulkanoConfig, VulkanoContext}; -use winit::{ - event::MouseButton, - event_loop::{ControlFlow, EventLoop}, - keyboard::{KeyCode, PhysicalKey}, -}; +mod renderer; +mod vulkan; -mod core; -mod game; +use renderer::app::App; +use vulkan::context::VulkanContext; fn main() { - use tracing_subscriber::layer::SubscriberExt; - use tracing_subscriber::util::SubscriberInitExt; - - tracing_subscriber::registry() - .with( - tracing_subscriber::fmt::layer() - .with_target(true) - .with_thread_ids(true) - .with_file(true) - .with_line_number(true), - ) - .with(tracing_tracy::TracyLayer::default()) - .with( - tracing_subscriber::EnvFilter::try_from_default_env() - .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")), - ) - .init(); - - let input_manager = InputManager::new(HashMap::from([ - ( - "move_forward".to_string(), - vec![ - VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyW), AxisDirection::Normal), - VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyS), AxisDirection::Invert), - ], - ), - ( - "move_right".to_string(), - vec![ - VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyD), AxisDirection::Normal), - VirtualBinding::Keyboard(PhysicalKey::Code(KeyCode::KeyA), AxisDirection::Invert), - ], - ), - ( - "mouse_x".to_string(), - vec![VirtualBinding::MouseX(AxisDirection::Normal)], - ), - ( - "mouse_y".to_string(), - vec![VirtualBinding::MouseY(AxisDirection::Normal)], - ), - ( - "mouse_wheel".to_string(), - vec![VirtualBinding::MouseWheelY(AxisDirection::Normal)], - ), - ( - "mouse_left".to_string(), - vec![VirtualBinding::MouseButton( - MouseButton::Left, - AxisDirection::Normal, - )], - ), - ( - "mouse_right".to_string(), - vec![VirtualBinding::MouseButton( - MouseButton::Right, - AxisDirection::Normal, - )], - ), - ])); - - let device_extensions = DeviceExtensions { - khr_swapchain: true, - ..Default::default() - }; - - let device_features = DeviceFeatures { - dynamic_rendering: true, - ..Default::default() - }; - - let vulkano_config = VulkanoConfig { - print_device_name: true, - device_extensions, - device_features, - ..Default::default() - }; - - let vulkano_context = VulkanoContext::new(vulkano_config); - - let event_loop = EventLoop::with_user_event().build().unwrap(); - event_loop.set_control_flow(ControlFlow::Poll); - let proxy = event_loop.create_proxy(); - - let mut app = core::app::App::new(vulkano_context, input_manager, proxy); - - match event_loop.run_app(&mut app) { - Ok(_) => {} - Err(e) => { - tracing::error!("Error running old app: {e}"); - } - } + let event_loop = EventLoop::new().unwrap(); + let vulkan_context = VulkanContext::new(&event_loop).unwrap(); + let mut app = App::new(vulkan_context); + event_loop.run_app(&mut app).unwrap(); } diff --git a/src/renderer/app.rs b/src/renderer/app.rs new file mode 100644 index 0000000..923d70c --- /dev/null +++ b/src/renderer/app.rs @@ -0,0 +1,262 @@ +use crate::renderer::components::{Entity, Material, Mesh, Transform}; +use crate::vulkan::context::VulkanContext; +use crate::vulkan::pipeline::{Pipeline, triangle::TrianglePipeline}; +use crate::vulkan::renderer::VulkanRenderer; +use crate::vulkan::resources::vertex::{MVPData, Vertex2D}; +use std::error::Error; +use std::sync::Arc; +use vulkano::VulkanError; +use vulkano::buffer::{Buffer, BufferCreateInfo, BufferUsage}; +use vulkano::command_buffer::{ + AutoCommandBufferBuilder, CommandBufferUsage, PrimaryAutoCommandBuffer, + RenderingAttachmentInfo, RenderingInfo, +}; +use vulkano::descriptor_set::{DescriptorSet, WriteDescriptorSet}; +use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter}; +use vulkano::pipeline::{Pipeline as VulkanPipeline, PipelineBindPoint}; +use vulkano::render_pass::{AttachmentLoadOp, AttachmentStoreOp}; +use vulkano::swapchain::Surface; +use winit::application::ApplicationHandler; +use winit::event::WindowEvent; +use winit::event_loop::ActiveEventLoop; +use winit::window::WindowId; + +pub struct App { + pub vulkan_context: VulkanContext, + pub renderer: Option, + pub entities: Vec, +} + +impl App { + pub fn new(vulkan_context: VulkanContext) -> Self { + Self { + vulkan_context, + renderer: None, + entities: Vec::new(), + } + } + + pub fn setup_test_entities(&mut self) -> Result<(), Box> { + // Créer un pipeline de test + let pipeline = TrianglePipeline::new(&self.vulkan_context.device); + + // Créer un buffer de vertex pour un triangle + let vertices = [ + Vertex2D { + position: [-0.5, -0.5], + color: [1.0, 0.0, 0.0], // Rouge + }, + Vertex2D { + position: [0.5, -0.5], + color: [0.0, 1.0, 0.0], // Vert + }, + Vertex2D { + position: [0.0, 0.5], + color: [0.0, 0.0, 1.0], // Bleu + }, + ]; + + let vertex_buffer = + Vertex2D::create_buffer(vertices.to_vec(), &self.vulkan_context.memory_allocator) + .unwrap(); + + // Créer un buffer uniform pour les matrices MVP + let mvp_data = MVPData { + world: [ + [1.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 1.0], + ], + view: [ + [1.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 1.0], + ], + projection: [ + [1.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 1.0], + ], + }; + + let uniform_buffer = Buffer::from_data( + self.vulkan_context.memory_allocator.clone(), + BufferCreateInfo { + usage: BufferUsage::UNIFORM_BUFFER, + ..Default::default() + }, + AllocationCreateInfo { + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, + ..Default::default() + }, + mvp_data, + ) + .unwrap(); + + // Créer un descriptor set de test + let descriptor_set = DescriptorSet::new( + self.vulkan_context.descriptor_set_allocator.clone(), + pipeline + .get_pipeline() + .layout() + .set_layouts() + .get(0) + .unwrap() + .clone(), + [WriteDescriptorSet::buffer(0, uniform_buffer)], + [], + )?; + + let material = Material { + pipeline: pipeline.get_pipeline().clone(), + descriptor_set, + }; + + // Créer quelques entités de test + let mut entities = Vec::new(); + for i in 0..3 { + entities.push(Entity { + mesh: Mesh { + vertex_buffer: vertex_buffer.clone(), + vertex_count: 3, + instance_count: 1, + }, + material: material.clone(), + transform: Transform { + position: [i as f32 * 0.5 - 0.5, 0.0, 0.0], + rotation: [0.0, 0.0, 0.0], + scale: [1.0, 1.0, 1.0], + }, + }); + } + self.entities = entities; + + Ok(()) + } + + pub fn render( + &self, + command_buffer: &mut AutoCommandBufferBuilder, + ) -> Result<(), Box> { + for entity in &self.entities { + command_buffer + .bind_pipeline_graphics(entity.material.pipeline.clone()) + .unwrap() + .bind_descriptor_sets( + PipelineBindPoint::Graphics, + entity.material.pipeline.layout().clone(), + 0, + entity.material.descriptor_set.clone(), + ) + .unwrap() + .bind_vertex_buffers(0, entity.mesh.vertex_buffer.clone()) + .unwrap(); + unsafe { + command_buffer + .draw(entity.mesh.vertex_count, 1, 0, 0) + .unwrap(); + } + } + Ok(()) + } +} + +impl ApplicationHandler for App { + fn resumed(&mut self, event_loop: &ActiveEventLoop) { + let window_attributes = winit::window::Window::default_attributes() + .with_title("Rust ASH Test") + .with_inner_size(winit::dpi::PhysicalSize::new( + f64::from(800), + f64::from(600), + )); + + let window = Arc::new(event_loop.create_window(window_attributes).unwrap()); + + let surface = + Surface::from_window(self.vulkan_context.instance.clone(), window.clone()).unwrap(); + + self.renderer = Some(VulkanRenderer::new( + window, + surface, + self.vulkan_context.device.clone(), + self.vulkan_context.queue.clone(), + )); + + self.setup_test_entities().unwrap(); + } + + fn window_event(&mut self, event_loop: &ActiveEventLoop, _id: WindowId, event: WindowEvent) { + match event { + WindowEvent::CloseRequested => { + log::debug!("The close button was pressed; stopping"); + event_loop.exit(); + } + WindowEvent::Resized(_) => { + let renderer = self.renderer.as_mut().unwrap(); + renderer.recreate_swapchain = true; + } + WindowEvent::RedrawRequested => { + let (image_index, acquire_future) = + match self.renderer.as_mut().unwrap().begin_frame() { + Ok(r) => r, + Err(VulkanError::OutOfDate) => return, + Err(e) => panic!("failed to acquire next image: {e}"), + }; + + let mut builder = AutoCommandBufferBuilder::primary( + self.vulkan_context.command_buffer_allocator.clone(), + self.vulkan_context.queue.queue_family_index(), + CommandBufferUsage::OneTimeSubmit, + ) + .unwrap(); + + { + builder + .begin_rendering(RenderingInfo { + color_attachments: vec![Some(RenderingAttachmentInfo { + load_op: AttachmentLoadOp::Clear, + store_op: AttachmentStoreOp::Store, + clear_value: Some([0.0, 0.0, 0.0, 1.0].into()), + ..RenderingAttachmentInfo::image_view( + self.renderer.as_ref().unwrap().attachment_image_views + [image_index as usize] + .clone(), + ) + })], + ..Default::default() + }) + .unwrap() + .set_viewport( + 0, + [self.renderer.as_ref().unwrap().viewport.clone()] + .into_iter() + .collect(), + ) + .unwrap(); + } + + self.render(&mut builder).unwrap(); + + { + builder.end_rendering().unwrap(); + } + + self.renderer + .as_mut() + .unwrap() + .end_frame(image_index, acquire_future, builder) + .unwrap(); + } + _ => {} + } + } + + fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) { + let renderer = self.renderer.as_mut().unwrap(); + renderer.window.request_redraw(); + } +} diff --git a/src/renderer/components.rs b/src/renderer/components.rs new file mode 100644 index 0000000..968539e --- /dev/null +++ b/src/renderer/components.rs @@ -0,0 +1,71 @@ +use std::sync::Arc; +use vulkano::buffer::Subbuffer; +use vulkano::buffer::allocator::SubbufferAllocator; +use vulkano::command_buffer::allocator::StandardCommandBufferAllocator; +use vulkano::command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer}; +use vulkano::descriptor_set::DescriptorSet; +use vulkano::descriptor_set::allocator::StandardDescriptorSetAllocator; +use vulkano::device::Device; +use vulkano::memory::allocator::StandardMemoryAllocator; +use vulkano::pipeline::GraphicsPipeline; +use vulkano::pipeline::Pipeline; + +use crate::vulkan::resources::vertex::Vertex2D; + +#[derive(Clone)] +pub struct Mesh { + pub vertex_buffer: Subbuffer<[Vertex2D]>, + pub vertex_count: u32, + pub instance_count: u32, +} + +#[derive(Clone)] +pub struct Material { + pub pipeline: Arc, + pub descriptor_set: Arc, +} + +#[derive(Clone)] +pub struct Transform { + pub position: [f32; 3], + pub rotation: [f32; 3], + pub scale: [f32; 3], +} + +#[derive(Clone)] +pub struct RenderResources { + pub device: Arc, + pub memory_allocator: Arc, + pub command_buffer_allocator: Arc, + pub uniform_buffer_allocator: Arc, + pub descriptor_set_allocator: Arc, +} + +pub struct Entity { + pub mesh: Mesh, + pub material: Material, + pub transform: Transform, +} + +pub fn render_system( + _resources: &RenderResources, + builder: &mut AutoCommandBufferBuilder, + entities: &[Entity], +) -> Result<(), Box> { + for entity in entities { + unsafe { + builder + .bind_pipeline_graphics(entity.material.pipeline.clone())? + .bind_descriptor_sets( + vulkano::pipeline::PipelineBindPoint::Graphics, + entity.material.pipeline.layout().clone(), + 0, + entity.material.descriptor_set.clone(), + )? + .bind_vertex_buffers(0, entity.mesh.vertex_buffer.clone())? + .draw(entity.mesh.vertex_count, entity.mesh.instance_count, 0, 0)?; + } + } + + Ok(()) +} diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs new file mode 100644 index 0000000..13545c4 --- /dev/null +++ b/src/renderer/mod.rs @@ -0,0 +1,2 @@ +pub mod app; +pub mod components; diff --git a/src/vulkan/context.rs b/src/vulkan/context.rs new file mode 100644 index 0000000..bd1aeba --- /dev/null +++ b/src/vulkan/context.rs @@ -0,0 +1,135 @@ +use std::sync::Arc; +use vulkano::buffer::BufferUsage; +use vulkano::buffer::allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo}; +use vulkano::command_buffer::allocator::StandardCommandBufferAllocator; +use vulkano::descriptor_set::allocator::StandardDescriptorSetAllocator; +use vulkano::device::physical::PhysicalDeviceType; +use vulkano::device::{ + Device, DeviceCreateInfo, DeviceExtensions, DeviceFeatures, Queue, QueueCreateInfo, QueueFlags, +}; +use vulkano::instance::{Instance, InstanceCreateFlags, InstanceCreateInfo}; +use vulkano::memory::allocator::{MemoryTypeFilter, StandardMemoryAllocator}; +use vulkano::swapchain::Surface; +use vulkano::{Version, VulkanLibrary}; +use winit::event_loop::EventLoop; + +pub struct VulkanContext { + pub instance: Arc, + pub device: Arc, + pub queue: Arc, + pub memory_allocator: Arc, + pub command_buffer_allocator: Arc, + pub uniform_buffer_allocator: Arc, + pub descriptor_set_allocator: Arc, +} + +impl VulkanContext { + pub fn new(event_loop: &EventLoop<()>) -> Result> { + let library = VulkanLibrary::new().unwrap(); + for layer in library.layer_properties().unwrap() { + log::debug!("Available layer: {}", layer.name()); + } + + let required_extensions = Surface::required_extensions(event_loop).unwrap(); + let instance = Instance::new( + library, + InstanceCreateInfo { + flags: InstanceCreateFlags::ENUMERATE_PORTABILITY, + enabled_extensions: required_extensions, + enabled_layers: vec![String::from("VK_LAYER_KHRONOS_validation")], + ..Default::default() + }, + ) + .unwrap(); + + let mut device_extensions = DeviceExtensions { + khr_swapchain: true, + ..DeviceExtensions::empty() + }; + + let (physical_device, queue_family_index) = instance + .enumerate_physical_devices() + .unwrap() + .filter(|p| { + p.api_version() >= Version::V1_3 || p.supported_extensions().khr_dynamic_rendering + }) + .filter(|p| p.supported_extensions().contains(&device_extensions)) + .filter_map(|p| { + p.queue_family_properties() + .iter() + .enumerate() + .position(|(_i, q)| q.queue_flags.intersects(QueueFlags::GRAPHICS)) + .map(|i| (p, i as u32)) + }) + .min_by_key(|(p, _)| match p.properties().device_type { + PhysicalDeviceType::DiscreteGpu => 0, + PhysicalDeviceType::IntegratedGpu => 1, + PhysicalDeviceType::VirtualGpu => 2, + PhysicalDeviceType::Cpu => 3, + PhysicalDeviceType::Other => 4, + _ => 5, + }) + .expect("no suitable physical device found"); + + log::debug!( + "Using device: {} (type: {:?})", + physical_device.properties().device_name, + physical_device.properties().device_type, + ); + + if physical_device.api_version() < Version::V1_3 { + device_extensions.khr_dynamic_rendering = true; + } + + log::debug!("Using device extensions: {:#?}", device_extensions); + + let (device, mut queues) = Device::new( + physical_device, + DeviceCreateInfo { + queue_create_infos: vec![QueueCreateInfo { + queue_family_index, + ..Default::default() + }], + enabled_extensions: device_extensions, + enabled_features: DeviceFeatures { + dynamic_rendering: true, + ..DeviceFeatures::empty() + }, + ..Default::default() + }, + ) + .unwrap(); + + let queue = queues.next().unwrap(); + let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); + let command_buffer_allocator = Arc::new(StandardCommandBufferAllocator::new( + device.clone(), + Default::default(), + )); + + let uniform_buffer_allocator = Arc::new(SubbufferAllocator::new( + memory_allocator.clone(), + SubbufferAllocatorCreateInfo { + buffer_usage: BufferUsage::UNIFORM_BUFFER, + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, + ..Default::default() + }, + )); + + let descriptor_set_allocator = Arc::new(StandardDescriptorSetAllocator::new( + device.clone(), + Default::default(), + )); + + Ok(Self { + instance, + device, + queue, + memory_allocator, + command_buffer_allocator, + uniform_buffer_allocator, + descriptor_set_allocator, + }) + } +} diff --git a/src/vulkan/mod.rs b/src/vulkan/mod.rs new file mode 100644 index 0000000..8a4bdd9 --- /dev/null +++ b/src/vulkan/mod.rs @@ -0,0 +1,4 @@ +pub mod context; +pub mod pipeline; +pub mod renderer; +pub mod resources; diff --git a/src/vulkan/pipeline/mod.rs b/src/vulkan/pipeline/mod.rs new file mode 100644 index 0000000..f9ba6d5 --- /dev/null +++ b/src/vulkan/pipeline/mod.rs @@ -0,0 +1,30 @@ +pub mod triangle; + +use std::sync::Arc; +use vulkano::device::Device; +use vulkano::pipeline::GraphicsPipeline; + +pub trait Pipeline { + fn create_pipeline(device: &Arc) -> Arc; + fn get_pipeline(&self) -> &Arc; +} + +pub struct PipelineManager { + pipelines: std::collections::HashMap>, +} + +impl PipelineManager { + pub fn new() -> Self { + Self { + pipelines: std::collections::HashMap::new(), + } + } + + pub fn register_pipeline(&mut self, name: String, pipeline: Arc) { + self.pipelines.insert(name, pipeline); + } + + pub fn get_pipeline(&self, name: &str) -> Option<&Arc> { + self.pipelines.get(name) + } +} diff --git a/src/vulkan/pipeline/triangle.rs b/src/vulkan/pipeline/triangle.rs new file mode 100644 index 0000000..c625e66 --- /dev/null +++ b/src/vulkan/pipeline/triangle.rs @@ -0,0 +1,127 @@ +use std::collections::BTreeMap; +use std::error::Error; +use std::sync::Arc; +use vulkano::descriptor_set::layout::{ + DescriptorSetLayoutBinding, DescriptorSetLayoutCreateInfo, DescriptorType, +}; +use vulkano::device::Device; +use vulkano::pipeline::graphics::GraphicsPipelineCreateInfo; +use vulkano::pipeline::graphics::color_blend::{ColorBlendAttachmentState, ColorBlendState}; +use vulkano::pipeline::graphics::input_assembly::InputAssemblyState; +use vulkano::pipeline::graphics::multisample::MultisampleState; +use vulkano::pipeline::graphics::rasterization::RasterizationState; +use vulkano::pipeline::graphics::subpass::PipelineRenderingCreateInfo; +use vulkano::pipeline::graphics::vertex_input::{Vertex, VertexDefinition}; +use vulkano::pipeline::graphics::viewport::ViewportState; +use vulkano::pipeline::layout::{PipelineDescriptorSetLayoutCreateInfo, PipelineLayoutCreateFlags}; +use vulkano::pipeline::{ + DynamicState, GraphicsPipeline, PipelineLayout, PipelineShaderStageCreateInfo, +}; +use vulkano::shader::{EntryPoint, ShaderStages}; + +use crate::vulkan::resources::vertex::Vertex2D; + +use super::Pipeline; + +mod shaders { + pub mod vs { + vulkano_shaders::shader! { + ty: "vertex", + path: r"res/shaders/vertex.vert", + } + } + + pub mod fs { + vulkano_shaders::shader! { + ty: "fragment", + path: r"res/shaders/vertex.frag", + } + } +} + +pub struct TrianglePipeline { + pipeline: Arc, +} + +impl super::Pipeline for TrianglePipeline { + fn create_pipeline(device: &Arc) -> Arc { + let (vs, fs) = load_shaders(device).unwrap(); + let vertex_input_state = Vertex2D::per_vertex().definition(&vs).unwrap(); + + let stages = [ + PipelineShaderStageCreateInfo::new(vs), + PipelineShaderStageCreateInfo::new(fs), + ]; + + let mut bindings = BTreeMap::::new(); + let mut descriptor_set_layout_binding = + DescriptorSetLayoutBinding::descriptor_type(DescriptorType::UniformBuffer); + descriptor_set_layout_binding.stages = ShaderStages::VERTEX; + bindings.insert(0, descriptor_set_layout_binding); + + let descriptor_set_layout = DescriptorSetLayoutCreateInfo { + bindings, + ..Default::default() + }; + + let create_info = PipelineDescriptorSetLayoutCreateInfo { + set_layouts: vec![descriptor_set_layout], + flags: PipelineLayoutCreateFlags::default(), + push_constant_ranges: vec![], + } + .into_pipeline_layout_create_info(device.clone()) + .unwrap(); + + let layout = PipelineLayout::new(device.clone(), create_info).unwrap(); + + let subpass = PipelineRenderingCreateInfo { + color_attachment_formats: vec![Some(vulkano::format::Format::B8G8R8A8_UNORM)], + ..Default::default() + }; + + GraphicsPipeline::new( + device.clone(), + None, + GraphicsPipelineCreateInfo { + stages: stages.into_iter().collect(), + vertex_input_state: Some(vertex_input_state), + input_assembly_state: Some(InputAssemblyState::default()), + viewport_state: Some(ViewportState::default()), + rasterization_state: Some(RasterizationState::default()), + multisample_state: Some(MultisampleState::default()), + color_blend_state: Some(ColorBlendState::with_attachment_states( + subpass.color_attachment_formats.len() as u32, + ColorBlendAttachmentState::default(), + )), + dynamic_state: [DynamicState::Viewport].into_iter().collect(), + subpass: Some(subpass.into()), + ..GraphicsPipelineCreateInfo::layout(layout) + }, + ) + .unwrap() + } + + fn get_pipeline(&self) -> &Arc { + &self.pipeline + } +} + +impl TrianglePipeline { + pub fn new(device: &Arc) -> Self { + Self { + pipeline: Self::create_pipeline(device), + } + } +} + +fn load_shaders(device: &Arc) -> Result<(EntryPoint, EntryPoint), Box> { + let vs = shaders::vs::load(device.clone())? + .entry_point("main") + .ok_or("Failed find main entry point of vertex shader".to_string())?; + + let fs = shaders::fs::load(device.clone())? + .entry_point("main") + .ok_or("Failed find main entry point of fragment shader".to_string())?; + + Ok((vs, fs)) +} diff --git a/src/vulkan/renderer.rs b/src/vulkan/renderer.rs new file mode 100644 index 0000000..079276b --- /dev/null +++ b/src/vulkan/renderer.rs @@ -0,0 +1,167 @@ +use std::sync::Arc; +use vulkano::command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer}; +use vulkano::device::Queue; +use vulkano::image::view::ImageView; +use vulkano::pipeline::graphics::viewport::Viewport; +use vulkano::swapchain::{Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo}; +use vulkano::sync::{self, GpuFuture}; +use vulkano::{Validated, VulkanError}; +use winit::window::Window; + +pub struct VulkanRenderer { + pub window: Arc, + pub surface: Arc, + pub swapchain: Arc, + pub queue: Arc, + pub attachment_image_views: Vec>, + pub previous_frame_end: Option>, + pub recreate_swapchain: bool, + pub viewport: Viewport, +} + +impl VulkanRenderer { + pub fn new( + window: Arc, + surface: Arc, + device: Arc, + queue: Arc, + ) -> Self { + let window_size = window.inner_size(); + let surface_formats = device + .physical_device() + .surface_formats(&surface, Default::default()) + .unwrap(); + let surface_format = surface_formats[0]; + + let (swapchain, images) = Swapchain::new( + device.clone(), + surface.clone(), + SwapchainCreateInfo { + image_extent: window_size.into(), + image_usage: vulkano::image::ImageUsage::COLOR_ATTACHMENT, + image_format: surface_format.0, + ..Default::default() + }, + ) + .unwrap(); + + let attachment_image_views = images + .into_iter() + .map(|image| ImageView::new_default(image).unwrap()) + .collect(); + + let viewport = Viewport { + offset: [0.0, 0.0], + extent: window_size.into(), + depth_range: 0.0..=1.0, + }; + + Self { + window, + surface, + swapchain, + queue, + attachment_image_views, + previous_frame_end: Some(sync::now(device).boxed()), + recreate_swapchain: false, + viewport, + } + } + + pub fn begin_frame(&mut self) -> Result<(u32, Box), VulkanError> { + self.previous_frame_end.as_mut().unwrap().cleanup_finished(); + + if self.recreate_swapchain { + self.recreate_swapchain(); + self.recreate_swapchain = false; + } + + let (image_index, suboptimal, acquire_future) = + match vulkano::swapchain::acquire_next_image(self.swapchain.clone(), None) + .map_err(Validated::unwrap) + { + Ok(r) => r, + Err(VulkanError::OutOfDate) => { + self.recreate_swapchain = true; + return Err(VulkanError::OutOfDate); + } + Err(e) => panic!("failed to acquire next image: {e}"), + }; + + if suboptimal { + self.recreate_swapchain = true; + } + + Ok((image_index, acquire_future.boxed())) + } + + pub fn end_frame( + &mut self, + image_index: u32, + acquire_future: Box, + command_buffer: AutoCommandBufferBuilder, + ) -> Result<(), VulkanError> { + let command_buffer = command_buffer.build().unwrap(); + let future = self + .previous_frame_end + .take() + .unwrap() + .join(acquire_future) + .then_execute(self.queue.clone(), command_buffer) + .unwrap() + .then_swapchain_present( + self.queue.clone(), + SwapchainPresentInfo::swapchain_image_index(self.swapchain.clone(), image_index), + ) + .then_signal_fence_and_flush(); + + match future.map_err(Validated::unwrap) { + Ok(future) => { + self.previous_frame_end = Some(future.boxed()); + Ok(()) + } + Err(VulkanError::OutOfDate) => { + self.recreate_swapchain = true; + self.previous_frame_end = Some(sync::now(self.queue.device().clone()).boxed()); + Ok(()) + } + Err(e) => { + println!("failed to flush future: {e}"); + self.previous_frame_end = Some(sync::now(self.queue.device().clone()).boxed()); + Ok(()) + } + } + } + + fn recreate_swapchain(&mut self) { + let image_extent: [u32; 2] = self.window.inner_size().into(); + if image_extent.contains(&0) { + return; + } + + let surface_formats = self + .queue + .device() + .physical_device() + .surface_formats(&self.surface, Default::default()) + .unwrap(); + let surface_format = surface_formats[0]; + + let (new_swapchain, new_images) = self + .swapchain + .recreate(SwapchainCreateInfo { + image_extent, + image_usage: vulkano::image::ImageUsage::COLOR_ATTACHMENT, + image_format: surface_format.0, + ..self.swapchain.create_info() + }) + .expect("failed to recreate swapchain"); + + self.swapchain = new_swapchain; + self.attachment_image_views = new_images + .into_iter() + .map(|image| ImageView::new_default(image).unwrap()) + .collect(); + self.viewport.extent = [image_extent[0] as f32, image_extent[1] as f32]; + } +} diff --git a/src/vulkan/resources/buffer.rs b/src/vulkan/resources/buffer.rs new file mode 100644 index 0000000..318d96e --- /dev/null +++ b/src/vulkan/resources/buffer.rs @@ -0,0 +1,65 @@ +use std::sync::Arc; +use vulkano::buffer::BufferContents; +use vulkano::buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer}; +use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}; + +pub struct BufferManager { + memory_allocator: Arc, +} + +impl BufferManager { + pub fn new(memory_allocator: Arc) -> Self { + Self { memory_allocator } + } + + pub fn create_vertex_buffer(&self, data: &[T]) -> Subbuffer<[T]> { + Buffer::from_iter( + self.memory_allocator.clone(), + BufferCreateInfo { + usage: BufferUsage::VERTEX_BUFFER, + ..Default::default() + }, + AllocationCreateInfo { + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, + ..Default::default() + }, + data.iter().cloned(), + ) + .unwrap() + } + + pub fn create_index_buffer(&self, data: &[u32]) -> Subbuffer<[u32]> { + Buffer::from_iter( + self.memory_allocator.clone(), + BufferCreateInfo { + usage: BufferUsage::INDEX_BUFFER, + ..Default::default() + }, + AllocationCreateInfo { + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, + ..Default::default() + }, + data.iter().cloned(), + ) + .unwrap() + } + + pub fn create_uniform_buffer(&self, data: &T) -> Subbuffer { + Buffer::from_data( + self.memory_allocator.clone(), + BufferCreateInfo { + usage: BufferUsage::UNIFORM_BUFFER, + ..Default::default() + }, + AllocationCreateInfo { + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, + ..Default::default() + }, + *data, + ) + .unwrap() + } +} diff --git a/src/vulkan/resources/descriptor.rs b/src/vulkan/resources/descriptor.rs new file mode 100644 index 0000000..6b7af8a --- /dev/null +++ b/src/vulkan/resources/descriptor.rs @@ -0,0 +1,47 @@ +use std::sync::Arc; +use vulkano::descriptor_set::DescriptorSet; +use vulkano::descriptor_set::WriteDescriptorSet; +use vulkano::descriptor_set::allocator::StandardDescriptorSetAllocator; +use vulkano::descriptor_set::layout::{ + DescriptorSetLayout, DescriptorSetLayoutBinding, DescriptorSetLayoutCreateInfo, DescriptorType, +}; +use vulkano::device::Device; +use vulkano::shader::ShaderStages; + +pub struct DescriptorManager { + device: Arc, + allocator: Arc, +} + +impl DescriptorManager { + pub fn new(device: Arc, allocator: Arc) -> Self { + Self { device, allocator } + } + + pub fn create_descriptor_set_layout( + &self, + bindings: &[(u32, DescriptorType, u32)], + ) -> Arc { + let mut bindings_map = std::collections::BTreeMap::new(); + for (binding_index, ty, _count) in bindings { + let mut binding = DescriptorSetLayoutBinding::descriptor_type(*ty); + binding.stages = ShaderStages::all_graphics(); + bindings_map.insert(*binding_index, binding); + } + + let create_info = DescriptorSetLayoutCreateInfo { + bindings: bindings_map, + ..Default::default() + }; + + DescriptorSetLayout::new(self.device.clone(), create_info).unwrap() + } + + pub fn create_descriptor_set( + &self, + layout: &Arc, + writes: Vec, + ) -> Arc { + DescriptorSet::new(self.allocator.clone(), layout.clone(), writes, []).unwrap() + } +} diff --git a/src/vulkan/resources/mod.rs b/src/vulkan/resources/mod.rs new file mode 100644 index 0000000..0c2b51c --- /dev/null +++ b/src/vulkan/resources/mod.rs @@ -0,0 +1,3 @@ +pub mod buffer; +pub mod descriptor; +pub mod vertex; diff --git a/src/vulkan/resources/vertex.rs b/src/vulkan/resources/vertex.rs new file mode 100644 index 0000000..cc25b1b --- /dev/null +++ b/src/vulkan/resources/vertex.rs @@ -0,0 +1,46 @@ +use std::sync::Arc; +use vulkano::Validated; +use vulkano::buffer::{ + AllocateBufferError, Buffer, BufferContents, BufferCreateInfo, BufferUsage, Subbuffer, +}; +use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator}; +use vulkano::pipeline::graphics::vertex_input::Vertex; + +#[derive(BufferContents, Vertex, Clone)] +#[repr(C)] +pub struct Vertex2D { + #[format(R32G32_SFLOAT)] + pub position: [f32; 2], + + #[format(R32G32B32_SFLOAT)] + pub color: [f32; 3], +} + +#[derive(BufferContents, Clone)] +#[repr(C)] +pub struct MVPData { + pub world: [[f32; 4]; 4], + pub view: [[f32; 4]; 4], + pub projection: [[f32; 4]; 4], +} + +impl Vertex2D { + pub fn create_buffer( + vertices: Vec, + memory_allocator: &Arc, + ) -> Result, Validated> { + Buffer::from_iter( + memory_allocator.clone(), + BufferCreateInfo { + usage: BufferUsage::VERTEX_BUFFER, + ..Default::default() + }, + AllocationCreateInfo { + memory_type_filter: MemoryTypeFilter::PREFER_DEVICE + | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, + ..Default::default() + }, + vertices.into_iter(), + ) + } +}