wgpucube is a WebGPU demo app using winit and wgpu. It renders a shaded, spinning cube with GPU acceleration. Inspired by the original kmscube by Rob Clark.
wgpucube uses winit for cross-platform window handling and wgpu as the cross-platform graphics library. Additionally, glam is used to provide fast and ergonomic linear algebra functionality.
The goal is to run on every platform that wgpu and winit support, though this is a work in progress.
The wasm32-unknown-unknown target must be installed to compile for the web:
rustup target add wasm32-unknown-unknownTrunk is used to bundle and serve the local web app demo with hot reloading. It is available through Homebrew, Nix, and some other package managers or it can be installed with cargo:
cargo install --locked trunkAn xtask command is provided to build and serve the web demo with hot reloading. The default configuration in trunk.toml will serve the demo on localhost port 8080:
cargo xtask run-wasmwgpucube does not currently take any command line arguments. To run in release mode, clone the repository and use cargo to run the project:
cargo run --releaseThe app can be built and run in the iOS simulator using cargo-bundle. This only works on macOS devices. XCode must be installed.
The Rust aarch64 iOS simulator target must be installed to compile for the iOS simulator:
rustup target add aarch64-apple-ios-simcargo-bundle must be installed to create the iOS app bundle:
cargo install cargo-bundle --lockedThe following command will build the app for the iOS simulator, boot an iOS simulator, launch the Simulator app to bring it to the foreground, install the app into the simulated iPhone, and launch it:
cargo xtask run-iosThe quickest path to build for Android is with cargo-apk.
cargo install cargo-apk --lockedThe Android SDK and NDK must be installed. Ensure that the ANDROID_HOME and ANDROID_NDK_ROOT environment variables are set to the correct paths.
export ANDROID_HOME=/path/to/android/sdk
export ANDROID_NDK_ROOT=/path/to/android/ndkConnect an Android device or start an Android simulator and run:
cargo apk run --lib --package wgpucubeNote that configuring the Android simulator to work correctly with GPU acceleration can be difficult, especially on macOS.
Calling std::Instant::now() on wasm32-unknown-unknown is not supported and will panic when called. The web_time crate is used as a drop-in replacement that works on browsers which support Performance.now(). For other platforms it acts as a zero overhead compile-time pass through to std::time functions.
Calling window.request_redraw() while handling a WindowEvent::RedrawRequested event does not work on iOS in winit v0.30. This breaks the common method of calling request_redraw() after handling each WindowEvent::RedrawRequested event for continuous rendering. Setting the event loop to ControlFlow::Poll is not a workaround because WindowEvent::RedrawRequested will not be sent on each event loop wakeup.
The workaround used in this project adds a request_redraw boolean flag to the Application structure that is set to true after each WindowEvent::RedrawRequested event is handled. Then the about_to_wait handler checks this flag and calls window.request_redraw() if it is set. Calling window.request_redraw() from about_to_wait() appears to work.
Winit tracking issue: rust-windowing/winit#3406
The current method of bundling for Android requires building as a library, not a binary. A separate lib.rs entrypoint exists to service the Android build. The android_logger is used in the lib.rs entrypoint to set up Android logging facilities.