diff --git a/Cargo.lock b/Cargo.lock index 81c851e..2e3b91a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,6 +44,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "aho-corasick" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +dependencies = [ + "memchr", +] + [[package]] name = "android-activity" version = "0.4.2" @@ -134,12 +143,6 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" -[[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" @@ -188,12 +191,20 @@ name = "bytemuck" version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +dependencies = [ + "bytemuck_derive", +] [[package]] -name = "byteorder" -version = "1.4.3" +name = "bytemuck_derive" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "fdde5c9cd29ebd706ce1b35600920a33550e402fc998a2e53ad3b42c3c47a192" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.26", +] [[package]] name = "calloop" @@ -240,12 +251,6 @@ 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 = "com-rs" version = "0.2.1" @@ -301,55 +306,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset 0.9.0", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "d3d12" version = "0.6.0" @@ -383,31 +339,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] -name = "either" -version = "1.8.1" +name = "env_logger" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] [[package]] name = "equivalent" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] -name = "exr" -version = "1.7.0" +name = "errno" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1e481eb11a482815d3e9d618db8c42a93207134662873809335a92327440c18" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ - "bit_field", - "flume", - "half", - "lebe", - "miniz_oxide", - "rayon-core", - "smallvec", - "zune-inflate", + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", ] [[package]] @@ -429,19 +397,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "flume" -version = "0.10.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" -dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "pin-project", - "spin", -] - [[package]] name = "foreign-types" version = "0.3.2" @@ -457,18 +412,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -[[package]] -name = "futures-core" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" - -[[package]] -name = "futures-sink" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" - [[package]] name = "getrandom" version = "0.2.10" @@ -476,20 +419,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", -] - -[[package]] -name = "gif" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" -dependencies = [ - "color_quant", - "weezl", ] [[package]] @@ -562,15 +493,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "half" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" -dependencies = [ - "crunchy", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -614,23 +536,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] -name = "image" -version = "0.24.6" +name = "humantime" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" -dependencies = [ - "bytemuck", - "byteorder", - "color_quant", - "exr", - "gif", - "jpeg-decoder", - "num-rational", - "num-traits", - "png", - "qoi", - "tiff", -] +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "indexmap" @@ -664,6 +573,17 @@ dependencies = [ "web-sys", ] +[[package]] +name = "is-terminal" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +dependencies = [ + "hermit-abi", + "rustix", + "windows-sys 0.48.0", +] + [[package]] name = "jni-sys" version = "0.3.0" @@ -679,15 +599,6 @@ dependencies = [ "libc", ] -[[package]] -name = "jpeg-decoder" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" -dependencies = [ - "rayon", -] - [[package]] name = "js-sys" version = "0.3.64" @@ -714,12 +625,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[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.147" @@ -746,6 +651,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" + [[package]] name = "lock_api" version = "0.4.10" @@ -795,15 +706,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "metal" version = "0.24.0" @@ -866,15 +768,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom", -] - [[package]] name = "ndk" version = "0.7.0" @@ -913,7 +806,7 @@ dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", - "memoffset 0.6.5", + "memoffset", ] [[package]] @@ -926,7 +819,7 @@ dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", - "memoffset 0.6.5", + "memoffset", ] [[package]] @@ -939,27 +832,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -969,16 +841,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "num_enum" version = "0.5.11" @@ -1018,7 +880,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] @@ -1128,40 +990,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" -[[package]] -name = "pin-project" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.25", -] - -[[package]] -name = "pixels" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ba8189b31db4f12fbf0d4a8eab2d7d7343a504a8d8a7ea4b14ffb2e6129136a" -dependencies = [ - "bytemuck", - "pollster", - "raw-window-handle", - "thiserror", - "ultraviolet", - "wgpu", -] - [[package]] name = "pkg-config" version = "0.3.27" @@ -1212,15 +1040,6 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "332cd62e95873ea4f41f3dfd6bbbfc5b52aec892d7e8d534197c4720a0bbbab2" -[[package]] -name = "qoi" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" -dependencies = [ - "bytemuck", -] - [[package]] name = "quote" version = "1.0.29" @@ -1243,36 +1062,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" [[package]] -name = "rayon" -version = "1.7.0" +name = "redox_syscall" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "either", - "rayon-core", + "bitflags 1.3.2", ] [[package]] -name = "rayon-core" -version = "1.11.0" +name = "regex" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", ] [[package]] -name = "redox_syscall" -version = "0.3.5" +name = "regex-automata" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" dependencies = [ - "bitflags 1.3.2", + "aho-corasick", + "memchr", + "regex-syntax", ] +[[package]] +name = "regex-syntax" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" + [[package]] name = "renderdoc-sys" version = "1.0.0" @@ -1292,12 +1118,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] -name = "safe_arch" -version = "0.7.0" +name = "rustix" +version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62a7484307bd40f8f7ccbacccac730108f2cae119a3b11c74485b48aa9ea650f" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" dependencies = [ - "bytemuck", + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1365,15 +1195,6 @@ dependencies = [ "wayland-protocols", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - [[package]] name = "spirv" version = "0.2.0+1.5.4" @@ -1409,9 +1230,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.25" +version = "2.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e3fc8c0c74267e2df136e5e5fb656a464158aa57624053375eb9c8c6e25ae2" +checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" dependencies = [ "proc-macro2", "quote", @@ -1444,18 +1265,19 @@ checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", ] [[package]] -name = "tiff" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" +name = "threedee" +version = "0.1.0" dependencies = [ - "flate2", - "jpeg-decoder", - "weezl", + "bytemuck", + "env_logger", + "log", + "pollster", + "wgpu", + "winit", ] [[package]] @@ -1491,9 +1313,9 @@ checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" [[package]] name = "toml_edit" -version = "0.19.12" +version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ "indexmap 2.0.0", "toml_datetime", @@ -1506,30 +1328,11 @@ version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a464a4b34948a5f67fddd2b823c62d9d92e44be75058b99939eae6c5b6960b33" -[[package]] -name = "twoderaycaster" -version = "0.1.0" -dependencies = [ - "image", - "pixels", - "winit", - "winit_input_helper", -] - -[[package]] -name = "ultraviolet" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0b28b9a6ce66d47e3c5666aa738c5ec5223fcdd4c263f3edc98ab6fef618b3" -dependencies = [ - "wide", -] - [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-width" @@ -1582,7 +1385,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", "wasm-bindgen-shared", ] @@ -1616,7 +1419,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.25", + "syn 2.0.26", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1710,12 +1513,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "weezl" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" - [[package]] name = "wgpu" version = "0.16.2" @@ -1816,16 +1613,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "wide" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40018623e2dba2602a9790faba8d33f2ebdebf4b86561b83928db735f8784728" -dependencies = [ - "bytemuck", - "safe_arch", -] - [[package]] name = "widestring" version = "1.0.2" @@ -2039,20 +1826,11 @@ dependencies = [ "x11-dl", ] -[[package]] -name = "winit_input_helper" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de0485e86aa2ee87d2d4c373a908c9548357bc65c5bce19fd884c8ea9eac4d7" -dependencies = [ - "winit", -] - [[package]] name = "winnow" -version = "0.4.9" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" +checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" dependencies = [ "memchr", ] @@ -2082,12 +1860,3 @@ name = "xml-rs" version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a56c84a8ccd4258aed21c92f70c0f6dea75356b6892ae27c24139da456f9336" - -[[package]] -name = "zune-inflate" -version = "0.2.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" -dependencies = [ - "simd-adler32", -] diff --git a/Cargo.toml b/Cargo.toml index 3b09aae..bfa60ab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,14 @@ [package] -name = "twoderaycaster" +name = "threedee" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -image = "0.24.6" -pixels = "0.13.0" -winit = "0.28.6" -winit_input_helper = "0.14.1" +winit = "0.28" +env_logger = "0.10" +log = "0.4" +wgpu = "0.16" +pollster = "0.3.0" +bytemuck = { version = "1.13.1", features = ["derive"] } diff --git a/README.md b/README.md index 8b4f3e4..652d5da 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# twodee raycaster -A very basic 2D raycaster built with Rust +# 3D Graphics Engine +Basic Graphics Engine built with `wgpu` in Rust -![Demo picture](https://github.com/manorajesh/twodeeraycaster/blob/master/images/demo.png) +![Demo picture](https://github.com/manorajesh/rusty-graphics/blob/wgpu/images/demo.png) ## Installation ``` -git clone https://github.com/manorajesh/twodeeraycaster.git && cd twodeeraycaster +git clone https://github.com/manorajesh/rusty-graphics.git && cd rusty-graphics cargo run ``` @@ -13,4 +13,4 @@ cargo run Use the arrow keys to traverse the extremely entertaining room and watch the shadows #### Important Code -The [`draw`](https://github.com/manorajesh/twodeeraycaster/blob/cdf31fba1238801ae4804fe2ce98fec9d935985d/src/raycaster.rs#L147-L207) function is responsible for casting the rays and rendering them accordingly. +The [`draw`](https://github.com/manorajesh/rusty-graphics/blob/cdf31fba1238801ae4804fe2ce98fec9d935985d/src/raycaster.rs#L147-L207) function is responsible for casting the rays and rendering them accordingly. diff --git a/assets/map.png b/assets/map.png deleted file mode 100644 index 7b43fb3..0000000 Binary files a/assets/map.png and /dev/null differ diff --git a/images/demo.png b/images/demo.png index 9b95141..6a52b93 100644 Binary files a/images/demo.png and b/images/demo.png differ diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..bebe6b1 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,333 @@ +use wgpu::util::DeviceExt; +use winit::{ + event::*, + event_loop::{ControlFlow, EventLoop}, + window::{WindowBuilder, Window}, +}; +use bytemuck; + +struct State { + surface: wgpu::Surface, + device: wgpu::Device, + queue: wgpu::Queue, + config: wgpu::SurfaceConfiguration, + size: winit::dpi::PhysicalSize, + window: Window, + render_pipeline: wgpu::RenderPipeline, + vertex_buffer: wgpu::Buffer, + num_vertices: u32, + index_buffer: wgpu::Buffer, + num_indices: u32, +} + +impl State { + // Creating some of the wgpu types requires async code + async fn new(window: Window) -> Self { + let size = window.inner_size(); + + // The instance is a handle to our GPU + // Backends::all => Vulkan + Metal + DX12 + Browser WebGPU + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { + backends: wgpu::Backends::all(), + dx12_shader_compiler: Default::default(), + }); + + // # Safety + // + // The surface needs to live as long as the window that created it. + // State owns the window so this should be safe. + let surface = unsafe { instance.create_surface(&window) }.unwrap(); + + let adapter = instance.request_adapter( + &wgpu::RequestAdapterOptions { + power_preference: wgpu::PowerPreference::default(), + compatible_surface: Some(&surface), + force_fallback_adapter: false, + }, + ).await.unwrap(); + + let (device, queue) = adapter.request_device( + &wgpu::DeviceDescriptor { + features: wgpu::Features::empty(), + // WebGL doesn't support all of wgpu's features, so if + // we're building for the web we'll have to disable some. + limits: wgpu::Limits::default(), + label: None, + }, + None, // Trace path + ).await.unwrap(); + + let surface_caps = surface.get_capabilities(&adapter); + // Shader code in this tutorial assumes an sRGB surface texture. Using a different + // one will result all the colors coming out darker. If you want to support non + // sRGB surfaces, you'll need to account for that when drawing to the frame. + let surface_format = surface_caps.formats.iter() + .copied() + .find(|f| f.is_srgb()) + .unwrap_or(surface_caps.formats[0]); + let config = wgpu::SurfaceConfiguration { + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + format: surface_format, + width: size.width, + height: size.height, + present_mode: surface_caps.present_modes[0], + alpha_mode: surface_caps.alpha_modes[0], + view_formats: vec![], + }; + surface.configure(&device, &config); + + // Configuring render pipeline with shader code + let shader = device.create_shader_module(wgpu::include_wgsl!("shader.wgsl")); + let render_pipeline_layout = + device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("Render Pipeline Layout"), + bind_group_layouts: &[], + push_constant_ranges: &[], + }); + let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("Render Pipeline"), + layout: Some(&render_pipeline_layout), + vertex: wgpu::VertexState { + module: &shader, + entry_point: "vs_main", + buffers: &[ + Vertex::desc(), + ], + }, + fragment: Some(wgpu::FragmentState { + module: &shader, + entry_point: "fs_main", + targets: &[Some(wgpu::ColorTargetState { + format: config.format, + blend: Some(wgpu::BlendState::REPLACE), + write_mask: wgpu::ColorWrites::ALL, + })], + }), + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleList, + strip_index_format: None, + front_face: wgpu::FrontFace::Ccw, + cull_mode: Some(wgpu::Face::Back), + // Setting this to anything other than Fill requires Features::NON_FILL_POLYGON_MODE + polygon_mode: wgpu::PolygonMode::Fill, + // Requires Features::DEPTH_CLIP_CONTROL + unclipped_depth: false, + // Requires Features::CONSERVATIVE_RASTERIZATION + conservative: false, + }, + depth_stencil: None, + multisample: wgpu::MultisampleState { + count: 1, + mask: !0, + alpha_to_coverage_enabled: false, + }, + multiview: None, + }); + + // Creating vertex buffer + let vertex_buffer = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(VERTICES), + usage: wgpu::BufferUsages::VERTEX, + } + ); + let num_vertices = VERTICES.len() as u32; + + // Create index buffer for better memory use + let index_buffer = device.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Index Buffer"), + contents: bytemuck::cast_slice(INDICES), + usage: wgpu::BufferUsages::INDEX, + } + ); + let num_indices = INDICES.len() as u32; + + Self { + window, + surface, + device, + queue, + config, + size, + render_pipeline, + vertex_buffer, + num_vertices, + index_buffer, + num_indices, + } + } + + pub fn window(&self) -> &Window { + &self.window + } + + pub fn resize(&mut self, new_size: winit::dpi::PhysicalSize) { + if new_size.width > 0 && new_size.height > 0 { + self.size = new_size; + self.config.width = new_size.width; + self.config.height = new_size.height; + self.surface.configure(&self.device, &self.config); + } + } + + fn input(&mut self, _event: &WindowEvent) -> bool { + false + } + + fn update(&mut self) { + // todo!() + } + + fn render(&mut self, color: [f64; 4]) -> Result<(), wgpu::SurfaceError> { + let output = self.surface.get_current_texture()?; + let view = output.texture.create_view(&wgpu::TextureViewDescriptor::default()); + let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { + label: Some("Render Encoder"), + }); + + { + let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: Some("Render Pass"), + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: &view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color { + r: color[0], + g: color[1], + b: color[2], + a: color[3], + }), + store: true, + }, + })], + depth_stencil_attachment: None, + }); + + render_pass.set_pipeline(&self.render_pipeline); + render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); + render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16); + render_pass.draw_indexed(0..self.num_indices, 0, 0..1); + } + + // submit will accept anything that implements IntoIter + self.queue.submit(std::iter::once(encoder.finish())); + output.present(); + + Ok(()) + + } +} + +#[repr(C)] +#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] +struct Vertex { + position: [f32; 3], + color: [f32; 3], +} + +impl Vertex { + fn desc() -> wgpu::VertexBufferLayout<'static> { + wgpu::VertexBufferLayout { + array_stride: std::mem::size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &[ + wgpu::VertexAttribute { + offset: 0, + shader_location: 0, + format: wgpu::VertexFormat::Float32x3, + }, + wgpu::VertexAttribute { + offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress, + shader_location: 1, + format: wgpu::VertexFormat::Float32x3, + } + ] + } + } +} + +const VERTICES: &[Vertex] = &[ + Vertex { position: [-0.0868241, 0.49240386, 0.0], color: [0.5, 0.0, 0.5] }, + Vertex { position: [-0.49513406, 0.06958647, 0.0], color: [0.5, 0.0, 0.5] }, + Vertex { position: [-0.21918549, -0.44939706, 0.0], color: [0.5, 0.0, 0.5] }, + Vertex { position: [0.35966998, -0.3473291, 0.0], color: [0.5, 0.0, 0.5] }, + Vertex { position: [0.44147372, 0.2347359, 0.0], color: [0.5, 0.0, 0.5] }, +]; + +const INDICES: &[u16] = &[ + 0, 1, 4, + 1, 2, 4, + 2, 3, 4, +]; + +pub async fn run() { + env_logger::init(); + let event_loop = EventLoop::new(); + let window = WindowBuilder::new().build(&event_loop).unwrap(); + + let mut state = State::new(window).await; + let mut color = [0.0, 0.0, 0.0, 1.0]; + + event_loop.run(move |event, _, control_flow| { + match event { + Event::RedrawRequested(window_id) if window_id == state.window().id() => { + state.update(); + match state.render(color) { + Ok(_) => {} + // Reconfigure the surface if lost + Err(wgpu::SurfaceError::Lost) => state.resize(state.size), + // The system is out of memory, we should probably quit + Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit, + // All other errors (Outdated, Timeout) should be resolved by the next frame + Err(e) => eprintln!("{:?}", e), + } + } + Event::MainEventsCleared => { + // RedrawRequested will only trigger once, unless we manually + // request it. + state.window().request_redraw(); + } + + Event::WindowEvent { + ref event, + window_id, + } if window_id == state.window().id() => if !state.input(event) { // UPDATED! + match event { + WindowEvent::CloseRequested + | WindowEvent::KeyboardInput { + input: + KeyboardInput { + state: ElementState::Pressed, + virtual_keycode: Some(VirtualKeyCode::Escape), + .. + }, + .. + } => *control_flow = ControlFlow::Exit, + + WindowEvent::Resized(physical_size) => { + state.resize(*physical_size); + } + + WindowEvent::ScaleFactorChanged { new_inner_size, .. } => { + state.resize(**new_inner_size); + } + + WindowEvent::CursorMoved { position, .. } => { + color = [ + position.x / state.size.width as f64, + position.y / state.size.height as f64, + position.x / state.size.width as f64, + 1.0, + ]; + } + _ => {} + } + } + _ => {} + } + }); +} + diff --git a/src/main.rs b/src/main.rs index 2b2c348..0ba5a3a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,186 +1,6 @@ -use pixels::Error; -use winit::{ - event::{DeviceEvent, Event, VirtualKeyCode, WindowEvent}, - event_loop::EventLoop, -}; -use winit_input_helper::WinitInputHelper; +use threedee::run; +use pollster; -mod raycaster; -mod vector; -mod window; - -pub const WIDTH: u32 = 3840; -pub const HEIGHT: u32 = 2160; -pub const SCALEFACTOR: u32 = 2; - -pub static mut ACCELERATION: f64 = 0.1; - -fn main() -> Result<(), Error> { - let mut input = WinitInputHelper::new(); - - let event_loop = EventLoop::new(); - let mut gw = window::GameWindow::new("2D Raycaster", &event_loop)?; - let mut raycaster = raycaster::RayCaster::new(60.); - let mut map_toggle = false; - - event_loop.run(move |event, _, control_flow| { - match event { - Event::RedrawRequested(_) => { - let now = std::time::Instant::now(); - // println!("Redraw requested"); - let frame = gw.pixels.frame_mut(); - - // Clear the frame - for pixel in frame.chunks_exact_mut(4) { - pixel.copy_from_slice(&[0, 0, 0, 0]); // Set every pixel to black - } - - raycaster.update_player(); - - raycaster.draw(frame, map_toggle).unwrap(); - gw.pixels.render().unwrap(); - let elapsed = now.elapsed().as_millis(); - println!("FPS: {}", 1000 / elapsed) - } - - Event::WindowEvent { - event: WindowEvent::CloseRequested, - .. - } => { - // println!("Window closed"); - *control_flow = winit::event_loop::ControlFlow::Exit; - } - - Event::WindowEvent { - event: WindowEvent::Resized(size), - .. - } => { - println!("Window resized to {:?}", size); - gw.resize((size.width, size.height)); - } - - Event::DeviceEvent { - event: DeviceEvent::MouseMotion { delta }, - .. - } => raycaster.change_direction(raycaster::Direction::Mouse(delta.0, delta.1)), - - _ => {} - } - - if input.update(&event) { - if input.held_shift() { - unsafe { - ACCELERATION = 0.5; - } - } else { - unsafe { - ACCELERATION = 0.1; - } - } - - if input.key_held(VirtualKeyCode::W) { - raycaster.change_direction(raycaster::Direction::Up) - } - - if input.key_held(VirtualKeyCode::S) { - raycaster.change_direction(raycaster::Direction::Down) - } - - if input.key_held(VirtualKeyCode::A) { - raycaster.change_direction(raycaster::Direction::Left) - } - - if input.key_held(VirtualKeyCode::D) { - raycaster.change_direction(raycaster::Direction::Right) - } - - if input.key_pressed(VirtualKeyCode::M) { - map_toggle = !map_toggle; - } - } - - gw.window.request_redraw(); - }); -} - -fn verline(frame: &mut [u8], x: usize, y1: usize, y2: usize, rgba: [u8; 4], scale: usize) { - for y in (y1 * scale)..=(y2 * scale) { - set_pixel(frame, x, y, rgba, scale); - } -} - -pub fn line( - frame: &mut [u8], - x1: isize, - y1: isize, - x2: isize, - y2: isize, - color: [u8; 4], - scale: usize, -) { - if x1 == x2 { - verline(frame, x1 as usize, y1 as usize, y2 as usize, color, scale); - return; - } - let dx = isize::abs(x2 - x1) * scale as isize; - let sx = if x1 < x2 { 1 } else { -1 }; - let dy = -isize::abs(y2 - y1) * scale as isize; - let sy = if y1 < y2 { 1 } else { -1 }; - let mut err = dx + dy; - let mut x = x1 * scale as isize; - let mut y = y1 * scale as isize; - - loop { - set_pixel(frame, x as usize, y as usize, color, scale); - - if x == x2 * scale as isize && y == y2 * scale as isize { - break; - } - - let e2 = 2 * err; - - if e2 >= dy { - err += dy; - x += sx * scale as isize; - } - - if e2 <= dx { - err += dx; - y += sy * scale as isize; - } - } -} - -fn filled_rectangle( - frame: &mut [u8], - x1: usize, - y1: usize, - x2: usize, - y2: usize, - color: [u8; 4], - scale: usize, -) { - for x in (x1 * scale)..=(x2 * scale) { - for y in (y1 * scale)..=(y2 * scale) { - if x >= WIDTH as usize || y >= HEIGHT as usize { - continue; - } - set_pixel(frame, x, y, color, scale); - } - } -} - -pub fn set_pixel(frame: &mut [u8], x: usize, y: usize, color: [u8; 4], scale: usize) { - for i in 0..scale { - for j in 0..scale { - let xi = x * scale + i; - let yj = y * scale + j; - if xi < WIDTH as usize && yj < HEIGHT as usize { - let index = (yj * WIDTH as usize + xi) * 4; - if index + 4 <= frame.len() { - frame[index..index + 4].copy_from_slice(&color); - } - } - } - } -} +fn main() { + pollster::block_on(run()); +} \ No newline at end of file diff --git a/src/raycaster.rs b/src/raycaster.rs deleted file mode 100644 index a927f75..0000000 --- a/src/raycaster.rs +++ /dev/null @@ -1,347 +0,0 @@ -use crate::{line, set_pixel, vector::Vector, verline, ACCELERATION, HEIGHT, WIDTH}; - -pub struct RayCaster { - player: Player, - map: Vec>, - fov: f64, -} - -struct Ray { - dir: Vector, - hit: bool, -} - -struct Player { - pub pos: Vector, - pub dir: Vector, - pub vel: Vector, -} - -pub enum Direction { - Up, - Down, - Left, - Right, - Mouse(f64, f64), -} - -#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] -struct MapCell { - pub color: [u8; 4], - pub solid: MapCellType, - pub height: f64, -} - -#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] -enum MapCellType { - Empty, - Wall, -} - -impl MapCell { - pub fn new(color: [u8; 4], solid: MapCellType, height: f64) -> Self { - Self { - color, - solid, - height, - } - } - - pub fn empty() -> Self { - Self { - color: [0, 0, 0, 0], - solid: MapCellType::Empty, - height: 0.0, - } - } -} - -impl RayCaster { - pub fn new(fov: f64) -> Self { - Self { - player: Player { - pos: Vector { x: 22.0, y: 12.0 }, - dir: Vector { x: -1.0, y: 0.0 }, - vel: Vector { x: 0., y: 0. }, - }, - - map: generate_map(), - - // map: [ - // [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], - // [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,0,0,0,0,0,2,2,2,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1], - // [1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,3,0,0,0,3,0,0,0,1], - // [1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,0,0,0,0,0,2,2,0,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1], - // [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,4,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,4,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], - // [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] - // ], - fov, - } - } - - pub fn draw(&self, frame: &mut [u8], map_toggle: bool) -> Result<(), String> { - if map_toggle { - // map - for y in 0..self.map.len() { - for x in 0..self.map[y].len() { - let cell = self.map[y][x]; - - set_pixel(frame, x, y, cell.color, 1); - // filled_rectangle(frame, x, y, x+1, y+2, color, PIXELSIZE) - } - } - - set_pixel( - frame, - self.player.pos.x as usize, - self.player.pos.y as usize, - [25, 0, 255, 255], - 1, - ); - line( - frame, - self.player.pos.x as isize, - self.player.pos.y as isize, - (self.player.pos.x + self.player.dir.x * 10.) as isize, - (self.player.pos.y + self.player.dir.y * 10.) as isize, - [255, 0, 0, 255], - 1, - ); - - // orthogonal line - line( - frame, - self.player.pos.x as isize, - self.player.pos.y as isize, - (self.player.pos.x + self.player.dir.orthogonal(Direction::Left).x * 10.) as isize, - (self.player.pos.y + self.player.dir.orthogonal(Direction::Left).y * 10.) as isize, - [0, 255, 0, 255], - 1, - ); - line( - frame, - self.player.pos.x as isize, - self.player.pos.y as isize, - (self.player.pos.x + self.player.dir.orthogonal(Direction::Right).x * 10.) as isize, - (self.player.pos.y + self.player.dir.orthogonal(Direction::Right).y * 10.) as isize, - [0, 0, 255, 255], - 1, - ); - return Ok(()); - } - - // raycasting - let half_fov: f64 = self.fov / 2.; - const NUMRAYS: f64 = WIDTH as f64; - for i in 0..NUMRAYS as usize { - let angle = (self.fov / NUMRAYS * i as f64 - half_fov) * 1f64.to_radians(); - let mut ray = Ray { - dir: self.player.dir.rotate(angle), - hit: false, - }; - - // map_pos is the current map cell we are in - let mut map_pos: Vector = Vector::new( - self.player.pos.x.floor() as i32, - self.player.pos.y.floor() as i32, - ); - - // delta of ray to next map cell - let delta_dist = Vector { - x: (1.0 / ray.dir.x).abs(), - y: (1.0 / ray.dir.y).abs(), - }; - - // step direction for map_pos - let step = Vector { - x: if ray.dir.x < 0. { -1. } else { 1. }, - y: if ray.dir.y < 0. { -1. } else { 1. }, - }; - - // ray distance from side of map cell (helps with determining direction to inc) - let mut side_dist: Vector = Vector { - x: if ray.dir.x < 0. { - // top left edge of map cell - (self.player.pos.x - map_pos.x as f64) * delta_dist.x - } else { - // top right edge of map cell - (map_pos.x as f64 + 1. - self.player.pos.x) * delta_dist.x - }, - - y: if ray.dir.y < 0. { - // top left edge of map cell - (self.player.pos.y - map_pos.y as f64) * delta_dist.y - } else { - // top right edge of map cell - (map_pos.y as f64 + 1. - self.player.pos.y) * delta_dist.y - }, - }; - - // DDA - let mut side = 0; - while !ray.hit { - if side_dist.x < side_dist.y { - side_dist.x += delta_dist.x; - map_pos.x += step.x as i32; - side = 0; - } else { - side_dist.y += delta_dist.y; - map_pos.y += step.y as i32; - side = 1; - } - - if self.map[map_pos.y as usize][map_pos.x as usize].solid != MapCellType::Empty { - ray.hit = true; - } - } - - let mut cell = self.map[map_pos.y as usize][map_pos.x as usize]; - - if side == 1 { - cell.color.div_assign(2) - } - - let distance: f64 = if side == 0 { - (map_pos.x as f64 - self.player.pos.x + (1. - step.x) / 2.) / ray.dir.x - } else { - (map_pos.y as f64 - self.player.pos.y + (1. - step.y) / 2.) / ray.dir.y - }; - - let correct_distance = distance * (self.player.dir.angle() - ray.dir.angle()).cos(); - - // fog - cell.color.mul_assign(1. / (1. + correct_distance * correct_distance * 0.0001)); - - let mut height = (HEIGHT as f64 / correct_distance).abs() * 15.; - if height > HEIGHT as f64 { - height = HEIGHT as f64; - } - - let column_start = HEIGHT as usize / 2 - height as usize / 2; - let column_end = HEIGHT as usize / 2 + height as usize / 2; - verline(frame, i, column_start, column_end, cell.color, 1); - } - Ok(()) - } - - pub fn update_player(&mut self) { - let new_pos_x = Vector::new(self.player.pos.x + self.player.vel.x, self.player.pos.y); - if self.is_valid_position(&new_pos_x) { - self.player.pos = new_pos_x; - } - - let new_pos_y = Vector::new(self.player.pos.x, self.player.pos.y + self.player.vel.y); - if self.is_valid_position(&new_pos_y) { - self.player.pos = new_pos_y; - } - - self.player.vel *= 0.8; - } - - fn is_valid_position(&self, pos: &Vector) -> bool { - if let Some(row) = self.map.get(pos.y as usize) { - if let Some(cell) = row.get(pos.x as usize) { - if cell.solid == MapCellType::Empty { - return true; - } - } - } - - false - } - - pub fn change_direction(&mut self, dir: Direction) { - const ROTATESPEED: f64 = 0.001; - let acceleration = unsafe { ACCELERATION }; - - match dir { - Direction::Down => { - self.player.vel.x -= self.player.dir.x * acceleration; - self.player.vel.y -= self.player.dir.y * acceleration; - } - Direction::Up => { - self.player.vel.x += self.player.dir.x * acceleration; - self.player.vel.y += self.player.dir.y * acceleration; - } - Direction::Left => { - let ortho = self.player.dir.orthogonal(Direction::Left); - self.player.vel.x -= ortho.x * acceleration; - self.player.vel.y -= ortho.y * acceleration; - } - Direction::Right => { - let ortho = self.player.dir.orthogonal(Direction::Right); - self.player.vel.x -= ortho.x * acceleration; - self.player.vel.y -= ortho.y * acceleration; - } - Direction::Mouse(dx, _) => { - self.player.dir = self.player.dir.rotate(dx * ROTATESPEED); - } - } - } -} - -trait MulAssign { - fn mul_assign(&mut self, rhs: f64); -} - -impl MulAssign for [u8; 4] { - fn mul_assign(&mut self, rhs: f64) { - self[0] = (self[0] as f64 * rhs) as u8; - self[1] = (self[1] as f64 * rhs) as u8; - self[2] = (self[2] as f64 * rhs) as u8; - self[3] = (self[3] as f64 * rhs) as u8; - } -} - -trait DivAssign { - fn div_assign(&mut self, rhs: u8); -} - -impl DivAssign for [u8; 4] { - fn div_assign(&mut self, rhs: u8) { - self[0] /= rhs; - self[1] /= rhs; - self[2] /= rhs; - self[3] /= rhs; - } -} - -fn generate_map() -> Vec> { - let img = image::open("assets/map.png").unwrap(); - let img = img.to_rgba8(); - let (width, height) = img.dimensions(); - - let mut buffer: Vec> = vec![vec![MapCell::empty(); width as usize]; height as usize]; - - for y in 0..height { - for x in 0..width { - let pixel = img.get_pixel(x, y).0; - let solid = if pixel == [0, 0, 0, 0] { - MapCellType::Empty - } else { - MapCellType::Wall - }; - buffer[y as usize][x as usize] = MapCell::new(pixel, solid, 0.); - } - } - - buffer -} \ No newline at end of file diff --git a/src/shader.wgsl b/src/shader.wgsl new file mode 100644 index 0000000..21b7d7d --- /dev/null +++ b/src/shader.wgsl @@ -0,0 +1,24 @@ +struct VertexInput { + @location(0) position: vec3, + @location(1) color: vec3, +} + +struct VertexOutput { + @builtin(position) clip_position: vec4, + @location(1) color: vec3, +}; + +@vertex +fn vs_main( + model: VertexInput, +) -> VertexOutput { + var out: VertexOutput; + out.color = model.color; + out.clip_position = vec4(model.position, 1.0); + return out; +} + +@fragment +fn fs_main(in: VertexOutput) -> @location(0) vec4 { + return vec4(in.color, 1.0); +} \ No newline at end of file diff --git a/src/vector.rs b/src/vector.rs deleted file mode 100644 index be2d1b4..0000000 --- a/src/vector.rs +++ /dev/null @@ -1,134 +0,0 @@ -use crate::raycaster::Direction; - -#[derive(Clone, Copy, PartialEq, PartialOrd)] -pub struct Vector { - pub x: T, - pub y: T, -} - -impl Vector { - pub fn new(x: T, y: T) -> Self { - Self { x, y } - } - - pub fn rotate(&self, angle: f64) -> Vector - where - T: Into + From + Copy, - { - let x = self.x.into(); - let y = self.y.into(); - - let new_x = (x * angle.cos() - y * angle.sin()).into(); - let new_y = (x * angle.sin() + y * angle.cos()).into(); - - Vector::new(new_x, new_y) - } - - pub fn angle(&self) -> f64 - where - T: Into + From + Copy, - { - let x = self.x.into(); - let y = self.y.into(); - y.atan2(x) - } - - pub fn orthogonal(&self, dir: Direction) -> Self - where - T: std::ops::Neg + Copy, - { - match dir { - Direction::Right => Vector::new(self.y, -self.x), - Direction::Left => Vector::new(-self.y, self.x), - _ => panic!("Invalid direction"), - } - } -} - -impl std::ops::Add for Vector -where - T: std::ops::Add, -{ - type Output = Self; - - fn add(self, rhs: Self) -> Self::Output { - Self { - x: self.x + rhs.x, - y: self.y + rhs.y, - } - } -} - -impl std::ops::AddAssign for Vector -where - T: std::ops::AddAssign, -{ - fn add_assign(&mut self, rhs: Self) { - self.x += rhs.x; - self.y += rhs.y; - } -} - -impl std::ops::AddAssign for Vector -where - T: std::ops::AddAssign + Copy, -{ - fn add_assign(&mut self, rhs: T) { - self.x += rhs; - self.y += rhs; - } -} - -impl std::ops::MulAssign for Vector -where - T: std::ops::MulAssign, -{ - fn mul_assign(&mut self, rhs: Self) { - self.x *= rhs.x; - self.y *= rhs.y; - } -} - -impl std::ops::SubAssign for Vector -where - T: std::ops::SubAssign, -{ - fn sub_assign(&mut self, rhs: Self) { - self.x -= rhs.x; - self.y -= rhs.y; - } -} - -impl std::ops::SubAssign for Vector -where - T: std::ops::SubAssign + Copy, -{ - fn sub_assign(&mut self, rhs: T) { - self.x -= rhs; - self.y -= rhs; - } -} - -impl std::ops::Mul for Vector -where - T: std::ops::Mul + Copy, -{ - type Output = Self; - - fn mul(self, rhs: T) -> Self::Output { - Self { - x: self.x * rhs, - y: self.y * rhs, - } - } -} - -impl std::ops::MulAssign for Vector -where - T: std::ops::MulAssign + Copy, -{ - fn mul_assign(&mut self, rhs: T) { - self.x *= rhs; - self.y *= rhs; - } -} diff --git a/src/window.rs b/src/window.rs deleted file mode 100644 index 5f67173..0000000 --- a/src/window.rs +++ /dev/null @@ -1,44 +0,0 @@ -use pixels::{Error, Pixels, SurfaceTexture, PixelsBuilder}; -use winit::{ - dpi::LogicalSize, - event_loop::EventLoop, - window::{CursorGrabMode, Window, WindowBuilder}, -}; - -use crate::{HEIGHT, WIDTH, SCALEFACTOR}; - -pub struct GameWindow { - pub window: Window, - pub pixels: Pixels, -} - -impl GameWindow { - pub fn new(title: &str, event_loop: &EventLoop<()>) -> Result { - let size = LogicalSize::new(WIDTH / SCALEFACTOR, HEIGHT / SCALEFACTOR); - let window = WindowBuilder::new() - .with_title(title) - .with_inner_size(size) - .build(event_loop) - .unwrap(); - - window - .set_cursor_grab(CursorGrabMode::Confined) - .or_else(|_e| window.set_cursor_grab(CursorGrabMode::Locked)) - .unwrap(); - window.set_cursor_visible(false); - - let surface_texture = SurfaceTexture::new(WIDTH, HEIGHT, &window); - let pixels = PixelsBuilder::new(WIDTH, HEIGHT, surface_texture) - .enable_vsync(true) - .build()?; - - Ok(Self { - window, - pixels, - }) - } - - pub fn resize(&mut self, new_size: (u32, u32)) { - self.pixels.resize_surface(new_size.0, new_size.1).unwrap(); - } -}