diff --git a/Cargo.lock b/Cargo.lock index 7d4a59a..431e1f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,12 +54,12 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "android-activity" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39b801912a977c3fd52d80511fe1c0c8480c6f957f21ae2ce1b92ffe970cf4b9" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", - "bitflags 2.4.2", + "bitflags 2.6.0", "cc", "cesu8", "jni", @@ -174,9 +174,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block" @@ -184,22 +184,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" -[[package]] -name = "block-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7" -dependencies = [ - "objc-sys", -] - [[package]] name = "block2" -version = "0.3.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "block-sys", "objc2", ] @@ -227,7 +217,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "log", "polling", "rustix", @@ -271,9 +261,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cfg_aliases" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "codespan-reporting" @@ -413,6 +403,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +[[package]] +name = "dpi" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" + [[package]] name = "either" version = "1.9.0" @@ -554,7 +550,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "gpu-descriptor-types", "hashbrown 0.14.3", ] @@ -565,7 +561,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bf0b36e6f090b7e1d8a4b49c0cb81c1f8376f72198c65dd3ad9ff3556b8b78c" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", ] [[package]] @@ -605,17 +601,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" -[[package]] -name = "icrate" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" -dependencies = [ - "block2", - "dispatch", - "objc2", -] - [[package]] name = "indexmap" version = "1.9.3" @@ -728,9 +713,9 @@ version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "libc", - "redox_syscall 0.4.1", + "redox_syscall", ] [[package]] @@ -833,11 +818,11 @@ dependencies = [ [[package]] name = "ndk" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "jni-sys", "log", "ndk-sys", @@ -854,9 +839,9 @@ checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" [[package]] name = "ndk-sys" -version = "0.5.0+25.2.9519653" +version = "0.6.0+11769913" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" dependencies = [ "jni-sys", ] @@ -915,25 +900,206 @@ dependencies = [ [[package]] name = "objc-sys" -version = "0.3.2" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c71324e4180d0899963fc83d9d241ac39e699609fc1025a850aadac8257459" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" [[package]] name = "objc2" -version = "0.4.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" dependencies = [ "objc-sys", "objc2-encode", ] +[[package]] +name = "objc2-app-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" +dependencies = [ + "bitflags 2.6.0", + "block2", + "libc", + "objc2", + "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.6.0", + "block2", + "objc2", + "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", + "objc2", + "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.6.0", + "block2", + "objc2", + "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", + "objc2", + "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", + "objc2", + "objc2-contacts", + "objc2-foundation", +] + [[package]] name = "objc2-encode" -version = "3.0.0" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8" + +[[package]] +name = "objc2-foundation" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.6.0", + "block2", + "dispatch", + "libc", + "objc2", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2", + "objc2", + "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.6.0", + "block2", + "objc2", + "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.6.0", + "block2", + "objc2", + "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", + "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.6.0", + "block2", + "objc2", + "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", + "objc2", + "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.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] [[package]] name = "objc_exception" @@ -995,7 +1161,7 @@ checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", + "redox_syscall", "smallvec", "windows-targets 0.48.5", ] @@ -1006,6 +1172,26 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1162,15 +1348,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -1204,7 +1381,7 @@ version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -1243,9 +1420,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sctk-adwaita" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b2eaf3a5b264a521b988b2e73042e742df700c4f962cde845d1541adb46550" +checksum = "7de61fa7334ee8ee1f5c3c58dcc414fb9361e7e8f5bff9d45f4d69eeb89a7169" dependencies = [ "ab_glyph", "log", @@ -1304,7 +1481,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60e3d9941fa3bacf7c2bf4b065304faa14164151254cd16ce1b1bc8fc381600f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "calloop", "calloop-wayland-source", "cursor-icon", @@ -1621,7 +1798,7 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ca7d52347346f5473bf2f56705f360e8440873052e575e55890c4fa57843ed3" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "nix", "wayland-backend", "wayland-scanner", @@ -1633,7 +1810,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "cursor-icon", "wayland-backend", ] @@ -1655,7 +1832,7 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e253d7107ba913923dc253967f35e8561a3c65f914543e46843c88ddd729e21c" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -1667,7 +1844,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -1680,7 +1857,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -1722,9 +1899,9 @@ dependencies = [ [[package]] name = "web-time" -version = "0.2.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", @@ -1762,7 +1939,7 @@ checksum = "8f478237b4bf0d5b70a39898a66fa67ca3a007d79f2520485b8b0c3dfc46f8c2" dependencies = [ "arrayvec", "bit-vec", - "bitflags 2.4.2", + "bitflags 2.6.0", "codespan-reporting", "log", "naga", @@ -1787,7 +1964,7 @@ dependencies = [ "arrayvec", "ash", "bit-set", - "bitflags 2.4.2", + "bitflags 2.6.0", "block", "core-graphics-types", "d3d12", @@ -1825,7 +2002,7 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0c153280bb108c2979eb5c7391cb18c56642dd3c072e55f52065e13e2a1252a" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "js-sys", "web-sys", ] @@ -2086,37 +2263,41 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winit" -version = "0.29.15" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d59ad965a635657faf09c8f062badd885748428933dad8e8bdd64064d92e5ca" +checksum = "49f45a7b7e2de6af35448d7718dab6d95acec466eb3bb7a56f4d31d1af754004" dependencies = [ "ahash", "android-activity", "atomic-waker", - "bitflags 2.4.2", + "bitflags 2.6.0", + "block2", "bytemuck", "calloop", "cfg_aliases", + "concurrent-queue", "core-foundation", "core-graphics", "cursor-icon", - "icrate", + "dpi", "js-sys", "libc", - "log", "memmap2", "ndk", - "ndk-sys", "objc2", - "once_cell", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", "orbclient", "percent-encoding", + "pin-project", "raw-window-handle", - "redox_syscall 0.3.5", + "redox_syscall", "rustix", "sctk-adwaita", "smithay-client-toolkit", "smol_str", + "tracing", "unicode-segmentation", "wasm-bindgen", "wasm-bindgen-futures", @@ -2126,7 +2307,7 @@ dependencies = [ "wayland-protocols-plasma", "web-sys", "web-time", - "windows-sys 0.48.0", + "windows-sys 0.52.0", "x11-dl", "x11rb", "xkbcommon-dl", @@ -2185,7 +2366,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "dlib", "log", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index d29c5b9..bf6686b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ static-array = { version = "0.5.0", features = ["rayon"] } [dev-dependencies] pixels = "0.13.0" -winit = { version = "0.29.15", default_features = false, features = ["rwh_05", "x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"] } +winit = { version = "0.30.3", default_features = false, features = ["rwh_05", "x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"] } rand = "0.8.5" approx = "0.5.1" diff --git a/examples/continuity_test_cube.rs b/examples/continuity_test_cube.rs index f70748a..01de14c 100644 --- a/examples/continuity_test_cube.rs +++ b/examples/continuity_test_cube.rs @@ -1,89 +1,114 @@ //! An example testing the continuity and correct mapping of the `CubeSphereGrid` projection. -use std::{error::Error, f64::consts::PI}; +use std::f64::consts::PI; use pixels::{SurfaceTexture, Pixels}; use surface_grid::{sphere::{CubeSphereGrid, CubeSpherePoint, SpherePoint}, SurfaceGrid, GridPoint}; -use winit::{event_loop::EventLoop, window::WindowBuilder, dpi::{LogicalSize, PhysicalSize}, event::{Event, WindowEvent}}; +use winit::{application::ApplicationHandler, dpi::{LogicalSize, PhysicalSize}, event::WindowEvent, event_loop::{ActiveEventLoop, EventLoop}, window::{Window, WindowAttributes, WindowId}}; // The initial window size. const WINDOW_WIDTH: usize = 720; const WINDOW_HEIGHT: usize = 480; -fn main() -> Result<(), Box> { - // This example uses winit with pixels to display the game. - let event_loop = EventLoop::new()?; +struct TestApp { + window: Option, + size: Option>, + pixels: Option, + buffer: CubeSphereGrid<(f64, f64, f64), 64>, +} - let size = LogicalSize::new(WINDOW_WIDTH as f64, WINDOW_HEIGHT as f64); +impl TestApp { + pub fn new() -> Self { + Self { + window: None, + size: None, + pixels: None, + buffer: CubeSphereGrid::from_fn(|point| point.position(1.0)) + } + } +} - // Build the window. - let window = WindowBuilder::new() - .with_title("Continuity Test") - .with_inner_size(size) - .build(&event_loop)?; +impl ApplicationHandler for TestApp { + fn resumed(&mut self, event_loop: &ActiveEventLoop) { + let size = LogicalSize::new(WINDOW_WIDTH as f64, WINDOW_HEIGHT as f64); + // Build the window. + let window_attrs = WindowAttributes::default() + .with_title("Cube Test") + .with_inner_size(size); - // Pixels setup. - let window_size = window.inner_size(); - let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window); + self.window = Some(event_loop.create_window(window_attrs).expect("Failed to create window.")); - let mut size = window_size; + // Pixels setup. + let window_size = self.window.as_ref().unwrap().inner_size(); + let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, self.window.as_ref().unwrap()); - let mut pixels = Pixels::new(window_size.width, window_size.height, surface_texture)?; + self.size = Some(window_size); - let buffer: CubeSphereGrid<_, 64> = CubeSphereGrid::from_fn(|point| point.position(1.0)); + self.pixels = Some(Pixels::new(window_size.width, window_size.height, surface_texture) + .expect("Failed to create pixel buffer.")); + } - event_loop.run(move |event, target| { + fn window_event( + &mut self, + event_loop: &ActiveEventLoop, + _window_id: WindowId, + event: WindowEvent, + ) { match event { - Event::WindowEvent { event, .. } => { - match event { - WindowEvent::Resized(window_size) => { - // Handle resizing. - if window_size.width != 0 && window_size.height != 0 { - size = PhysicalSize::new(window_size.width, window_size.height); - - pixels.resize_buffer(size.width, size.height) - .expect("Failed to resize buffer"); - pixels.resize_surface(window_size.width, window_size.height) - .expect("Failed to resize surface"); - } - - window.request_redraw() - }, - WindowEvent::CloseRequested => { - target.exit() + WindowEvent::Resized(window_size) => { + // Handle resizing. + if window_size.width != 0 && window_size.height != 0 { + self.size = Some(PhysicalSize::new(window_size.width, window_size.height)); + + self.pixels.as_mut().unwrap().resize_buffer(self.size.as_ref().unwrap().width, self.size.as_ref().unwrap().height) + .expect("Failed to resize buffer"); + self.pixels.as_mut().unwrap().resize_surface(window_size.width, window_size.height) + .expect("Failed to resize surface"); + } + + self.window.as_ref().unwrap().request_redraw() + }, + WindowEvent::CloseRequested => { + event_loop.exit() + }, + WindowEvent::RedrawRequested => { + // Display the result using pixels. + let frame = self.pixels.as_mut().unwrap().frame_mut(); + + for y in 0..self.size.as_ref().unwrap().height { + for x in 0..self.size.as_ref().unwrap().width { + let i = (y as usize * self.size.as_ref().unwrap().width as usize + x as usize) * 4; + + // Convert the X Y screen coordinates to an equirectangular + // projection of the latitude and longitude. + let latitude = (y as f64 / self.size.as_ref().unwrap().height as f64) * PI - PI / 2.0; + let longitude = (x as f64 / self.size.as_ref().unwrap().width as f64) * PI * 2.0; + + let (x, y, z) = self.buffer[CubeSpherePoint::from_geographic(latitude, longitude)]; + + frame[i + 0] = ((x + 1.0) / 2.0 * 255.0) as u8; + frame[i + 1] = ((y + 1.0) / 2.0 * 255.0) as u8; + frame[i + 2] = ((z + 1.0) / 2.0 * 255.0) as u8; + frame[i + 3] = 255; } - WindowEvent::RedrawRequested => { - // Display the result using pixels. - let frame = pixels.frame_mut(); - - for y in 0..size.height { - for x in 0..size.width { - let i = (y as usize * size.width as usize + x as usize) * 4; - - // Convert the X Y screen coordinates to an equirectangular - // projection of the latitude and longitude. - let latitude = (y as f64 / size.height as f64) * PI - PI / 2.0; - let longitude = (x as f64 / size.width as f64) * PI * 2.0; - - let (x, y, z) = buffer[CubeSpherePoint::from_geographic(latitude, longitude)]; - - frame[i + 0] = ((x + 1.0) / 2.0 * 255.0) as u8; - frame[i + 1] = ((y + 1.0) / 2.0 * 255.0) as u8; - frame[i + 2] = ((z + 1.0) / 2.0 * 255.0) as u8; - frame[i + 3] = 255; - } - } - - // Render the pixels to the screen. - pixels.render().expect("Failed to render"); - }, - _ => {} } + + // Render the pixels to the screen. + self.pixels.as_ref().unwrap().render().expect("Failed to render"); }, _ => {} } - })?; + } +} + +fn main() { + // This example uses winit with pixels to display the game. + let event_loop = EventLoop::new() + .expect("Failed to start event loop."); + + let mut app = TestApp::new(); - Ok(()) + event_loop.run_app(&mut app) + .expect("Failed to run app."); } diff --git a/examples/continuity_test_rect.rs b/examples/continuity_test_rect.rs index 239b17e..4e12b59 100644 --- a/examples/continuity_test_rect.rs +++ b/examples/continuity_test_rect.rs @@ -1,91 +1,114 @@ -//! An example testing the continuity and correct mapping of the `CubeSphereGrid` projection. +//! An example testing the continuity and correct mapping of the `RectangleSphere` projection. -use std::{error::Error, f64::consts::PI}; +use std::f64::consts::PI; use pixels::{SurfaceTexture, Pixels}; -use surface_grid::{sphere::{RectangleSphereGrid, RectangleSpherePoint, SpherePoint}, SurfaceGrid, GridPoint}; -use winit::{event_loop::EventLoop, window::WindowBuilder, dpi::{LogicalSize, PhysicalSize}, event::{Event, WindowEvent}}; +use surface_grid::{sphere::{RectangleSpherePoint, RectangleSphereGrid, SpherePoint}, GridPoint, SurfaceGrid}; +use winit::{application::ApplicationHandler, dpi::{LogicalSize, PhysicalSize}, event::WindowEvent, event_loop::{ActiveEventLoop, EventLoop}, window::{Window, WindowAttributes, WindowId}}; // The initial window size. const WINDOW_WIDTH: usize = 720; const WINDOW_HEIGHT: usize = 480; -fn main() -> Result<(), Box> { - // This example uses winit with pixels to display the game. - let event_loop = EventLoop::new()?; +struct TestApp { + window: Option, + size: Option>, + pixels: Option, + buffer: RectangleSphereGrid<(f64, f64, f64), 128, 128>, +} - let size = LogicalSize::new(WINDOW_WIDTH as f64, WINDOW_HEIGHT as f64); +impl TestApp { + pub fn new() -> Self { + Self { + window: None, + size: None, + pixels: None, + buffer: RectangleSphereGrid::from_fn(|point| point.position(1.0)) + } + } +} - // Build the window. - let window = WindowBuilder::new() - .with_title("Continuity Test") - .with_inner_size(size) - .build(&event_loop)?; +impl ApplicationHandler for TestApp { + fn resumed(&mut self, event_loop: &ActiveEventLoop) { + let size = LogicalSize::new(WINDOW_WIDTH as f64, WINDOW_HEIGHT as f64); + // Build the window. + let window_attrs = WindowAttributes::default() + .with_title("Cube Test") + .with_inner_size(size); - // Pixels setup. - let window_size = window.inner_size(); - let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window); + self.window = Some(event_loop.create_window(window_attrs).expect("Failed to create window.")); - let mut size = window_size; + // Pixels setup. + let window_size = self.window.as_ref().unwrap().inner_size(); + let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, self.window.as_ref().unwrap()); - let mut pixels = Pixels::new(window_size.width, window_size.height, surface_texture)?; + self.size = Some(window_size); - let buffer: RectangleSphereGrid<_, 400, 200> = RectangleSphereGrid::from_fn(|point| (point.position(1.0))); + self.pixels = Some(Pixels::new(window_size.width, window_size.height, surface_texture) + .expect("Failed to create pixel buffer.")); + } - event_loop.run(move |event, target| { + fn window_event( + &mut self, + event_loop: &ActiveEventLoop, + _window_id: WindowId, + event: WindowEvent, + ) { match event { - Event::WindowEvent { event, .. } => { - match event { - WindowEvent::Resized(window_size) => { - // Handle resizing. - if window_size.width != 0 && window_size.height != 0 { - size = PhysicalSize::new(window_size.width, window_size.height); - - pixels.resize_buffer(size.width, size.height) - .expect("Failed to resize buffer"); - pixels.resize_surface(window_size.width, window_size.height) - .expect("Failed to resize surface"); - } - - window.request_redraw() - }, - WindowEvent::CloseRequested => { - target.exit() + WindowEvent::Resized(window_size) => { + // Handle resizing. + if window_size.width != 0 && window_size.height != 0 { + self.size = Some(PhysicalSize::new(window_size.width, window_size.height)); + + self.pixels.as_mut().unwrap().resize_buffer(self.size.as_ref().unwrap().width, self.size.as_ref().unwrap().height) + .expect("Failed to resize buffer"); + self.pixels.as_mut().unwrap().resize_surface(window_size.width, window_size.height) + .expect("Failed to resize surface"); + } + + self.window.as_ref().unwrap().request_redraw() + }, + WindowEvent::CloseRequested => { + event_loop.exit() + }, + WindowEvent::RedrawRequested => { + // Display the result using pixels. + let frame = self.pixels.as_mut().unwrap().frame_mut(); + + for y in 0..self.size.as_ref().unwrap().height { + for x in 0..self.size.as_ref().unwrap().width { + let i = (y as usize * self.size.as_ref().unwrap().width as usize + x as usize) * 4; + + // Convert the X Y screen coordinates to an equirectangular + // projection of the latitude and longitude. + let latitude = (y as f64 / self.size.as_ref().unwrap().height as f64) * PI - PI / 2.0; + let longitude = (x as f64 / self.size.as_ref().unwrap().width as f64) * PI * 2.0; + + let (x, y, z) = self.buffer[RectangleSpherePoint::from_geographic(latitude, longitude)]; + + frame[i + 0] = ((x + 1.0) / 2.0 * 255.0) as u8; + frame[i + 1] = ((y + 1.0) / 2.0 * 255.0) as u8; + frame[i + 2] = ((z + 1.0) / 2.0 * 255.0) as u8; + frame[i + 3] = 255; } - WindowEvent::RedrawRequested => { - // Display the result using pixels. - let frame = pixels.frame_mut(); - - for y in 0..size.height { - for x in 0..size.width { - let i = (y as usize * size.width as usize + x as usize) * 4; - - // Convert the X Y screen coordinates to an equirectangular - // projection of the latitude and longitude. - let latitude = (y as f64 / size.height as f64) * PI - PI / 2.0; - let longitude = (x as f64 / size.width as f64) * PI * 2.0; - - // Gets the value stored at the latitude and longitude calculated. - let (x, y, z) = buffer[RectangleSpherePoint::from_geographic(latitude, longitude)]; - - frame[i + 0] = ((x + 1.0) / 2.0 * 255.0) as u8; - frame[i + 1] = ((y + 1.0) / 2.0 * 255.0) as u8; - frame[i + 2] = ((z + 1.0) / 2.0 * 255.0) as u8; - frame[i + 3] = 255; - } - } - - // Render the pixels to the screen. - pixels.render().expect("Failed to render"); - }, - _ => {} } + + // Render the pixels to the screen. + self.pixels.as_ref().unwrap().render().expect("Failed to render"); }, _ => {} } - })?; - - Ok(()) + } } +fn main() { + // This example uses winit with pixels to display the game. + let event_loop = EventLoop::new() + .expect("Failed to start event loop."); + + let mut app = TestApp::new(); + + event_loop.run_app(&mut app) + .expect("Failed to run app."); +} diff --git a/examples/conway.rs b/examples/conway.rs index 4b37a25..483f415 100644 --- a/examples/conway.rs +++ b/examples/conway.rs @@ -1,136 +1,170 @@ //! An example implementing conways game of life on the surface of a sphere. -use std::{error::Error, f64::consts::PI, mem::swap, time::{Instant, Duration}}; +use std::{f64::consts::PI, mem::swap, time::{Duration, Instant}}; use pixels::{SurfaceTexture, Pixels}; use rand::{thread_rng, Rng}; use surface_grid::{sphere::{CubeSphereGrid, CubeSpherePoint, SpherePoint}, SurfaceGrid}; -use winit::{event_loop::{EventLoop, ControlFlow}, window::WindowBuilder, dpi::{LogicalSize, PhysicalSize}, event::{Event, WindowEvent, StartCause}}; +use winit::{application::ApplicationHandler, dpi::{LogicalSize, PhysicalSize}, event::{StartCause, WindowEvent}, event_loop::{ActiveEventLoop, ControlFlow, EventLoop}, window::{Window, WindowAttributes, WindowId}}; // The initial window size. const WINDOW_WIDTH: usize = 720; const WINDOW_HEIGHT: usize = 480; -fn main() -> Result<(), Box> { - // This example uses winit with pixels to display the game. - let event_loop = EventLoop::new()?; +struct ConwayGameOfLife { + window: Option, + pixels: Option, + buffer1: CubeSphereGrid, + buffer2: CubeSphereGrid, + size: Option>, +} - let size = LogicalSize::new(WINDOW_WIDTH as f64, WINDOW_HEIGHT as f64); +impl ConwayGameOfLife { + pub fn new() -> Self { + // Create two grids to swap between. + // This saves allocating a new grid for each frame. + let mut rng = thread_rng(); + + // The size specified here might be smaller than expected. + // This is because it is the size of each cube face rather than the size of the whole grid. + // A size of 512 leads to 1572864 grid cells. This is equivalent to an image around 1500x1500. + let buffer1: CubeSphereGrid = CubeSphereGrid::from_fn(|_| rng.gen()); + let buffer2: CubeSphereGrid = CubeSphereGrid::default(); + + Self { + window: None, + pixels: None, + size: None, + buffer1, + buffer2, + } + } +} - // Build the window. - let window = WindowBuilder::new() - .with_title("Conway's Game of Life") - .with_inner_size(size) - .build(&event_loop)?; +impl ApplicationHandler for ConwayGameOfLife { + fn resumed(&mut self, event_loop: &ActiveEventLoop) { + let size = LogicalSize::new(WINDOW_WIDTH as f64, WINDOW_HEIGHT as f64); + // Build the window. + let window_attrs = WindowAttributes::default() + .with_title("Conway's Game of Life") + .with_inner_size(size); - // Pixels setup. - let window_size = window.inner_size(); - let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, &window); + self.window = Some(event_loop.create_window(window_attrs).expect("Failed to create window.")); - let mut size = window_size; + // Pixels setup. + let window_size = self.window.as_ref().unwrap().inner_size(); + let surface_texture = SurfaceTexture::new(window_size.width, window_size.height, self.window.as_ref().unwrap()); - let mut pixels = Pixels::new(window_size.width, window_size.height, surface_texture)?; + self.size = Some(window_size); - // Create two grids to swap between. - // This saves allocating a new grid for each frame. - let mut rng = thread_rng(); + self.pixels = Some(Pixels::new(window_size.width, window_size.height, surface_texture) + .expect("Failed to create pixel buffer.")); - // The size specified here might be smaller than expected. - // This is because it is the size of each cube face rather than the size of the whole grid. - // A size of 512 leads to 1572864 grid cells. This is equivalent to an image around 1500x1500. - let mut buffer1: CubeSphereGrid = CubeSphereGrid::from_fn(|_| rng.gen()); - let mut buffer2: CubeSphereGrid = CubeSphereGrid::default(); + } - event_loop.run(move |event, target| { + fn window_event( + &mut self, + event_loop: &ActiveEventLoop, + _window_id: WindowId, + event: WindowEvent, + ) { match event { - Event::NewEvents(StartCause::Init) => { - // Update at 60 FPS. - target.set_control_flow(ControlFlow::WaitUntil(Instant::now() + Duration::from_millis(1000 / 60))) - }, - Event::NewEvents(StartCause::ResumeTimeReached { .. }) => { - // Redraw on each frame. - window.request_redraw(); - } - Event::WindowEvent { event, .. } => { - match event { - WindowEvent::Resized(window_size) => { - // Handle resizing. - if window_size.width != 0 && window_size.height != 0 { - size = PhysicalSize::new(window_size.width, window_size.height); - - pixels.resize_buffer(size.width, size.height) - .expect("Failed to resize buffer"); - pixels.resize_surface(window_size.width, window_size.height) - .expect("Failed to resize surface"); - } + WindowEvent::Resized(window_size) => { + // Handle resizing. + if window_size.width != 0 && window_size.height != 0 { + self.size = Some(PhysicalSize::new(window_size.width, window_size.height)); + + self.pixels.as_mut().unwrap().resize_buffer(self.size.as_ref().unwrap().width, self.size.as_ref().unwrap().height) + .expect("Failed to resize buffer"); + self.pixels.as_mut().unwrap().resize_surface(window_size.width, window_size.height) + .expect("Failed to resize surface"); + } - window.request_redraw() - }, - WindowEvent::CloseRequested => { - target.exit() + self.window.as_ref().unwrap().request_redraw() + }, + WindowEvent::CloseRequested => { + event_loop.exit() + }, + WindowEvent::RedrawRequested => { + // Calculate conways game of life in parallel. + self.buffer2.set_from_neighbours_diagonals_par(&self.buffer1, |s1, s2, s3, s4, current, s6, s7, s8, s9| { + let count = [s1, s2, s3, s4, s6, s7, s8, s9] + .into_iter() + .filter(|s| **s) + .count(); + + if count < 2 { + false + } else if count > 3 { + false + } else if *current && count == 2 { + true + } else if count == 3 { + true + } else { + false } - WindowEvent::RedrawRequested => { - // Calculate conways game of life in parallel. - buffer2.set_from_neighbours_diagonals_par(&buffer1, |s1, s2, s3, s4, current, s6, s7, s8, s9| { - let count = [s1, s2, s3, s4, s6, s7, s8, s9] - .into_iter() - .filter(|s| **s) - .count(); - - if count < 2 { - false - } else if count > 3 { - false - } else if *current && count == 2 { - true - } else if count == 3 { - true - } else { - false - } - }); - - // Swap the buffers. - swap(&mut buffer2, &mut buffer1); - - // Display the result using pixels. - let frame = pixels.frame_mut(); - - for y in 0..size.height { - for x in 0..size.width { - let i = (y as usize * size.width as usize + x as usize) * 4; - - // Convert the X Y screen coordinates to an equirectangular - // projection of the latitude and longitude. - let latitude = (y as f64 / size.height as f64) * PI - PI / 2.0; - let longitude = (x as f64 / size.width as f64) * PI * 2.0; - - // Gets the value stored at the latitude and longitude calculated. - let value = buffer1[CubeSpherePoint::from_geographic(latitude, longitude)]; - - // Set the pixel colour. - if value { - frame[i] = 255; - frame[i + 1] = 255; - frame[i + 2] = 255; - } else { - frame[i] = 0; - frame[i + 1] = 0; - frame[i + 2] = 0; - } - frame[i + 3] = 255; - } + }); + + // Swap the buffers. + swap(&mut self.buffer2, &mut self.buffer1); + + // Display the result using pixels. + let frame = self.pixels.as_mut().unwrap().frame_mut(); + + for y in 0..self.size.as_ref().unwrap().height { + for x in 0..self.size.as_ref().unwrap().width { + let i = (y as usize * self.size.as_ref().unwrap().width as usize + x as usize) * 4; + + // Convert the X Y screen coordinates to an equirectangular + // projection of the latitude and longitude. + let latitude = (y as f64 / self.size.as_ref().unwrap().height as f64) * PI - PI / 2.0; + let longitude = (x as f64 / self.size.as_ref().unwrap().width as f64) * PI * 2.0; + + // Gets the value stored at the latitude and longitude calculated. + let value = self.buffer1[CubeSpherePoint::from_geographic(latitude, longitude)]; + + // Set the pixel colour. + if value { + frame[i] = 255; + frame[i + 1] = 255; + frame[i + 2] = 255; + } else { + frame[i] = 0; + frame[i + 1] = 0; + frame[i + 2] = 0; } - - // Render the pixels to the screen. - pixels.render().expect("Failed to render"); - }, - _ => {} + frame[i + 3] = 255; + } } + + // Render the pixels to the screen. + self.pixels.as_ref().unwrap().render().expect("Failed to render"); + }, + _ => {} + } + } + + fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: StartCause) { + match cause { + StartCause::ResumeTimeReached { .. } => { + self.window.as_ref().unwrap().request_redraw(); + }, + StartCause::Init => { + event_loop.set_control_flow(ControlFlow::WaitUntil(Instant::now() + Duration::from_millis(1000 / 60))) }, _ => {} } - })?; + } +} + +fn main() { + // This example uses winit with pixels to display the game. + let event_loop = EventLoop::new() + .expect("Failed to start event loop."); + + let mut app = ConwayGameOfLife::new(); - Ok(()) + event_loop.run_app(&mut app) + .expect("Failed to run app."); } diff --git a/src/sphere.rs b/src/sphere.rs index 7261340..b484825 100644 --- a/src/sphere.rs +++ b/src/sphere.rs @@ -258,8 +258,8 @@ impl SpherePoint for RectangleSpherePoint * ((y * H as f64) as i32).rem_euclid(H as i32) + H as i32 * (y.floor() as i32).rem_euclid(2)) as u32; - let y = if y == 100 { - 99 + let y = if y == H as u32 { + H as u32 - 1 } else { y };