feat: web build via trunk with WebGPU detection + fallback
This commit is contained in:
parent
25e2207e0d
commit
9c8f384d0e
5
.cargo/config.toml
Normal file
5
.cargo/config.toml
Normal file
@ -0,0 +1,5 @@
|
||||
# WebGPU bindings in web-sys are gated behind `web_sys_unstable_apis`.
|
||||
# Enable that cfg when building for the web target only (harmless on desktop,
|
||||
# where src/web.rs is cfg'd out anyway).
|
||||
[target.'cfg(target_arch = "wasm32")']
|
||||
rustflags = ["--cfg", "web_sys_unstable_apis"]
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
/target
|
||||
/dist
|
||||
|
||||
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -4910,6 +4910,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"bevy",
|
||||
"bevy_egui",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
@ -11,6 +11,7 @@ bevy_egui = "0.41"
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
web-sys = { version = "0.3", features = ["Gpu", "Navigator", "Window", "Document", "HtmlElement", "Element"] }
|
||||
wasm-bindgen = "0.2"
|
||||
js-sys = "0.3"
|
||||
|
||||
# Smaller wasm binary in release web builds (per Bevy examples README).
|
||||
[profile.wasm-release]
|
||||
|
||||
8
Trunk.toml
Normal file
8
Trunk.toml
Normal file
@ -0,0 +1,8 @@
|
||||
[build]
|
||||
target = "web/index.html"
|
||||
dist = "dist"
|
||||
|
||||
[serve]
|
||||
address = "127.0.0.1"
|
||||
port = 8080
|
||||
open = false
|
||||
23
src/main.rs
23
src/main.rs
@ -1,8 +1,29 @@
|
||||
use bevy::prelude::*;
|
||||
use bevy::window::WindowPlugin;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
mod web;
|
||||
|
||||
fn main() {
|
||||
// On web, abort startup if WebGPU isn't available and show a message.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
if !web::webgpu_available() {
|
||||
web::show_fallback_message();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_plugins(DefaultPlugins.set(WindowPlugin {
|
||||
primary_window: Some(Window {
|
||||
title: "singularity-rs".into(),
|
||||
// On web, make the canvas track the browser window size.
|
||||
fit_canvas_to_parent: true,
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
}))
|
||||
.add_systems(Startup, setup)
|
||||
.run();
|
||||
}
|
||||
|
||||
42
src/web.rs
Normal file
42
src/web.rs
Normal file
@ -0,0 +1,42 @@
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use wasm_bindgen::JsCast;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub fn webgpu_available() -> bool {
|
||||
// `navigator.gpu` is gated in web-sys behind `web_sys_unstable_apis` and its
|
||||
// getter returns `Gpu` directly (not `Option<Gpu>`), so we probe the JS
|
||||
// object for the property instead. Reflect::has returns `true` when the
|
||||
// browser exposes the WebGPU API.
|
||||
web_sys::window()
|
||||
.and_then(|w| {
|
||||
let nav = w.navigator();
|
||||
js_sys::Reflect::has(nav.as_ref(), &"gpu".into()).ok()
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub fn show_fallback_message() {
|
||||
if let Some(window) = web_sys::window() {
|
||||
if let Some(document) = window.document() {
|
||||
if let Some(body) = document.body() {
|
||||
let el = document
|
||||
.create_element("div")
|
||||
.unwrap()
|
||||
.unchecked_into::<web_sys::HtmlElement>();
|
||||
el.set_inner_text(
|
||||
"WebGPU is not available in this browser. \
|
||||
Please use a recent version of Chrome, Edge, or Firefox.",
|
||||
);
|
||||
el.set_attribute(
|
||||
"style",
|
||||
"position:fixed;inset:0;display:flex;align-items:center;\
|
||||
justify-content:center;font-family:sans-serif;font-size:1.5rem;\
|
||||
text-align:center;padding:2rem;background:#111;color:#eee;",
|
||||
)
|
||||
.ok();
|
||||
body.append_child(&el).ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
21
web/index.html
Normal file
21
web/index.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>singularity-rs</title>
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; height: 100%; overflow: hidden; background: #000; }
|
||||
canvas { width: 100vw; height: 100vh; display: block; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<link
|
||||
data-trunk rel="rust"
|
||||
href="../Cargo.toml"
|
||||
data-bin="singularity-rs"
|
||||
data-type="main"
|
||||
data-cargo-features="bevy/webgpu"
|
||||
data-wasm-opt="z"
|
||||
/>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user