From e35f5130aea5542185a9e877c4210583a71089a2 Mon Sep 17 00:00:00 2001 From: deepCurse Date: Fri, 31 Jan 2025 16:46:42 -0400 Subject: [PATCH] finished implementing textures and texture sampling fixed some issues with build.rs and made it a bit more generic --- Cargo.lock | 1249 ++++++++++++++++- Cargo.toml | 17 +- build.rs | 138 +- shaders/f_default.glsl | 9 - shaders/glsl_default.frag | 24 + shaders/{v_default.glsl => glsl_default.vert} | 7 +- src/graphics_engines/opengl/mod.rs | 446 ++++++ src/graphics_engines/vulkan/mod.rs | 645 +++++---- src/linux.rs | 132 +- src/main.rs | 26 +- src/vita/mod.rs | 2 +- src/windows.rs | 134 +- 12 files changed, 2328 insertions(+), 501 deletions(-) delete mode 100644 shaders/f_default.glsl create mode 100644 shaders/glsl_default.frag rename shaders/{v_default.glsl => glsl_default.vert} (63%) diff --git a/Cargo.lock b/Cargo.lock index 784fd19..57d6931 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,12 +40,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom", + "getrandom 0.2.15", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.35", ] +[[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.5.2" @@ -60,9 +66,30 @@ dependencies = [ "jni-sys", "libc", "log", - "ndk", + "ndk 0.8.0", "ndk-context", - "ndk-sys", + "ndk-sys 0.5.0+25.2.9519653", + "num_enum", + "thiserror 1.0.69", +] + +[[package]] +name = "android-activity" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" +dependencies = [ + "android-properties", + "bitflags 2.8.0", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk 0.9.0", + "ndk-context", + "ndk-sys 0.6.0+11769913", "num_enum", "thiserror 1.0.69", ] @@ -97,6 +124,23 @@ dependencies = [ "num-traits", ] +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "arrayref" version = "0.3.9" @@ -136,6 +180,29 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e335041290c43101ca215eed6f43ec437eb5a42125573f600fc3fa42b9bddd62" +dependencies = [ + "arrayvec", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -166,6 +233,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + [[package]] name = "bitflags" version = "1.3.2" @@ -181,6 +254,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitstream-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" + [[package]] name = "block" version = "0.1.6" @@ -203,9 +282,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" dependencies = [ "block-sys", - "objc2", + "objc2 0.4.1", ] +[[package]] +name = "block2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +dependencies = [ + "objc2 0.5.2", +] + +[[package]] +name = "built" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c360505aed52b7ec96a3636c3f039d99103c37d1d9b4f7a8c743d3ea9ffcd03b" + [[package]] name = "bumpalo" version = "3.16.0" @@ -238,6 +332,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.9.0" @@ -258,13 +358,39 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "calloop" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" +dependencies = [ + "bitflags 2.8.0", + "log", + "polling", + "rustix", + "slab", + "thiserror 1.0.69", +] + [[package]] name = "calloop-wayland-source" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" dependencies = [ - "calloop", + "calloop 0.12.4", + "rustix", + "wayland-backend", + "wayland-client", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" +dependencies = [ + "calloop 0.13.0", "rustix", "wayland-backend", "wayland-client", @@ -287,6 +413,16 @@ 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" @@ -305,6 +441,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "cgl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +dependencies = [ + "libc", +] + [[package]] name = "cgmath" version = "0.18.0" @@ -364,6 +509,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "combine" version = "4.6.7" @@ -442,12 +593,37 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + [[package]] name = "ctrlc" version = "3.4.5" @@ -494,6 +670,57 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" +[[package]] +name = "dpi" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" + +[[package]] +name = "drm" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98888c4bbd601524c11a7ed63f814b8825f420514f78e96f752c437ae9cbb5d1" +dependencies = [ + "bitflags 2.8.0", + "bytemuck", + "drm-ffi", + "drm-fourcc", + "rustix", +] + +[[package]] +name = "drm-ffi" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97c98727e48b7ccb4f4aea8cfe881e5b07f702d17b7875991881b41af7278d53" +dependencies = [ + "drm-sys", + "rustix", +] + +[[package]] +name = "drm-fourcc" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aafbcdb8afc29c1a7ee5fbe53b5d62f4565b35a042a662ca9fecd0b54dae6f4" + +[[package]] +name = "drm-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd39dde40b6e196c2e8763f23d119ddb1a8714534bf7d77fa97a65b0feda3986" +dependencies = [ + "libc", + "linux-raw-sys 0.6.5", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + [[package]] name = "equivalent" version = "1.0.1" @@ -510,6 +737,21 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "exr" +version = "1.73.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83197f59927b46c04a183a619b7c29df34e63e63c7869320862268c0ef687e0" +dependencies = [ + "bit_field", + "half", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + [[package]] name = "fdeflate" version = "0.3.7" @@ -580,7 +822,29 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.13.3+wasi-0.2.2", + "windows-targets 0.52.6", +] + +[[package]] +name = "gif" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" +dependencies = [ + "color_quant", + "weezl", ] [[package]] @@ -612,6 +876,63 @@ dependencies = [ "web-sys", ] +[[package]] +name = "glutin" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03642b8b0cce622392deb0ee3e88511f75df2daac806102597905c3ea1974848" +dependencies = [ + "bitflags 2.8.0", + "cfg_aliases 0.2.1", + "cgl", + "core-foundation", + "dispatch", + "glutin_egl_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "libloading", + "objc2 0.5.2", + "objc2-app-kit", + "objc2-foundation", + "once_cell", + "raw-window-handle", + "wayland-sys", + "windows-sys 0.52.0", + "x11-dl", +] + +[[package]] +name = "glutin-winit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f" +dependencies = [ + "cfg_aliases 0.2.1", + "glutin", + "raw-window-handle", + "winit 0.30.8", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c4680ba6195f424febdc3ba46e7a42a0e58743f2edb115297b86d7f8ecc02d2" +dependencies = [ + "gl_generator", + "windows-sys 0.52.0", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7bb2938045a88b612499fbcba375a77198e01306f52272e692f8c1f3751185" +dependencies = [ + "gl_generator", + "x11-dl", +] + [[package]] name = "glutin_wgl_sys" version = "0.6.1" @@ -672,6 +993,16 @@ dependencies = [ "bitflags 2.8.0", ] +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.15.2" @@ -711,11 +1042,50 @@ version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" dependencies = [ - "block2", + "block2 0.3.0", "dispatch", - "objc2", + "objc2 0.4.1", ] +[[package]] +name = "image" +version = "0.25.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" +dependencies = [ + "bytemuck", + "byteorder-lite", + "color_quant", + "exr", + "gif", + "image-webp", + "num-traits", + "png", + "qoi", + "ravif", + "rayon", + "rgb", + "tiff", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.2.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.7.0" @@ -726,6 +1096,26 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "jni" version = "0.21.1" @@ -757,6 +1147,12 @@ dependencies = [ "libc", ] +[[package]] +name = "jpeg-decoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" + [[package]] name = "js-sys" version = "0.3.77" @@ -790,12 +1186,28 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + [[package]] name = "libc" version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +[[package]] +name = "libfuzzer-sys" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf78f52d400cf2d84a3a973a78a592b4adc535739e0a5597a0da6f0c357adc75" +dependencies = [ + "arbitrary", + "cc", +] + [[package]] name = "libloading" version = "0.8.6" @@ -823,6 +1235,12 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +[[package]] +name = "linux-raw-sys" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a385b1be4e5c3e362ad2ffa73c392e53f031eaa5b7d648e64cd87f27f6063d7" + [[package]] name = "litrs" version = "0.4.1" @@ -845,6 +1263,15 @@ version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" +[[package]] +name = "loop9" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" +dependencies = [ + "imgref", +] + [[package]] name = "malloc_buf" version = "0.0.6" @@ -854,6 +1281,16 @@ dependencies = [ "libc", ] +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + [[package]] name = "memchr" version = "2.7.4" @@ -907,14 +1344,19 @@ dependencies = [ "cgmath", "concat-idents", "ctrlc", + "drm", + "gl_generator", + "glutin", + "glutin-winit", + "image", "jobserver", "libc", "log", "metal 0.31.0", "num_cpus", "objc", - "png", - "rand", + "rand 0.9.0", + "raw-window-handle", "shaderc", "thiserror 2.0.11", "tobj", @@ -924,9 +1366,16 @@ dependencies = [ "vitasdk-sys", "vulkanalia", "wgpu", - "winit", + "winit 0.29.15", + "winit 0.30.8", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.3" @@ -944,7 +1393,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] @@ -979,7 +1428,22 @@ dependencies = [ "bitflags 2.8.0", "jni-sys", "log", - "ndk-sys", + "ndk-sys 0.5.0+25.2.9519653", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.8.0", + "jni-sys", + "log", + "ndk-sys 0.6.0+11769913", "num_enum", "raw-window-handle", "thiserror 1.0.69", @@ -1000,6 +1464,21 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +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 = "nix" version = "0.29.0" @@ -1012,6 +1491,22 @@ dependencies = [ "libc", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "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" @@ -1022,6 +1517,47 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-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" @@ -1085,7 +1621,93 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" dependencies = [ "objc-sys", - "objc2-encode", + "objc2-encode 3.0.0", +] + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode 4.1.0", +] + +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.8.0", + "block2 0.5.1", + "libc", + "objc2 0.5.2", + "objc2-core-data", + "objc2-core-image", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.8.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" +dependencies = [ + "bitflags 2.8.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-image" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-core-location" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-contacts", + "objc2-foundation", ] [[package]] @@ -1094,6 +1716,117 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.8.0", + "block2 0.5.1", + "dispatch", + "libc", + "objc2 0.5.2", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-app-kit", + "objc2-foundation", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.8.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.8.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", + "objc2-metal", +] + +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2 0.5.2", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.8.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.8.0", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-core-location", + "objc2-foundation", +] + [[package]] name = "objc_exception" version = "0.1.2" @@ -1186,6 +1919,26 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-project" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.16" @@ -1232,7 +1985,7 @@ version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" dependencies = [ - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -1264,6 +2017,34 @@ name = "profiling" version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quick-xml" @@ -1290,8 +2071,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.0", + "zerocopy 0.8.14", ] [[package]] @@ -1301,7 +2093,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "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.0", ] [[package]] @@ -1310,7 +2112,17 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "rand_core" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff" +dependencies = [ + "getrandom 0.3.1", + "zerocopy 0.8.14", ] [[package]] @@ -1319,12 +2131,82 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde" +[[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.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2413fd96bd0ea5cdeeb37eaf446a22e6ed7b981d792828721e74ded1980a45c6" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error", + "rav1e", + "rayon", + "rgb", +] + [[package]] name = "raw-window-handle" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -1334,6 +2216,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_syscall" version = "0.5.8" @@ -1349,6 +2240,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" +[[package]] +name = "rgb" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" + [[package]] name = "roxmltree" version = "0.14.1" @@ -1379,7 +2276,7 @@ dependencies = [ "bitflags 2.8.0", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.15", "windows-sys 0.59.0", ] @@ -1419,7 +2316,7 @@ dependencies = [ "ab_glyph", "log", "memmap2", - "smithay-client-toolkit", + "smithay-client-toolkit 0.18.1", "tiny-skia", ] @@ -1443,6 +2340,15 @@ dependencies = [ "syn", ] +[[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" @@ -1494,6 +2400,15 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + [[package]] name = "slab" version = "0.4.9" @@ -1525,8 +2440,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" dependencies = [ "bitflags 2.8.0", - "calloop", - "calloop-wayland-source", + "calloop 0.12.4", + "calloop-wayland-source 0.2.0", "cursor-icon", "libc", "log", @@ -1537,8 +2452,33 @@ dependencies = [ "wayland-client", "wayland-csd-frame", "wayland-cursor", - "wayland-protocols", - "wayland-protocols-wlr", + "wayland-protocols 0.31.2", + "wayland-protocols-wlr 0.2.0", + "wayland-scanner", + "xkeysym", +] + +[[package]] +name = "smithay-client-toolkit" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" +dependencies = [ + "bitflags 2.8.0", + "calloop 0.13.0", + "calloop-wayland-source 0.3.0", + "cursor-icon", + "libc", + "log", + "memmap2", + "rustix", + "thiserror 1.0.69", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols 0.32.5", + "wayland-protocols-wlr 0.3.5", "wayland-scanner", "xkeysym", ] @@ -1616,6 +2556,25 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + [[package]] name = "termcolor" version = "1.4.1" @@ -1675,6 +2634,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tiff" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "tiny-skia" version = "0.11.4" @@ -1740,11 +2710,26 @@ dependencies = [ "syn", ] +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + [[package]] name = "toml_datetime" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -1753,6 +2738,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", + "serde", + "serde_spanned", "toml_datetime", "winnow", ] @@ -1844,12 +2831,29 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[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" + [[package]] name = "version_check" version = "0.9.5" @@ -1901,6 +2905,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.13.3+wasi-0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" version = "0.2.100" @@ -2032,6 +3045,18 @@ dependencies = [ "wayland-scanner", ] +[[package]] +name = "wayland-protocols" +version = "0.32.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd0ade57c4e6e9a8952741325c30bf82f4246885dca8bf561898b86d0c1f58e" +dependencies = [ + "bitflags 2.8.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + [[package]] name = "wayland-protocols-plasma" version = "0.2.0" @@ -2041,7 +3066,20 @@ dependencies = [ "bitflags 2.8.0", "wayland-backend", "wayland-client", - "wayland-protocols", + "wayland-protocols 0.31.2", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b31cab548ee68c7eb155517f2212049dc151f7cd7910c2b66abfd31c3ee12bd" +dependencies = [ + "bitflags 2.8.0", + "wayland-backend", + "wayland-client", + "wayland-protocols 0.32.5", "wayland-scanner", ] @@ -2054,7 +3092,20 @@ dependencies = [ "bitflags 2.8.0", "wayland-backend", "wayland-client", - "wayland-protocols", + "wayland-protocols 0.31.2", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "782e12f6cd923c3c316130d56205ebab53f55d6666b7faddfad36cecaeeb4022" +dependencies = [ + "bitflags 2.8.0", + "wayland-backend", + "wayland-client", + "wayland-protocols 0.32.5", "wayland-scanner", ] @@ -2101,6 +3152,22 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "weezl" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" + [[package]] name = "wgpu" version = "24.0.0" @@ -2179,7 +3246,7 @@ dependencies = [ "log", "metal 0.31.0", "naga", - "ndk-sys", + "ndk-sys 0.5.0+25.2.9519653", "objc", "once_cell", "ordered-float", @@ -2526,11 +3593,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d59ad965a635657faf09c8f062badd885748428933dad8e8bdd64064d92e5ca" dependencies = [ "ahash", - "android-activity", + "android-activity 0.5.2", "atomic-waker", "bitflags 2.8.0", "bytemuck", - "calloop", + "calloop 0.12.4", "cfg_aliases 0.1.1", "core-foundation", "core-graphics", @@ -2540,9 +3607,9 @@ dependencies = [ "libc", "log", "memmap2", - "ndk", - "ndk-sys", - "objc2", + "ndk 0.8.0", + "ndk-sys 0.5.0+25.2.9519653", + "objc2 0.4.1", "once_cell", "orbclient", "percent-encoding", @@ -2550,23 +3617,74 @@ dependencies = [ "redox_syscall 0.3.5", "rustix", "sctk-adwaita", - "smithay-client-toolkit", + "smithay-client-toolkit 0.18.1", "smol_str", "unicode-segmentation", "wasm-bindgen", "wasm-bindgen-futures", "wayland-backend", "wayland-client", - "wayland-protocols", - "wayland-protocols-plasma", + "wayland-protocols 0.31.2", + "wayland-protocols-plasma 0.2.0", "web-sys", - "web-time", + "web-time 0.2.4", "windows-sys 0.48.0", "x11-dl", "x11rb", "xkbcommon-dl", ] +[[package]] +name = "winit" +version = "0.30.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5d74280aabb958072864bff6cfbcf9025cf8bfacdde5e32b5e12920ef703b0f" +dependencies = [ + "ahash", + "android-activity 0.6.0", + "atomic-waker", + "bitflags 2.8.0", + "block2 0.5.1", + "bytemuck", + "calloop 0.13.0", + "cfg_aliases 0.2.1", + "concurrent-queue", + "core-foundation", + "core-graphics", + "cursor-icon", + "dpi", + "js-sys", + "libc", + "memmap2", + "ndk 0.9.0", + "objc2 0.5.2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "orbclient", + "percent-encoding", + "pin-project", + "raw-window-handle", + "redox_syscall 0.4.1", + "rustix", + "smithay-client-toolkit 0.19.2", + "smol_str", + "tracing", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", + "wayland-client", + "wayland-protocols 0.32.5", + "wayland-protocols-plasma 0.3.5", + "web-sys", + "web-time 1.1.0", + "windows-sys 0.52.0", + "x11-dl", + "x11rb", + "xkbcommon-dl", +] + [[package]] name = "winnow" version = "0.6.24" @@ -2576,6 +3694,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags 2.8.0", +] + [[package]] name = "x11-dl" version = "2.21.0" @@ -2652,7 +3779,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "byteorder", - "zerocopy-derive", + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a367f292d93d4eab890745e75a778da40909cab4d6ff8173693812f79c4a2468" +dependencies = [ + "zerocopy-derive 0.8.14", ] [[package]] @@ -2665,3 +3801,38 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zerocopy-derive" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1" +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", +] diff --git a/Cargo.toml b/Cargo.toml index 063a712..6f98018 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,6 +43,7 @@ members = [] shaderc = "0.8.3" num_cpus = "1.16.0" jobserver = "0.1.32" +gl_generator = "0.14" [dependencies] tracing = { version = "0.1.41", features = [ @@ -56,16 +57,26 @@ anyhow = "1.0.95" thiserror = "2.0.11" cgmath = "0.18.0" -png = "0.17.16" +image = "0.25.5" +# png = "0.17.16" tobj = { version = "4.0.2", features = ["log"] } [target.'cfg(any(target_os = "windows",target_os = "linux",target_os = "macos"))'.dependencies] +# vulkan vulkanalia = { version = "0.26.0", features = [ "libloading", "provisional", "window", ] } -winit = "0.29" # dont update, many many breaking changes with no guides +old_winit = { package = "winit", version = "0.29" } # dont update, many many breaking changes with no guides +# end vulkan +# opengl +glutin = "0.32.2" +glutin-winit = "0.5.0" +raw-window-handle = "0.6" +winit = { version = "0.30.0", default-features = false, features = ["rwh_06"] } +drm = { version = "0.12", optional = true } +# end opengl ctrlc = "3.4.5" tokio = { version = "1.43.0", features = ["full"] } @@ -76,7 +87,7 @@ wgpu = "24.0.0" vitasdk-sys = { version = "0.3.3", features = ["all-stubs"] } concat-idents = "1.1.5" libc = "0.2.153" -rand = "0.8.5" +rand = "0.9.0" tokio = { version = "1.36.0", features = [ "fs", "macros", diff --git a/build.rs b/build.rs index 5ba0e9e..f0704f1 100644 --- a/build.rs +++ b/build.rs @@ -1,26 +1,46 @@ -// Requires crates: shaderc, num_cpus, jobserver +// Requires crates: shaderc, num_cpus, jobserver, gl_generator // This file is licensed to anyone who obtains a copy by lever1209 under the CC BY 4.0 license available here: https://creativecommons.org/licenses/by/4.0/ const SHADER_SRC_ROOT:&'static str = "shaders/"; -const SUPPORTED_SHADER_FORMAT_EXTENSIONS_GLSL:[&'static str; 1] = ["glsl"]; -const SUPPORTED_SHADER_FORMAT_EXTENSIONS_HLSL:[&'static str; 2] = ["cg", "hlsl"]; -const COMPILED_SHADER_EXTENSION:&'static str = ".spv"; +const FRAGMENT_EXTENSIONS:[&'static str; 1] = ["frag"]; +const VERTEX_EXTENSIONS:[&'static str; 1] = ["vert"]; +const GLSL_PREFIXES:[&'static str; 1] = ["glsl"]; +const HLSL_PREFIXES:[&'static str; 2] = ["cg", "hlsl"]; +static MAX_THREAD_COUNT:std::sync::LazyLock = std::sync::LazyLock::new(|| num_cpus::get()); fn main() -> Result<(), Box> { println!("cargo:rerun-if-changed=build.rs"); + setup_gl_bindings()?; + compile_shaders()?; Ok(()) } +fn setup_gl_bindings() -> Result<(), Box> { + let path = std::path::PathBuf::from(&std::env::var("OUT_DIR")?).join("gl_bindings.rs"); + + // Skip generation if the file is already there + if !path.exists() { + let mut file = std::fs::File::create(path)?; + gl_generator::Registry::new(gl_generator::Api::Gles2, (3, 0), gl_generator::Profile::Core, gl_generator::Fallbacks::All, []) + .write_bindings(gl_generator::StructGenerator, &mut file)?; + } + + Ok(()) +} + fn compile_shaders() -> Result<(), Box> { println!("cargo:rerun-if-changed={SHADER_SRC_ROOT}"); let client = unsafe { jobserver::Client::from_env() }.unwrap_or({ - println!("cargo:warning=Could not connect to the gnu jobserver. Assuming max supported threads."); - jobserver::Client::new(num_cpus::get())? + println!( + "cargo:warning=Could not connect to the gnu jobserver. Using defined max thread count: {}.", + *MAX_THREAD_COUNT + ); + jobserver::Client::new(*MAX_THREAD_COUNT)? }); let out_dir = std::env::var("OUT_DIR").map_err(|err| format!("Could not read environment variable OUT_DIR: `{err}`"))?; @@ -31,7 +51,7 @@ fn compile_shaders() -> Result<(), Box> { let mut shader_source_files = vec![]; if let Err(err) = walk_dir(SHADER_SRC_ROOT.into(), &mut shader_source_files) { - println!("cargo:warning=There was an error walking the shader source directory: `{err}`"); + return Err(format!("There was an error walking the shader source directory: `{err}`").into()); }; for input_path in shader_source_files { @@ -41,44 +61,58 @@ fn compile_shaders() -> Result<(), Box> { let shader_out_dir = shader_out_dir.clone(); - running_tasks.push((input_path.clone(), std::thread::spawn(move || -> Result<(), Box> { + running_tasks.push(( + // Store a copy here in case we panic and need to know which file caused the panic (realistically should never happen but whatever) + input_path.clone(), + std::thread::spawn(move || -> Result<(), Box> { + let _aquired = aquired; - let input_file_stem = match input_path.file_stem().and_then(|f| <&str>::try_from(f).ok()) { - Some(stem) => stem.to_owned(), - None => return Err(format!("Could not read file stem of file: {input_path:?}").into()), - }; + let output_path = shader_out_dir.join(&input_path.file_name().unwrap()); // Guaranteed to be a file because of walk_dir - let shader_kind = match &input_file_stem[0..=1] { - "f_" => shaderc::ShaderKind::Fragment, - "v_" => shaderc::ShaderKind::Vertex, - _ => return Err(format!("Shader folder contains a file that is neither a vertex or fragment shader: {input_path:?}").into()), - }; - - let new_file_name = input_file_stem + COMPILED_SHADER_EXTENSION; - let output_path = shader_out_dir.join(&new_file_name); - - if let Err(error) = compile_shader(&input_path, &output_path, shader_kind) { - println!("cargo:warning=Compilation process for input file: {input_path:?} was not successful: `{error}`"); - println!("cargo:warning=I cant be assed to fix this myself but cargo cuts off newlines in warning messages, so if the above error gets cut off youre going to need to find the text file or re run cargo with the -vv flag"); - } - - drop(aquired); - Ok(()) - }))); + if let Err(error) = compile_shader(&input_path, &output_path) { + return Err(format!("Compilation process for input file: {input_path:?} was not successful: `{error}`") + .replace('\n', "\t") + .into()); + } + Ok(()) + }), + )); } + let mut has_error = false; + for (input_file, task) in running_tasks { match task.join() { Ok(Ok(())) => (), Ok(Err(err)) => { println!("cargo:warning=There was an error running a task: `{err}`"); + has_error = true; }, Err(_) => { println!("cargo:warning=A thread panicked while processing this file!: {input_file:?}",); + has_error = true; }, } } - Ok(()) + + if has_error { + Err("Cannot proceed with build process. One or more shaders failed to compile.".into()) + } else { + Ok(()) + } +} + +fn get_stem_and_ext(path:&std::path::PathBuf) -> Result<(String, String), Box> { + Ok(( + match path.file_stem().and_then(|f| <&str>::try_from(f).ok()) { + Some(stem) => stem.to_owned(), + None => return Err(format!("Could not read file stem of file: {path:?}").into()), + }, + match path.extension().and_then(|f| <&str>::try_from(f).ok()) { + Some(stem) => stem.to_owned(), + None => return Err(format!("Could not read extension of file: {path:?}").into()), + }, + )) } fn walk_dir(path:std::path::PathBuf, file_paths_buf:&mut Vec) -> Result<(), Box> { @@ -94,22 +128,48 @@ fn walk_dir(path:std::path::PathBuf, file_paths_buf:&mut Vec } } -fn compile_shader(input_path:&std::path::PathBuf, output_path:&std::path::PathBuf, shader_kind:shaderc::ShaderKind) -> Result<(), Box> { +fn compile_shader(input_path:&std::path::PathBuf, output_path:&std::path::PathBuf) -> Result<(), Box> { let compiler = match shaderc::Compiler::new() { Some(compiler) => compiler, None => return Err(format!("Could not initialize shaderc compiler.").into()), }; - let target = if let Some(extension) = input_path.extension().and_then(|s| <&str>::try_from(s).ok()) { - if SUPPORTED_SHADER_FORMAT_EXTENSIONS_GLSL.contains(&extension) { - shaderc::SourceLanguage::GLSL - } else if SUPPORTED_SHADER_FORMAT_EXTENSIONS_HLSL.contains(&extension) { - shaderc::SourceLanguage::HLSL - } else { - return Err(format!("Could not determine compile target! This file has an invalid extension.").into()); + let (stem, ext) = get_stem_and_ext(&input_path)?; + + let mut target = None; + for glsl_prefix in GLSL_PREFIXES { + if stem.starts_with(glsl_prefix) { + target = Some(shaderc::SourceLanguage::GLSL); + break; } + } + for hlsl_prefix in HLSL_PREFIXES { + if stem.starts_with(hlsl_prefix) { + target = Some(shaderc::SourceLanguage::HLSL); + break; + } + } + let target = if let Some(target) = target { + target } else { - return Err(format!("Could not determine compile target! This file is missing an extension.").into()); + return Err(format!("This file is neither HLSL or GLSL!").into()); + }; + + let mut shader_kind = None; + for vertex_extension in VERTEX_EXTENSIONS { + if ext == vertex_extension { + shader_kind = Some(shaderc::ShaderKind::Vertex) + } + } + for fragment_extension in FRAGMENT_EXTENSIONS { + if ext == fragment_extension { + shader_kind = Some(shaderc::ShaderKind::Fragment) + } + } + let shader_kind = if let Some(shader_kind) = shader_kind { + shader_kind + } else { + return Err(format!("This file is neither a fragment shader or vertex shader!").into()); }; let options = match shaderc::CompileOptions::new() { diff --git a/shaders/f_default.glsl b/shaders/f_default.glsl deleted file mode 100644 index 13009da..0000000 --- a/shaders/f_default.glsl +++ /dev/null @@ -1,9 +0,0 @@ -#version 450 - -layout(location = 0) in vec3 fragColor; - -layout(location = 0) out vec4 outColor; - -void main() { - outColor = vec4(fragColor, 1.0); -} \ No newline at end of file diff --git a/shaders/glsl_default.frag b/shaders/glsl_default.frag new file mode 100644 index 0000000..32359e6 --- /dev/null +++ b/shaders/glsl_default.frag @@ -0,0 +1,24 @@ +#version 450 + +layout(binding = 1) uniform sampler2D texSampler; + +layout(location = 0) in vec3 fragColor; +layout(location = 1) in vec2 fragTexCoord; + +layout(location = 0) out vec4 outColor; + +void main() { + // outColor = texture(texSampler, fragTexCoord); + outColor = vec4(fragColor, 1.0) * texture(texSampler, fragTexCoord).rgba; +} + +// #version 450 + +// layout(location = 0) in vec3 fragColor; +// layout(location = 1) in vec2 fragTexCoord; + +// layout(location = 0) out vec4 outColor; + +// void main() { +// outColor = vec4(fragTexCoord, 0.0, 1.0); +// } \ No newline at end of file diff --git a/shaders/v_default.glsl b/shaders/glsl_default.vert similarity index 63% rename from shaders/v_default.glsl rename to shaders/glsl_default.vert index dec0210..5510aa3 100644 --- a/shaders/v_default.glsl +++ b/shaders/glsl_default.vert @@ -6,12 +6,15 @@ layout(binding = 0) uniform UniformBufferObject { mat4 proj; } ubo; -layout(location = 0) in vec3 inPosition; +layout(location = 0) in vec2 inPosition; layout(location = 1) in vec3 inColor; +layout(location = 2) in vec2 inTexCoord; layout(location = 0) out vec3 fragColor; +layout(location = 1) out vec2 fragTexCoord; void main() { - gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0); + gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0); fragColor = inColor; + fragTexCoord = inTexCoord; } diff --git a/src/graphics_engines/opengl/mod.rs b/src/graphics_engines/opengl/mod.rs index 8b13789..6de5042 100644 --- a/src/graphics_engines/opengl/mod.rs +++ b/src/graphics_engines/opengl/mod.rs @@ -1 +1,447 @@ +use std::error::Error; +use std::ffi::CStr; +use std::ffi::CString; +use std::num::NonZeroU32; +use std::ops::Deref; +use gl::types::GLfloat; +use winit::application::ApplicationHandler; +use winit::event::KeyEvent; +use winit::event::WindowEvent; +use winit::event_loop::ActiveEventLoop; +use winit::keyboard::Key; +use winit::keyboard::NamedKey; +use winit::raw_window_handle::HasWindowHandle; +use winit::window::Window; +use winit::window::WindowAttributes; + +use glutin::config::Config; +use glutin::config::ConfigTemplateBuilder; +use glutin::config::GetGlConfig; +use glutin::context::ContextApi; +use glutin::context::ContextAttributesBuilder; +use glutin::context::NotCurrentContext; +use glutin::context::PossiblyCurrentContext; +use glutin::context::Version; +use glutin::display::GetGlDisplay; +use glutin::prelude::*; +use glutin::surface::Surface; +use glutin::surface::SwapInterval; +use glutin::surface::WindowSurface; + +use glutin_winit::DisplayBuilder; +use glutin_winit::GlWindow; + +pub mod gl { + // #![allow(clippy::all)] + + pub use Gles2 as Gl; + + include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs")); +} + +pub fn main(event_loop:winit::event_loop::EventLoop<()>) -> Result<(), Box> { + // The template will match only the configurations supporting rendering + // to windows. + // + // XXX We force transparency only on macOS, given that EGL on X11 doesn't + // have it, but we still want to show window. The macOS situation is like + // that, because we can query only one config at a time on it, but all + // normal platforms will return multiple configs, so we can find the config + // with transparency ourselves inside the `reduce`. + let template = ConfigTemplateBuilder::new().with_alpha_size(8).with_transparency(cfg!(cgl_backend)); + + let display_builder = DisplayBuilder::new().with_window_attributes(Some(window_attributes())); + + let mut app = App::new(template, display_builder); + event_loop.run_app(&mut app)?; + + app.exit_state +} + +impl ApplicationHandler for App { + fn resumed(&mut self, event_loop:&ActiveEventLoop) { + let (window, gl_config) = match &self.gl_display { + // We just created the event loop, so initialize the display, pick the config, and + // create the context. + GlDisplayCreationState::Builder(display_builder) => { + let (window, gl_config) = match display_builder.clone().build(event_loop, self.template.clone(), gl_config_picker) { + Ok((window, gl_config)) => (window.unwrap(), gl_config), + Err(err) => { + self.exit_state = Err(err); + event_loop.exit(); + return; + }, + }; + + println!("Picked a config with {} samples", gl_config.num_samples()); + + // Mark the display as initialized to not recreate it on resume, since the + // display is valid until we explicitly destroy it. + self.gl_display = GlDisplayCreationState::Init; + + // Create gl context. + self.gl_context = Some(create_gl_context(&window, &gl_config).treat_as_possibly_current()); + + (window, gl_config) + }, + GlDisplayCreationState::Init => { + println!("Recreating window in `resumed`"); + // Pick the config which we already use for the context. + let gl_config = self.gl_context.as_ref().unwrap().config(); + match glutin_winit::finalize_window(event_loop, window_attributes(), &gl_config) { + Ok(window) => (window, gl_config), + Err(err) => { + self.exit_state = Err(err.into()); + event_loop.exit(); + return; + }, + } + }, + }; + + let attrs = window.build_surface_attributes(Default::default()).expect("Failed to build surface attributes"); + let gl_surface = unsafe { gl_config.display().create_window_surface(&gl_config, &attrs).unwrap() }; + + // The context needs to be current for the Renderer to set up shaders and + // buffers. It also performs function loading, which needs a current context on + // WGL. + let gl_context = self.gl_context.as_ref().unwrap(); + gl_context.make_current(&gl_surface).unwrap(); + + self.renderer.get_or_insert_with(|| Renderer::new(&gl_config.display())); + + // Try setting vsync. + if let Err(res) = gl_surface.set_swap_interval(gl_context, SwapInterval::Wait(NonZeroU32::new(1).unwrap())) { + eprintln!("Error setting vsync: {res:?}"); + } + + assert!(self.state.replace(AppState { gl_surface, window }).is_none()); + } + + fn suspended(&mut self, _event_loop:&ActiveEventLoop) { + // This event is only raised on Android, where the backing NativeWindow for a GL + // Surface can appear and disappear at any moment. + println!("Android window removed"); + + // Destroy the GL Surface and un-current the GL Context before ndk-glue releases + // the window back to the system. + self.state = None; + + // Make context not current. + self.gl_context = Some(self.gl_context.take().unwrap().make_not_current().unwrap().treat_as_possibly_current()); + } + + fn window_event(&mut self, event_loop:&ActiveEventLoop, _window_id:winit::window::WindowId, event:WindowEvent) { + match event { + WindowEvent::Resized(size) if size.width != 0 && size.height != 0 => { + // Some platforms like EGL require resizing GL surface to update the size + // Notable platforms here are Wayland and macOS, other don't require it + // and the function is no-op, but it's wise to resize it for portability + // reasons. + if let Some(AppState { gl_surface, window: _ }) = self.state.as_ref() { + let gl_context = self.gl_context.as_ref().unwrap(); + gl_surface.resize(gl_context, NonZeroU32::new(size.width).unwrap(), NonZeroU32::new(size.height).unwrap()); + + let renderer = self.renderer.as_ref().unwrap(); + renderer.resize(size.width as i32, size.height as i32); + } + }, + WindowEvent::CloseRequested | + WindowEvent::KeyboardInput { + event: KeyEvent { + logical_key: Key::Named(NamedKey::Escape), + .. + }, + .. + } => event_loop.exit(), + _ => (), + } + } + + fn exiting(&mut self, _event_loop:&ActiveEventLoop) { + // NOTE: The handling below is only needed due to nvidia on Wayland to not crash + // on exit due to nvidia driver touching the Wayland display from on + // `exit` hook. + let _gl_display = self.gl_context.take().unwrap().display(); + + // Clear the window. + self.state = None; + #[cfg(egl_backend)] + #[allow(irrefutable_let_patterns)] + if let glutin::display::Display::Egl(display) = _gl_display { + unsafe { + display.terminate(); + } + } + } + + fn about_to_wait(&mut self, _event_loop:&ActiveEventLoop) { + if let Some(AppState { gl_surface, window }) = self.state.as_ref() { + let gl_context = self.gl_context.as_ref().unwrap(); + let renderer = self.renderer.as_ref().unwrap(); + renderer.draw(); + window.request_redraw(); + + gl_surface.swap_buffers(gl_context).unwrap(); + } + } +} + +fn create_gl_context(window:&Window, gl_config:&Config) -> NotCurrentContext { + let raw_window_handle = window.window_handle().ok().map(|wh| wh.as_raw()); + + // The context creation part. + let context_attributes = ContextAttributesBuilder::new().build(raw_window_handle); + + // Since glutin by default tries to create OpenGL core context, which may not be + // present we should try gles. + let fallback_context_attributes = ContextAttributesBuilder::new() + .with_context_api(ContextApi::Gles(None)) + .build(raw_window_handle); + + // There are also some old devices that support neither modern OpenGL nor GLES. + // To support these we can try and create a 2.1 context. + let legacy_context_attributes = ContextAttributesBuilder::new() + .with_context_api(ContextApi::OpenGl(Some(Version::new(2, 1)))) + .build(raw_window_handle); + + // Reuse the uncurrented context from a suspended() call if it exists, otherwise + // this is the first time resumed() is called, where the context still + // has to be created. + let gl_display = gl_config.display(); + + unsafe { + gl_display.create_context(gl_config, &context_attributes).unwrap_or_else(|_| { + gl_display.create_context(gl_config, &fallback_context_attributes).unwrap_or_else(|_| { + gl_display + .create_context(gl_config, &legacy_context_attributes) + .expect("failed to create context") + }) + }) + } +} + +fn window_attributes() -> WindowAttributes { + Window::default_attributes() + .with_transparent(true) + .with_title("Glutin triangle gradient example (press Escape to exit)") +} + +enum GlDisplayCreationState { + /// The display was not build yet. + Builder(DisplayBuilder), + /// The display was already created for the application. + Init, +} + +struct App { + template: ConfigTemplateBuilder, + renderer: Option, + // NOTE: `AppState` carries the `Window`, thus it should be dropped after everything else. + state: Option, + gl_context:Option, + gl_display:GlDisplayCreationState, + exit_state:Result<(), Box>, +} + +impl App { + fn new(template:ConfigTemplateBuilder, display_builder:DisplayBuilder) -> Self { + Self { + template, + gl_display:GlDisplayCreationState::Builder(display_builder), + exit_state:Ok(()), + gl_context:None, + state:None, + renderer:None, + } + } +} + +struct AppState { + gl_surface:Surface, + // NOTE: Window should be dropped after all resources created using its + // raw-window-handle. + window: Window, +} + +// Find the config with the maximum number of samples, so our triangle will be +// smooth. +pub fn gl_config_picker(configs:Box+'_>) -> Config { + configs + .reduce(|accum, config| { + let transparency_check = config.supports_transparency().unwrap_or(false) & !accum.supports_transparency().unwrap_or(false); + + if transparency_check || config.num_samples() > accum.num_samples() { + config + } else { + accum + } + }) + .unwrap() +} + +pub struct Renderer { + program:gl::types::GLuint, + vao: gl::types::GLuint, + vbo: gl::types::GLuint, + gl: gl::Gl, +} + +impl Renderer { + pub fn new(gl_display:&D) -> Self { + unsafe { + let gl = gl::Gl::load_with(|symbol| { + let symbol = CString::new(symbol).unwrap(); + gl_display.get_proc_address(symbol.as_c_str()).cast() + }); + + if let Some(renderer) = get_gl_string(&gl, gl::RENDERER) { + println!("Running on {}", renderer.to_string_lossy()); + } + if let Some(version) = get_gl_string(&gl, gl::VERSION) { + println!("OpenGL Version {}", version.to_string_lossy()); + } + + if let Some(shaders_version) = get_gl_string(&gl, gl::SHADING_LANGUAGE_VERSION) { + println!("Shaders version on {}", shaders_version.to_string_lossy()); + } + + let vertex_shader = create_shader(&gl, gl::VERTEX_SHADER, VERTEX_SHADER_SOURCE); + let fragment_shader = create_shader(&gl, gl::FRAGMENT_SHADER, FRAGMENT_SHADER_SOURCE); + + let program = gl.CreateProgram(); + + gl.AttachShader(program, vertex_shader); + gl.AttachShader(program, fragment_shader); + + gl.LinkProgram(program); + + gl.UseProgram(program); + + gl.DeleteShader(vertex_shader); + gl.DeleteShader(fragment_shader); + + let mut vao = std::mem::zeroed(); + gl.GenVertexArrays(1, &mut vao); + gl.BindVertexArray(vao); + + let mut vbo = std::mem::zeroed(); + gl.GenBuffers(1, &mut vbo); + gl.BindBuffer(gl::ARRAY_BUFFER, vbo); + gl.BufferData( + gl::ARRAY_BUFFER, + (VERTEX_DATA.len() * std::mem::size_of::()) as gl::types::GLsizeiptr, + VERTEX_DATA.as_ptr() as *const _, + gl::STATIC_DRAW, + ); + + let pos_attrib = gl.GetAttribLocation(program, b"position\0".as_ptr() as *const _); + let color_attrib = gl.GetAttribLocation(program, b"color\0".as_ptr() as *const _); + gl.VertexAttribPointer( + pos_attrib as gl::types::GLuint, + 2, + gl::FLOAT, + 0, + 5 * std::mem::size_of::() as gl::types::GLsizei, + std::ptr::null(), + ); + gl.VertexAttribPointer( + color_attrib as gl::types::GLuint, + 3, + gl::FLOAT, + 0, + 5 * std::mem::size_of::() as gl::types::GLsizei, + (2 * std::mem::size_of::()) as *const () as *const _, + ); + gl.EnableVertexAttribArray(pos_attrib as gl::types::GLuint); + gl.EnableVertexAttribArray(color_attrib as gl::types::GLuint); + + Self { program, vao, vbo, gl } + } + } + + pub fn draw(&self) { self.draw_with_clear_color(0.1, 0.1, 0.1, 0.9) } + + pub fn draw_with_clear_color(&self, red:GLfloat, green:GLfloat, blue:GLfloat, alpha:GLfloat) { + unsafe { + self.gl.UseProgram(self.program); + + self.gl.BindVertexArray(self.vao); + self.gl.BindBuffer(gl::ARRAY_BUFFER, self.vbo); + + self.gl.ClearColor(red, green, blue, alpha); + self.gl.Clear(gl::COLOR_BUFFER_BIT); + self.gl.DrawArrays(gl::TRIANGLES, 0, 3); + } + } + + pub fn resize(&self, width:i32, height:i32) { + unsafe { + self.gl.Viewport(0, 0, width, height); + } + } +} + +impl Deref for Renderer { + type Target = gl::Gl; + + fn deref(&self) -> &Self::Target { &self.gl } +} + +impl Drop for Renderer { + fn drop(&mut self) { + unsafe { + self.gl.DeleteProgram(self.program); + self.gl.DeleteBuffers(1, &self.vbo); + self.gl.DeleteVertexArrays(1, &self.vao); + } + } +} + +unsafe fn create_shader(gl:&gl::Gl, shader:gl::types::GLenum, source:&[u8]) -> gl::types::GLuint { + let shader = gl.CreateShader(shader); + gl.ShaderSource(shader, 1, [source.as_ptr().cast()].as_ptr(), std::ptr::null()); + gl.CompileShader(shader); + shader +} + +fn get_gl_string(gl:&gl::Gl, variant:gl::types::GLenum) -> Option<&'static CStr> { + unsafe { + let s = gl.GetString(variant); + (!s.is_null()).then(|| CStr::from_ptr(s.cast())) + } +} + +#[rustfmt::skip] +static VERTEX_DATA: [f32; 15] = [ + -0.5, -0.5, 1.0, 0.0, 0.0, + 0.0, 0.5, 0.0, 1.0, 0.0, + 0.5, -0.5, 0.0, 0.0, 1.0, +]; + +const VERTEX_SHADER_SOURCE:&[u8] = b" +#version 100 +precision mediump float; + +attribute vec2 position; +attribute vec3 color; + +varying vec3 v_color; + +void main() { + gl_Position = vec4(position, 0.0, 1.0); + v_color = color; +} +\0"; + +const FRAGMENT_SHADER_SOURCE:&[u8] = b" +#version 100 +precision mediump float; + +varying vec3 v_color; + +void main() { + gl_FragColor = vec4(v_color, 1.0); +} +\0"; diff --git a/src/graphics_engines/vulkan/mod.rs b/src/graphics_engines/vulkan/mod.rs index aba203c..e08d2ab 100644 --- a/src/graphics_engines/vulkan/mod.rs +++ b/src/graphics_engines/vulkan/mod.rs @@ -10,7 +10,6 @@ use log::*; use std::collections::HashSet; use std::ffi::CStr; -use std::fs::File; use std::mem::size_of; use std::os::raw::c_void; use std::ptr::copy_nonoverlapping as memcpy; @@ -29,7 +28,7 @@ use vulkanalia::vk::ExtDebugUtilsExtension; use vulkanalia::vk::KhrSurfaceExtension; use vulkanalia::vk::KhrSwapchainExtension; -use winit::window::Window; +use old_winit::window::Window; type Vec2f = cgmath::Vector2; type Vec3f = cgmath::Vector3; @@ -64,17 +63,15 @@ const MAX_FRAMES_IN_FLIGHT:usize = 2; // ]; static VERTICES:[Vertex; 4] = [ - Vertex::new(vec2(-0.5, -0.5), vec3(0.3, 0.0, 1.0)), - Vertex::new(vec2(0.5, -0.5), vec3(0.3, 0.0, 1.0)), - Vertex::new(vec2(0.5, 0.5), vec3(0.3, 0.0, 1.0)), - Vertex::new(vec2(-0.5, 0.5), vec3(0.3, 0.0, 1.0)), - // Vertex::new(vec2(-1.0, -1.0),vec3(0.3, 0.0, 1.0)), - // Vertex::new(vec2(1.0, -1.0), vec3(0.3, 0.0, 1.0)), - // Vertex::new(vec2(1.0, 1.0), vec3(0.3, 0.0, 1.0)), - // Vertex::new(vec2(-1.0, 1.0), vec3(0.3, 0.0, 1.0)), + Vertex::new(vec2(-0.5, -0.5), vec3(1.0, 1.0, 1.0), vec2(1.0, 0.0)), + Vertex::new(vec2(0.5, -0.5), vec3(1.0, 1.0, 1.0), vec2(0.0, 0.0)), + Vertex::new(vec2(0.5, 0.5), vec3(1.0, 1.0, 1.0), vec2(0.0, 1.0)), + Vertex::new(vec2(-0.5, 0.5), vec3(1.0, 1.0, 1.0), vec2(1.0, 1.0)), ]; + const INDICES:&[u16] = &[0, 1, 2, 2, 3, 0]; +/// The shaders compiled by build.rs keep the same name and relative path as the source file exactly macro_rules! const_shaders { { $($vis:vis $identifier:ident = $string:literal; )* } => { $( @@ -137,7 +134,12 @@ impl App { /// Renders a frame for our Vulkan app. pub unsafe fn render(&mut self, window:&Window) -> Result<()> { - self.device.wait_for_fences(&[self.data.in_flight_fences[self.frame]], true, u64::MAX)?; + // self.device + // .wait_for_fences(&[self.data.in_flight_fences[self.frame]], true, u64::MAX)?; + + let in_flight_fence = self.data.in_flight_fences[self.frame]; + + self.device.wait_for_fences(&[in_flight_fence], true, u64::MAX)?; let result = self.device.acquire_next_image_khr( self.data.swapchain, @@ -152,12 +154,22 @@ impl App { Err(e) => return Err(anyhow!(e)), }; - if !self.data.images_in_flight[image_index as usize].is_null() { - self.device - .wait_for_fences(&[self.data.images_in_flight[image_index as usize]], true, u64::MAX)?; + // if !self.data.images_in_flight[image_index].is_null() { + // self.device.wait_for_fences( + // &[self.data.images_in_flight[image_index as usize]], + // true, + // u64::MAX, + // )?; + // } + + // self.data.images_in_flight[image_index] = self.data.in_flight_fences[self.frame]; + + let image_in_flight = self.data.images_in_flight[image_index]; + if !image_in_flight.is_null() { + self.device.wait_for_fences(&[image_in_flight], true, u64::MAX)?; } - self.data.images_in_flight[image_index as usize] = self.data.in_flight_fences[self.frame]; + self.data.images_in_flight[image_index] = in_flight_fence; self.update_uniform_buffer(image_index)?; @@ -206,7 +218,7 @@ impl App { let model = Mat4f::from_axis_angle(vec3(0.0, 0.0, 1.0), Deg(45.0) * time); - let view = Mat4f::look_at_rh(point3(2.0, 5.0, 2.0), point3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0)); + let view = Mat4f::look_at_rh(point3(2.0, 2.0, 2.0), point3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0)); let mut proj = cgmath::perspective( Deg(45.0), @@ -273,9 +285,11 @@ impl App { self.device.free_memory(self.data.vertex_buffer_memory, None); self.device.destroy_buffer(self.data.vertex_buffer, None); + self.device.destroy_sampler(self.data.texture_sampler, None); + self.device.destroy_image_view(self.data.texture_image_view, None); + self.device.free_memory(self.data.texture_image_memory, None); self.device.destroy_image(self.data.texture_image, None); - self.device.destroy_image_view(self.data.texture_image_view, None); self.device.destroy_command_pool(self.data.command_pool, None); @@ -343,6 +357,7 @@ struct AppData { texture_image: vk::Image, texture_image_memory: vk::DeviceMemory, texture_image_view: vk::ImageView, + texture_sampler: vk::Sampler, } unsafe fn create_instance(window:&Window, entry:&Entry, data:&mut AppData) -> Result { @@ -351,14 +366,14 @@ unsafe fn create_instance(window:&Window, entry:&Entry, data:&mut AppData) -> Re // Lets hope one day we will be on this list let application_info = vk::ApplicationInfo::builder() - // Our application information - .application_name(VK_APPLICATION_NAME) - .application_version(vk::make_version(0, 1, 0)) - // Our engine information - .engine_name(VK_ENGINE_NAME) - .engine_version(vk::make_version(0, 1, 0)) - // Vulkan api version target - .api_version(vk::make_version(1, 0, 0)); + // Our application information + .application_name(VK_APPLICATION_NAME) + .application_version(vk::make_version(0, 1, 0)) + // Our engine information + .engine_name(VK_ENGINE_NAME) + .engine_version(vk::make_version(0, 1, 0)) + // Vulkan api version target + .api_version(vk::make_version(1, 0, 0)); // Get the names of available layers let available_layers = entry @@ -385,8 +400,8 @@ unsafe fn create_instance(window:&Window, entry:&Entry, data:&mut AppData) -> Re // Required by Vulkan SDK on macOS since 1.3.216. let flags = if cfg!(target_os = "macos") && entry.version()? >= PORTABILITY_MACOS_VERSION { info!("Enabling extensions for macOS portability."); + // already present above // extensions.push( - // // already present above // vk::KHR_GET_PHYSICAL_DEVICE_PROPERTIES2_EXTENSION.name.as_ptr(), // ); extensions.push(vk::KHR_PORTABILITY_ENUMERATION_EXTENSION.name.as_ptr()); @@ -471,6 +486,11 @@ unsafe fn check_physical_device(instance:&Instance, data:&AppData, physical_devi return Err(anyhow!(SuitabilityError("Insufficient swapchain support."))); } + let features = instance.get_physical_device_features(physical_device); + if features.sampler_anisotropy != vk::TRUE { + return Err(anyhow!(SuitabilityError("No sampler anisotropy."))); + } + // // TODO handle this like the other one? // let properties = instance.get_physical_device_properties(physical_device); // if properties.device_type != vk::PhysicalDeviceType::DISCRETE_GPU { @@ -531,7 +551,7 @@ unsafe fn create_logical_device(entry:&Entry, instance:&Instance, data:&mut AppD extensions.push(vk::KHR_PORTABILITY_SUBSET_EXTENSION.name.as_ptr()); } - let features = vk::PhysicalDeviceFeatures::builder(); + let features = vk::PhysicalDeviceFeatures::builder().sampler_anisotropy(true); let info = vk::DeviceCreateInfo::builder() .queue_create_infos(&queue_infos) @@ -697,7 +717,13 @@ unsafe fn create_descriptor_set_layout(device:&Device, data:&mut AppData) -> Res .descriptor_count(1) .stage_flags(vk::ShaderStageFlags::VERTEX); - let bindings = &[ubo_binding]; + let sampler_binding = vk::DescriptorSetLayoutBinding::builder() + .binding(1) + .descriptor_type(vk::DescriptorType::COMBINED_IMAGE_SAMPLER) + .descriptor_count(1) + .stage_flags(vk::ShaderStageFlags::FRAGMENT); + + let bindings = &[ubo_binding, sampler_binding]; let info = vk::DescriptorSetLayoutCreateInfo::builder().bindings(bindings); data.descriptor_set_layout = device.create_descriptor_set_layout(&info, None)?; @@ -707,8 +733,8 @@ unsafe fn create_descriptor_set_layout(device:&Device, data:&mut AppData) -> Res unsafe fn create_pipeline(device:&Device, data:&mut AppData) -> Result<()> { const_shaders! { - frag = "f_default.spv"; - vert = "v_default.spv"; + frag = "glsl_default.frag"; + vert = "glsl_default.vert"; } let vert_shader_module = create_shader_module(device, &vert[..])?; @@ -763,14 +789,14 @@ unsafe fn create_pipeline(device:&Device, data:&mut AppData) -> Result<()> { let attachment = vk::PipelineColorBlendAttachmentState::builder() .color_write_mask(vk::ColorComponentFlags::all()) - .blend_enable(false); - // .blend_enable(true) - // .src_color_blend_factor(vk::BlendFactor::SRC_ALPHA) - // .dst_color_blend_factor(vk::BlendFactor::ONE_MINUS_SRC_ALPHA) - // .color_blend_op(vk::BlendOp::ADD) - // .src_alpha_blend_factor(vk::BlendFactor::ONE) - // .dst_alpha_blend_factor(vk::BlendFactor::ZERO) - // .alpha_blend_op(vk::BlendOp::ADD); + // .blend_enable(false); + .blend_enable(true) + .src_color_blend_factor(vk::BlendFactor::SRC_ALPHA) + .dst_color_blend_factor(vk::BlendFactor::ONE_MINUS_SRC_ALPHA) + .color_blend_op(vk::BlendOp::ADD) + .src_alpha_blend_factor(vk::BlendFactor::ONE) + .dst_alpha_blend_factor(vk::BlendFactor::ZERO) + .alpha_blend_op(vk::BlendOp::ADD); let attachments = &[attachment]; let color_blend_state = vk::PipelineColorBlendStateCreateInfo::builder() @@ -837,8 +863,8 @@ unsafe fn create_command_pool(instance:&Instance, device:&Device, data:&mut AppD let indices = QueueFamilyIndices::get(instance, data, data.physical_device)?; let info = vk::CommandPoolCreateInfo::builder() - .flags(vk::CommandPoolCreateFlags::empty()) // Optional. - .queue_family_index(indices.graphics); + .flags(vk::CommandPoolCreateFlags::empty()) // Optional. + .queue_family_index(indices.graphics); data.command_pool = device.create_command_pool(&info, None)?; @@ -846,16 +872,18 @@ unsafe fn create_command_pool(instance:&Instance, device:&Device, data:&mut AppD } unsafe fn create_texture_image(instance:&Instance, device:&Device, data:&mut AppData) -> Result<()> { - let image = File::open("assets/common/archlogo.512.png")?; + let image = include_bytes!("../../../assets/common/archlogo.512.png"); - let decoder = png::Decoder::new(image); - let mut reader = decoder.read_info()?; + let mut image = image::ImageReader::new(std::io::Cursor::new(image.to_vec())); + image.set_format(image::ImageFormat::Png); + let image = image.decode()?; - let mut pixels = vec![0; reader.info().raw_bytes()]; - reader.next_frame(&mut pixels)?; // what format is this reading to? + let pixelcollection:Vec<(u32, u32, image::Rgba)> = image::GenericImageView::pixels(&image).collect(); //.view(0, 0, image.width(), image.height()); - let size = reader.info().raw_bytes() as u64; - let (width, height) = reader.info().size(); + let rawpixeldata = Vec::from_iter(pixelcollection.iter().map(|(pox, poy, dat)| dat.0)); + + let size = (rawpixeldata.len() * 4) as u64; + let (width, height) = image::GenericImageView::dimensions(&image); let (staging_buffer, staging_buffer_memory) = create_buffer( instance, @@ -868,7 +896,7 @@ unsafe fn create_texture_image(instance:&Instance, device:&Device, data:&mut App let memory = device.map_memory(staging_buffer_memory, 0, size, vk::MemoryMapFlags::empty())?; - memcpy(pixels.as_ptr(), memory.cast(), pixels.len()); + memcpy(rawpixeldata.as_ptr(), memory.cast(), rawpixeldata.len()); device.unmap_memory(staging_buffer_memory); @@ -911,6 +939,203 @@ unsafe fn create_texture_image(instance:&Instance, device:&Device, data:&mut App Ok(()) } + +unsafe fn create_texture_image_view(device:&Device, data:&mut AppData) -> Result<()> { + data.texture_image_view = create_image_view(device, data.texture_image, vk::Format::R8G8B8A8_SRGB)?; + + Ok(()) +} + +unsafe fn create_texture_sampler(device:&Device, data:&mut AppData) -> Result<()> { + // let mut ccolor = vk::SamplerCustomBorderColorCreateInfoEXT::builder() + // .format(vk::Format::R8G8B8A8_SRGB) + // .custom_border_color(vk::ClearColorValue { + // float32:[0.0125, 0.001, 0.007, 1.0], + // // float32:[1.0, 1.0, 1.0, 1.0], + // }) + // .build(); + + let info = vk::SamplerCreateInfo::builder() + .mag_filter(vk::Filter::LINEAR) + .min_filter(vk::Filter::LINEAR) + .address_mode_u(vk::SamplerAddressMode::CLAMP_TO_BORDER) + .address_mode_v(vk::SamplerAddressMode::CLAMP_TO_BORDER) + .address_mode_w(vk::SamplerAddressMode::CLAMP_TO_BORDER) + .anisotropy_enable(true) + .max_anisotropy(16.0) + .border_color(vk::BorderColor::INT_OPAQUE_WHITE) + // .border_color(vk::BorderColor::FLOAT_CUSTOM_EXT) + // .push_next(&mut ccolor) + .unnormalized_coordinates(false) + .compare_enable(false) + .compare_op(vk::CompareOp::ALWAYS) + .mipmap_mode(vk::SamplerMipmapMode::LINEAR) + .mip_lod_bias(0.0) + .min_lod(0.0) + .max_lod(0.0); + + data.texture_sampler = device.create_sampler(&info, None)?; + + Ok(()) +} + +unsafe fn create_vertex_buffer(instance:&Instance, device:&Device, data:&mut AppData) -> Result<()> { + let size = (size_of::() * VERTICES.len()) as u64; + + let (staging_buffer, staging_buffer_memory) = create_buffer( + instance, + device, + data, + size, + vk::BufferUsageFlags::TRANSFER_SRC, + vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE, + )?; + + let memory = device.map_memory(staging_buffer_memory, 0, size, vk::MemoryMapFlags::empty())?; + + memcpy(VERTICES.as_ptr(), memory.cast(), VERTICES.len()); + + device.unmap_memory(staging_buffer_memory); + + let (vertex_buffer, vertex_buffer_memory) = create_buffer( + instance, + device, + data, + size, + vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::VERTEX_BUFFER, + vk::MemoryPropertyFlags::DEVICE_LOCAL, + )?; + + data.vertex_buffer = vertex_buffer; + data.vertex_buffer_memory = vertex_buffer_memory; + + copy_buffer(device, data, staging_buffer, vertex_buffer, size)?; + + device.destroy_buffer(staging_buffer, None); + device.free_memory(staging_buffer_memory, None); + + Ok(()) +} + +unsafe fn create_index_buffer(instance:&Instance, device:&Device, data:&mut AppData) -> Result<()> { + let size = (size_of::() * INDICES.len()) as u64; + + let (staging_buffer, staging_buffer_memory) = create_buffer( + instance, + device, + data, + size, + vk::BufferUsageFlags::TRANSFER_SRC, + vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE, + )?; + + let memory = device.map_memory(staging_buffer_memory, 0, size, vk::MemoryMapFlags::empty())?; + + memcpy(INDICES.as_ptr(), memory.cast(), INDICES.len()); + + device.unmap_memory(staging_buffer_memory); + + let (index_buffer, index_buffer_memory) = create_buffer( + instance, + device, + data, + size, + vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::INDEX_BUFFER, + vk::MemoryPropertyFlags::DEVICE_LOCAL, + )?; + + data.index_buffer = index_buffer; + data.index_buffer_memory = index_buffer_memory; + + copy_buffer(device, data, staging_buffer, index_buffer, size)?; + + device.destroy_buffer(staging_buffer, None); + device.free_memory(staging_buffer_memory, None); + + Ok(()) +} + +unsafe fn create_uniform_buffers(instance:&Instance, device:&Device, data:&mut AppData) -> Result<()> { + data.uniform_buffers.clear(); + data.uniform_buffers_memory.clear(); + + for _ in 0..data.swapchain_images.len() { + let (uniform_buffer, uniform_buffer_memory) = create_buffer( + instance, + device, + data, + size_of::() as u64, + vk::BufferUsageFlags::UNIFORM_BUFFER, + vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE, + )?; + + data.uniform_buffers.push(uniform_buffer); + data.uniform_buffers_memory.push(uniform_buffer_memory); + } + + Ok(()) +} + +unsafe fn create_descriptor_pool(device:&Device, data:&mut AppData) -> Result<()> { + let ubo_size = vk::DescriptorPoolSize::builder() + .type_(vk::DescriptorType::UNIFORM_BUFFER) + .descriptor_count(data.swapchain_images.len() as u32); + + let sampler_size = vk::DescriptorPoolSize::builder() + .type_(vk::DescriptorType::COMBINED_IMAGE_SAMPLER) + .descriptor_count(data.swapchain_images.len() as u32); + + let pool_sizes = &[ubo_size, sampler_size]; + let info = vk::DescriptorPoolCreateInfo::builder() + .pool_sizes(pool_sizes) + .max_sets(data.swapchain_images.len() as u32); + + data.descriptor_pool = device.create_descriptor_pool(&info, None)?; + + Ok(()) +} + +unsafe fn create_descriptor_sets(device:&Device, data:&mut AppData) -> Result<()> { + let layouts = vec![data.descriptor_set_layout; data.swapchain_images.len()]; + let info = vk::DescriptorSetAllocateInfo::builder() + .descriptor_pool(data.descriptor_pool) + .set_layouts(&layouts); + + data.descriptor_sets = device.allocate_descriptor_sets(&info)?; + + for i in 0..data.swapchain_images.len() { + let info = vk::DescriptorBufferInfo::builder() + .buffer(data.uniform_buffers[i]) + .offset(0) + .range(size_of::() as u64); + + let buffer_info = &[info]; + let ubo_write = vk::WriteDescriptorSet::builder() + .dst_set(data.descriptor_sets[i]) + .dst_binding(0) + .dst_array_element(0) + .descriptor_type(vk::DescriptorType::UNIFORM_BUFFER) + .buffer_info(buffer_info); + + let info = vk::DescriptorImageInfo::builder() + .image_layout(vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL) + .image_view(data.texture_image_view) + .sampler(data.texture_sampler); + + let image_info = &[info]; + let sampler_write = vk::WriteDescriptorSet::builder() + .dst_set(data.descriptor_sets[i]) + .dst_binding(1) + .dst_array_element(0) + .descriptor_type(vk::DescriptorType::COMBINED_IMAGE_SAMPLER) + .image_info(image_info); + + device.update_descriptor_sets(&[ubo_write, sampler_write], &[] as &[vk::CopyDescriptorSet]); + } + + Ok(()) +} + unsafe fn create_command_buffers(device:&Device, data:&mut AppData) -> Result<()> { let allocate_info = vk::CommandBufferAllocateInfo::builder() .command_pool(data.command_pool) @@ -921,10 +1146,9 @@ unsafe fn create_command_buffers(device:&Device, data:&mut AppData) -> Result<() for (i, command_buffer) in data.command_buffers.iter().enumerate() { let inheritance = vk::CommandBufferInheritanceInfo::builder(); - let info = vk::CommandBufferBeginInfo::builder() - .flags(vk::CommandBufferUsageFlags::empty()) // Optional. - .inheritance_info(&inheritance); // Optional. + .flags(vk::CommandBufferUsageFlags::empty()) // Optional. + .inheritance_info(&inheritance); // Optional. device.begin_command_buffer(*command_buffer, &info)?; @@ -933,6 +1157,7 @@ unsafe fn create_command_buffers(device:&Device, data:&mut AppData) -> Result<() let color_clear_value = vk::ClearValue { color:vk::ClearColorValue { float32:[0.0125, 0.0094, 0.0071, 1.0], + // float32: [0.0, 0.0, 0.0, 1.0], }, }; @@ -1031,15 +1256,24 @@ impl SwapchainSupport { } } +#[repr(C)] +#[derive(Copy, Clone, Debug)] +struct UniformBufferObject { + model:Mat4f, + view: Mat4f, + proj: Mat4f, +} + #[repr(C)] #[derive(Copy, Clone, Debug)] struct Vertex { - pos: Vec2f, - color:Vec3f, + pos: Vec2f, + color: Vec3f, + tex_coord:Vec2f, } impl Vertex { - const fn new(pos:Vec2f, color:Vec3f) -> Self { Self { pos, color } } + const fn new(pos:Vec2f, color:Vec3f, tex_coord:Vec2f) -> Self { Self { pos, color, tex_coord } } fn binding_description() -> vk::VertexInputBindingDescription { vk::VertexInputBindingDescription::builder() @@ -1049,7 +1283,7 @@ impl Vertex { .build() } - fn attribute_descriptions() -> [vk::VertexInputAttributeDescription; 2] { + fn attribute_descriptions() -> [vk::VertexInputAttributeDescription; 3] { let pos = vk::VertexInputAttributeDescription::builder() .binding(0) .location(0) @@ -1064,71 +1298,17 @@ impl Vertex { .offset(size_of::() as u32) .build(); - [pos, color] + let tex_coord = vk::VertexInputAttributeDescription::builder() + .binding(0) + .location(2) + .format(vk::Format::R32G32_SFLOAT) + .offset((size_of::() + size_of::()) as u32) + .build(); + + [pos, color, tex_coord] } } -unsafe fn create_vertex_buffer(instance:&Instance, device:&Device, data:&mut AppData) -> Result<()> { - let size = (size_of::() * VERTICES.len()) as u64; - - let (staging_buffer, staging_buffer_memory) = create_buffer( - instance, - device, - data, - size, - vk::BufferUsageFlags::TRANSFER_SRC, - vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE, - )?; - - let memory = device.map_memory(staging_buffer_memory, 0, size, vk::MemoryMapFlags::empty())?; - - memcpy(VERTICES.as_ptr(), memory.cast(), VERTICES.len()); - - device.unmap_memory(staging_buffer_memory); - - let (vertex_buffer, vertex_buffer_memory) = create_buffer( - instance, - device, - data, - size, - vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::VERTEX_BUFFER, - vk::MemoryPropertyFlags::DEVICE_LOCAL, - )?; - - data.vertex_buffer = vertex_buffer; - data.vertex_buffer_memory = vertex_buffer_memory; - - copy_buffer(device, data, staging_buffer, vertex_buffer, size)?; - - device.destroy_buffer(staging_buffer, None); - device.free_memory(staging_buffer_memory, None); - - Ok(()) -} - -unsafe fn copy_buffer(device:&Device, data:&AppData, source:vk::Buffer, destination:vk::Buffer, size:vk::DeviceSize) -> Result<()> { - let command_buffer = begin_single_time_commands(device, data)?; - - let regions = vk::BufferCopy::builder().size(size); - device.cmd_copy_buffer(command_buffer, source, destination, &[regions]); - - end_single_time_commands(device, data, command_buffer)?; - - Ok(()) -} - -unsafe fn get_memory_type_index(instance:&Instance, data:&AppData, properties:vk::MemoryPropertyFlags, requirements:vk::MemoryRequirements) -> Result { - let memory = instance.get_physical_device_memory_properties(data.physical_device); - - (0..memory.memory_type_count) - .find(|i| { - let suitable = (requirements.memory_type_bits & (1 << i)) != 0; - let memory_type = memory.memory_types[*i as usize]; - suitable && memory_type.property_flags.contains(properties) - }) - .ok_or_else(|| anyhow!("Failed to find suitable memory type.")) -} - unsafe fn create_buffer( instance:&Instance, device:&Device, data:&AppData, size:vk::DeviceSize, usage:vk::BufferUsageFlags, properties:vk::MemoryPropertyFlags, ) -> Result<(vk::Buffer, vk::DeviceMemory)> { @@ -1149,112 +1329,13 @@ unsafe fn create_buffer( Ok((buffer, buffer_memory)) } -unsafe fn create_index_buffer(instance:&Instance, device:&Device, data:&mut AppData) -> Result<()> { - let size = (size_of::() * INDICES.len()) as u64; +unsafe fn copy_buffer(device:&Device, data:&AppData, source:vk::Buffer, destination:vk::Buffer, size:vk::DeviceSize) -> Result<()> { + let command_buffer = begin_single_time_commands(device, data)?; - let (staging_buffer, staging_buffer_memory) = create_buffer( - instance, - device, - data, - size, - vk::BufferUsageFlags::TRANSFER_SRC, - vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE, - )?; + let regions = vk::BufferCopy::builder().size(size); + device.cmd_copy_buffer(command_buffer, source, destination, &[regions]); - let memory = device.map_memory(staging_buffer_memory, 0, size, vk::MemoryMapFlags::empty())?; - - memcpy(INDICES.as_ptr(), memory.cast(), INDICES.len()); - - device.unmap_memory(staging_buffer_memory); - - let (index_buffer, index_buffer_memory) = create_buffer( - instance, - device, - data, - size, - vk::BufferUsageFlags::TRANSFER_DST | vk::BufferUsageFlags::INDEX_BUFFER, - vk::MemoryPropertyFlags::DEVICE_LOCAL, - )?; - - data.index_buffer = index_buffer; - data.index_buffer_memory = index_buffer_memory; - - copy_buffer(device, data, staging_buffer, index_buffer, size)?; - - device.destroy_buffer(staging_buffer, None); - device.free_memory(staging_buffer_memory, None); - - Ok(()) -} - -#[repr(C)] -#[derive(Copy, Clone, Debug)] -struct UniformBufferObject { - model:Mat4f, - view: Mat4f, - proj: Mat4f, -} - -unsafe fn create_uniform_buffers(instance:&Instance, device:&Device, data:&mut AppData) -> Result<()> { - data.uniform_buffers.clear(); - data.uniform_buffers_memory.clear(); - - for _ in 0..data.swapchain_images.len() { - let (uniform_buffer, uniform_buffer_memory) = create_buffer( - instance, - device, - data, - size_of::() as u64, - vk::BufferUsageFlags::UNIFORM_BUFFER, - vk::MemoryPropertyFlags::HOST_COHERENT | vk::MemoryPropertyFlags::HOST_VISIBLE, - )?; - - data.uniform_buffers.push(uniform_buffer); - data.uniform_buffers_memory.push(uniform_buffer_memory); - } - - Ok(()) -} - -unsafe fn create_descriptor_pool(device:&Device, data:&mut AppData) -> Result<()> { - let ubo_size = vk::DescriptorPoolSize::builder() - .type_(vk::DescriptorType::UNIFORM_BUFFER) - .descriptor_count(data.swapchain_images.len() as u32); - - let pool_sizes = &[ubo_size]; - let info = vk::DescriptorPoolCreateInfo::builder() - .pool_sizes(pool_sizes) - .max_sets(data.swapchain_images.len() as u32); - - data.descriptor_pool = device.create_descriptor_pool(&info, None)?; - - Ok(()) -} - -unsafe fn create_descriptor_sets(device:&Device, data:&mut AppData) -> Result<()> { - let layouts = vec![data.descriptor_set_layout; data.swapchain_images.len()]; - let info = vk::DescriptorSetAllocateInfo::builder() - .descriptor_pool(data.descriptor_pool) - .set_layouts(&layouts); - - data.descriptor_sets = device.allocate_descriptor_sets(&info)?; - - for i in 0..data.swapchain_images.len() { - let info = vk::DescriptorBufferInfo::builder() - .buffer(data.uniform_buffers[i]) - .offset(0) - .range(size_of::() as u64); - - let buffer_info = &[info]; - let ubo_write = vk::WriteDescriptorSet::builder() - .dst_set(data.descriptor_sets[i]) - .dst_binding(0) - .dst_array_element(0) - .descriptor_type(vk::DescriptorType::UNIFORM_BUFFER) - .buffer_info(buffer_info); - - device.update_descriptor_sets(&[ubo_write], &[] as &[vk::CopyDescriptorSet]); - } + end_single_time_commands(device, data, command_buffer)?; Ok(()) } @@ -1272,8 +1353,8 @@ unsafe fn create_image( .tiling(tiling) .initial_layout(vk::ImageLayout::UNDEFINED) .usage(usage) - .samples(vk::SampleCountFlags::_1) - .sharing_mode(vk::SharingMode::EXCLUSIVE); + .sharing_mode(vk::SharingMode::EXCLUSIVE) + .samples(vk::SampleCountFlags::_1); let image = device.create_image(&info, None)?; @@ -1290,47 +1371,26 @@ unsafe fn create_image( Ok((image, image_memory)) } -unsafe fn begin_single_time_commands(device:&Device, data:&AppData) -> Result { - let info = vk::CommandBufferAllocateInfo::builder() - .level(vk::CommandBufferLevel::PRIMARY) - .command_pool(data.command_pool) - .command_buffer_count(1); - - let command_buffer = device.allocate_command_buffers(&info)?[0]; - - let info = vk::CommandBufferBeginInfo::builder().flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT); - - device.begin_command_buffer(command_buffer, &info)?; - - Ok(command_buffer) -} - -unsafe fn end_single_time_commands(device:&Device, data:&AppData, command_buffer:vk::CommandBuffer) -> Result<()> { - device.end_command_buffer(command_buffer)?; - - let command_buffers = &[command_buffer]; - let info = vk::SubmitInfo::builder().command_buffers(command_buffers); - - device.queue_submit(data.graphics_queue, &[info], vk::Fence::null())?; - device.queue_wait_idle(data.graphics_queue)?; - - device.free_command_buffers(data.command_pool, &[command_buffer]); - - Ok(()) -} - -unsafe fn transition_image_layout( - device:&Device, data:&AppData, image:vk::Image, format:vk::Format, old_layout:vk::ImageLayout, new_layout:vk::ImageLayout, -) -> Result<()> { - let command_buffer = begin_single_time_commands(device, data)?; - - let subresource = vk::ImageSubresourceRange::builder() +unsafe fn create_image_view(device:&Device, image:vk::Image, format:vk::Format) -> Result { + let subresource_range = vk::ImageSubresourceRange::builder() .aspect_mask(vk::ImageAspectFlags::COLOR) .base_mip_level(0) .level_count(1) .base_array_layer(0) .layer_count(1); + let info = vk::ImageViewCreateInfo::builder() + .image(image) + .view_type(vk::ImageViewType::_2D) + .format(format) + .subresource_range(subresource_range); + + Ok(device.create_image_view(&info, None)?) +} + +unsafe fn transition_image_layout( + device:&Device, data:&AppData, image:vk::Image, format:vk::Format, old_layout:vk::ImageLayout, new_layout:vk::ImageLayout, +) -> Result<()> { let (src_access_mask, dst_access_mask, src_stage_mask, dst_stage_mask) = match (old_layout, new_layout) { (vk::ImageLayout::UNDEFINED, vk::ImageLayout::TRANSFER_DST_OPTIMAL) => ( vk::AccessFlags::empty(), @@ -1347,6 +1407,15 @@ unsafe fn transition_image_layout( _ => return Err(anyhow!("Unsupported image layout transition!")), }; + let command_buffer = begin_single_time_commands(device, data)?; + + let subresource = vk::ImageSubresourceRange::builder() + .aspect_mask(vk::ImageAspectFlags::COLOR) + .base_mip_level(0) + .level_count(1) + .base_array_layer(0) + .layer_count(1); + let barrier = vk::ImageMemoryBarrier::builder() .old_layout(old_layout) .new_layout(new_layout) @@ -1396,27 +1465,43 @@ unsafe fn copy_buffer_to_image(device:&Device, data:&AppData, buffer:vk::Buffer, Ok(()) } -unsafe fn create_texture_image_view(device:&Device, data:&mut AppData) -> Result<()> { - data.texture_image_view = create_image_view(device, data.texture_image, vk::Format::R8G8B8A8_SRGB)?; - +unsafe fn get_memory_type_index(instance:&Instance, data:&AppData, properties:vk::MemoryPropertyFlags, requirements:vk::MemoryRequirements) -> Result { + let memory = instance.get_physical_device_memory_properties(data.physical_device); + + (0..memory.memory_type_count) + .find(|i| { + let suitable = (requirements.memory_type_bits & (1 << i)) != 0; + let memory_type = memory.memory_types[*i as usize]; + suitable && memory_type.property_flags.contains(properties) + }) + .ok_or_else(|| anyhow!("Failed to find suitable memory type.")) +} + +unsafe fn begin_single_time_commands(device:&Device, data:&AppData) -> Result { + let info = vk::CommandBufferAllocateInfo::builder() + .level(vk::CommandBufferLevel::PRIMARY) + .command_pool(data.command_pool) + .command_buffer_count(1); + + let command_buffer = device.allocate_command_buffers(&info)?[0]; + + let info = vk::CommandBufferBeginInfo::builder().flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT); + + device.begin_command_buffer(command_buffer, &info)?; + + Ok(command_buffer) +} + +unsafe fn end_single_time_commands(device:&Device, data:&AppData, command_buffer:vk::CommandBuffer) -> Result<()> { + device.end_command_buffer(command_buffer)?; + + let command_buffers = &[command_buffer]; + let info = vk::SubmitInfo::builder().command_buffers(command_buffers); + + device.queue_submit(data.graphics_queue, &[info], vk::Fence::null())?; + device.queue_wait_idle(data.graphics_queue)?; + + device.free_command_buffers(data.command_pool, &[command_buffer]); + Ok(()) } - -unsafe fn create_image_view(device:&Device, image:vk::Image, format:vk::Format) -> Result { - let subresource_range = vk::ImageSubresourceRange::builder() - .aspect_mask(vk::ImageAspectFlags::COLOR) - .base_mip_level(0) - .level_count(1) - .base_array_layer(0) - .layer_count(1); - - let info = vk::ImageViewCreateInfo::builder() - .image(image) - .view_type(vk::ImageViewType::_2D) - .format(format) - .subresource_range(subresource_range); - - Ok(device.create_image_view(&info, None)?) -} - -unsafe fn create_texture_sampler(device:&Device, data:&mut AppData) -> Result<()> { Ok(()) } diff --git a/src/linux.rs b/src/linux.rs index be6d4d8..56c21a7 100644 --- a/src/linux.rs +++ b/src/linux.rs @@ -4,15 +4,16 @@ use log::*; use vulkanalia::prelude::v1_0::*; -use winit::dpi::LogicalSize; -use winit::event::Event; -use winit::event::WindowEvent; -use winit::event_loop::EventLoop; -use winit::window::WindowBuilder; - +use crate::graphics_engines; use crate::graphics_engines::vulkan::App; const WINDOW_TITLE:&'static str = "MineMod"; +const MODE:GMode = GMode::Vulkan; + +pub enum GMode { + Vulkan, + OpenGL, +} pub fn main() -> Result<()> { super::init_logging(); @@ -30,65 +31,82 @@ pub fn main() -> Result<()> { // Window - let event_loop = EventLoop::new()?; - let window = WindowBuilder::new() - .with_title(WINDOW_TITLE) - .with_inner_size(LogicalSize::new(1024, 768)) - .build(&event_loop)?; + match MODE { + GMode::Vulkan => { + use old_winit::dpi::LogicalSize; + use old_winit::event::Event; + use old_winit::event::WindowEvent; + use old_winit::event_loop::EventLoop; + use old_winit::window::WindowBuilder; - info!("Creating app and starting event loop."); + let event_loop = EventLoop::new()?; + let window = WindowBuilder::new() + .with_title(WINDOW_TITLE) + .with_inner_size(LogicalSize::new(1024, 768)) + .build(&event_loop)?; - // App + info!("Creating app and starting event loop."); - let mut app = unsafe { App::create(&window)? }; - let mut minimized = false; + // App - let shutdown_rx = std::sync::Arc::new(std::sync::Mutex::new(Some(shutdown_rx))); + let mut app = unsafe { App::create(&window)? }; + let mut minimized = false; - event_loop.run(move |event, elwt| { - let mut shutdown_rx_guard = shutdown_rx.lock().unwrap(); + let shutdown_rx = std::sync::Arc::new(std::sync::Mutex::new(Some(shutdown_rx))); - if let Some(receiver) = shutdown_rx_guard.as_mut() { - if receiver.try_recv().is_ok() { - info!("Closing event loop and destroying Vulkan instance."); - elwt.exit(); - unsafe { - app.device.device_wait_idle().unwrap(); - app.destroy(); - } - return; - } - } + event_loop.run(move |event, elwt| { + let mut shutdown_rx_guard = shutdown_rx.lock().unwrap(); - match event { - // Request a redraw when all events were processed. - Event::AboutToWait => window.request_redraw(), - Event::WindowEvent { event, .. } => match event { - // Render a frame if our Vulkan app is not being destroyed. - WindowEvent::RedrawRequested if !elwt.exiting() && !minimized => { - unsafe { app.render(&window) }.unwrap(); - }, - WindowEvent::Resized(size) => - if size.width == 0 || size.height == 0 { - minimized = true; - } else { - minimized = false; - app.resized = true; - }, - // Destroy our Vulkan app. - WindowEvent::CloseRequested => { - info!("Closing event loop and destroying Vulkan instance."); - elwt.exit(); - unsafe { - app.device.device_wait_idle().unwrap(); - app.destroy(); + if let Some(receiver) = shutdown_rx_guard.as_mut() { + if receiver.try_recv().is_ok() { + info!("Closing event loop and destroying Vulkan instance."); + elwt.exit(); + unsafe { + app.device.device_wait_idle().unwrap(); + app.destroy(); + } + return; } - }, - _ => {}, - }, - _ => {}, - } - })?; + } + + match event { + // Request a redraw when all events were processed. + Event::AboutToWait => window.request_redraw(), + Event::WindowEvent { event, .. } => match event { + // Render a frame if our Vulkan app is not being destroyed. + WindowEvent::RedrawRequested if !elwt.exiting() && !minimized => { + unsafe { app.render(&window) }.unwrap(); + }, + WindowEvent::Resized(size) => + if size.width == 0 || size.height == 0 { + minimized = true; + } else { + minimized = false; + app.resized = true; + }, + // Destroy our Vulkan app. + WindowEvent::CloseRequested => { + info!("Closing event loop and destroying Vulkan instance."); + elwt.exit(); + unsafe { + app.device.device_wait_idle().unwrap(); + app.destroy(); + } + }, + _ => {}, + }, + _ => {}, + } + })?; + }, + GMode::OpenGL => { + use winit::event_loop::EventLoop; + + if let Err(err) = graphics_engines::opengl::main(EventLoop::new().unwrap()) { + error!("An error occured in the opengl backend: {err}"); + }; + }, + } info!("Exiting program."); diff --git a/src/main.rs b/src/main.rs index 0c239f0..acb2f9f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] +// #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] #![deny(clippy::unwrap_used)] #![allow( // dead_code, @@ -78,18 +78,18 @@ mod graphics_engines; fn init_logging() { tracing_subscriber::fmt() - .compact() - .with_timer(tracing_subscriber::fmt::time::uptime()) - .with_ansi(true) - .with_level(true) - // .with_thread_ids(true) - .with_thread_names(true) - .with_max_level(if cfg!(debug_assertions) { - tracing::level_filters::LevelFilter::DEBUG - } else { - tracing::level_filters::LevelFilter::INFO - }) - .init(); + .compact() + .with_timer(tracing_subscriber::fmt::time::uptime()) + .with_ansi(true) + .with_level(true) + // .with_thread_ids(true) + .with_thread_names(true) + .with_max_level(if cfg!(debug_assertions) { + tracing::level_filters::LevelFilter::DEBUG + } else { + tracing::level_filters::LevelFilter::INFO + }) + .init(); // pretty_env_logger::init_timed(); } diff --git a/src/vita/mod.rs b/src/vita/mod.rs index 7712921..fb04f96 100644 --- a/src/vita/mod.rs +++ b/src/vita/mod.rs @@ -53,7 +53,7 @@ pub fn main() { std::panic::set_hook(Box::new(custom_panic_hook)); super::init_logging(); - panic!("Vista system target is not supported currently."); + panic!("Vita system target is not supported currently."); // for _ in 0..3 { // raw_rainbow(); diff --git a/src/windows.rs b/src/windows.rs index 2b92962..56c21a7 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -4,22 +4,23 @@ use log::*; use vulkanalia::prelude::v1_0::*; -use winit::dpi::LogicalSize; -use winit::event::Event; -use winit::event::WindowEvent; -use winit::event_loop::EventLoop; -use winit::window::WindowBuilder; - +use crate::graphics_engines; use crate::graphics_engines::vulkan::App; const WINDOW_TITLE:&'static str = "MineMod"; +const MODE:GMode = GMode::Vulkan; + +pub enum GMode { + Vulkan, + OpenGL, +} pub fn main() -> Result<()> { super::init_logging(); info!("Registering CTRLC hook."); - let (shutdown_tx, shutdown_rx) = std::sync::mpsc::channel::<()>(); + let (shutdown_tx, shutdown_rx) = std::sync::mpsc::channel(); ctrlc::set_handler(move || { shutdown_tx.send(()).expect("Failed to send shutdown signal"); @@ -30,65 +31,82 @@ pub fn main() -> Result<()> { // Window - let event_loop = EventLoop::new()?; - let window = WindowBuilder::new() - .with_title(WINDOW_TITLE) - .with_inner_size(LogicalSize::new(1024, 768)) - .build(&event_loop)?; + match MODE { + GMode::Vulkan => { + use old_winit::dpi::LogicalSize; + use old_winit::event::Event; + use old_winit::event::WindowEvent; + use old_winit::event_loop::EventLoop; + use old_winit::window::WindowBuilder; - info!("Creating app and starting event loop."); + let event_loop = EventLoop::new()?; + let window = WindowBuilder::new() + .with_title(WINDOW_TITLE) + .with_inner_size(LogicalSize::new(1024, 768)) + .build(&event_loop)?; - // App + info!("Creating app and starting event loop."); - let mut app = unsafe { App::create(&window)? }; - let mut minimized = false; + // App - let shutdown_rx = std::sync::Arc::new(std::sync::Mutex::new(Some(shutdown_rx))); + let mut app = unsafe { App::create(&window)? }; + let mut minimized = false; - event_loop.run(move |event, elwt| { - let mut shutdown_rx_guard = shutdown_rx.lock().unwrap(); + let shutdown_rx = std::sync::Arc::new(std::sync::Mutex::new(Some(shutdown_rx))); - if let Some(receiver) = shutdown_rx_guard.as_mut() { - if receiver.try_recv().is_ok() { - info!("Closing event loop and destroying Vulkan instance."); - elwt.exit(); - unsafe { - app.device.device_wait_idle().unwrap(); - app.destroy(); - } - return; - } - } + event_loop.run(move |event, elwt| { + let mut shutdown_rx_guard = shutdown_rx.lock().unwrap(); - match event { - // Request a redraw when all events were processed. - Event::AboutToWait => window.request_redraw(), - Event::WindowEvent { event, .. } => match event { - // Render a frame if our Vulkan app is not being destroyed. - WindowEvent::RedrawRequested if !elwt.exiting() && !minimized => { - unsafe { app.render(&window) }.unwrap(); - }, - WindowEvent::Resized(size) => - if size.width == 0 || size.height == 0 { - minimized = true; - } else { - minimized = false; - app.resized = true; - }, - // Destroy our Vulkan app. - WindowEvent::CloseRequested => { - info!("Closing event loop and destroying Vulkan instance."); - elwt.exit(); - unsafe { - app.device.device_wait_idle().unwrap(); - app.destroy(); + if let Some(receiver) = shutdown_rx_guard.as_mut() { + if receiver.try_recv().is_ok() { + info!("Closing event loop and destroying Vulkan instance."); + elwt.exit(); + unsafe { + app.device.device_wait_idle().unwrap(); + app.destroy(); + } + return; } - }, - _ => {}, - }, - _ => {}, - } - })?; + } + + match event { + // Request a redraw when all events were processed. + Event::AboutToWait => window.request_redraw(), + Event::WindowEvent { event, .. } => match event { + // Render a frame if our Vulkan app is not being destroyed. + WindowEvent::RedrawRequested if !elwt.exiting() && !minimized => { + unsafe { app.render(&window) }.unwrap(); + }, + WindowEvent::Resized(size) => + if size.width == 0 || size.height == 0 { + minimized = true; + } else { + minimized = false; + app.resized = true; + }, + // Destroy our Vulkan app. + WindowEvent::CloseRequested => { + info!("Closing event loop and destroying Vulkan instance."); + elwt.exit(); + unsafe { + app.device.device_wait_idle().unwrap(); + app.destroy(); + } + }, + _ => {}, + }, + _ => {}, + } + })?; + }, + GMode::OpenGL => { + use winit::event_loop::EventLoop; + + if let Err(err) = graphics_engines::opengl::main(EventLoop::new().unwrap()) { + error!("An error occured in the opengl backend: {err}"); + }; + }, + } info!("Exiting program.");