81893788c1
The 2048 surface limit was never wgpu's or the GPU's — it's downlevel_webgl2_defaults().max_texture_dimension_2d (2048), which WgpuSettingsPriority::WebGL2 forces. Switch to Functionality: on the WebGL2 (Gl) backend Bevy then adopts the adapter's real limits, which are still WebGL2-constrained for features/buffers (shaders stay GLES-compatible) but report the GPU's true max texture dimension (e.g. 16384). The device is requested with exactly what the adapter offers, so creation can't fail, the surface is no longer capped, and large viewports (4K) render with no letterbox and no hardcoded cap. Removes the resize_constraints cap and the play.html max-width/height caps. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
80 lines
4.2 KiB
Rust
80 lines
4.2 KiB
Rust
//! Browser entry point for the Ferrous Solitaire Bevy WASM build.
|
||
//!
|
||
//! This crate compiles the full `solitaire_engine` to `wasm32-unknown-unknown`
|
||
//! and renders to a `<canvas id="bevy-canvas">` element. It shares the same
|
||
//! ECS code path as the desktop and Android builds; the only differences are:
|
||
//! - Audio, sync, and analytics plugins are cfg-gated out in `CoreGamePlugin`
|
||
//! on the wasm32 target (see `solitaire_engine/src/core_game_plugin.rs`).
|
||
//! - `LocalOnlyProvider` is passed as the sync provider (sync is disabled).
|
||
//! - Storage is handled automatically by `WasmStorage` (localStorage-backed),
|
||
//! wired by `CoreGamePlugin` via `default_storage_backend()`.
|
||
|
||
use bevy::asset::AssetMetaCheck;
|
||
use bevy::prelude::*;
|
||
use bevy::render::RenderPlugin;
|
||
use bevy::render::settings::{RenderCreation, WgpuSettings, WgpuSettingsPriority};
|
||
use bevy::window::{Window, WindowPlugin, WindowResolution};
|
||
use solitaire_data::LocalOnlyProvider;
|
||
use solitaire_engine::CoreGamePlugin;
|
||
use wasm_bindgen::prelude::*;
|
||
|
||
#[wasm_bindgen(start)]
|
||
pub fn start() {
|
||
console_error_panic_hook::set_once();
|
||
|
||
App::new()
|
||
.add_plugins(
|
||
DefaultPlugins
|
||
.set(WindowPlugin {
|
||
primary_window: Some(Window {
|
||
// Bind to the existing <canvas id="bevy-canvas"> in play.html.
|
||
// Without this, Bevy appends its own canvas to <body>.
|
||
canvas: Some("#bevy-canvas".into()),
|
||
// Let CSS size the canvas; Bevy follows the element's size.
|
||
fit_canvas_to_parent: true,
|
||
// Prevent the browser stealing keyboard events and scroll.
|
||
prevent_default_event_handling: true,
|
||
// Render at CSS/logical pixels (scale_factor 1.0) rather
|
||
// than physical (CSS × devicePixelRatio). This keeps the
|
||
// surface smaller on HiDPI displays — lighter GPU load and
|
||
// stable sizing — at the cost of some crispness. The wgpu
|
||
// texture-dimension limit is now taken from the adapter (see
|
||
// the RenderPlugin below), so this is purely a quality/perf
|
||
// choice, no longer a crash-avoidance hack.
|
||
resolution: WindowResolution::default()
|
||
.with_scale_factor_override(1.0),
|
||
..default()
|
||
}),
|
||
..default()
|
||
})
|
||
// Bevy's default AssetPlugin fetches a `.meta` sidecar file for
|
||
// every asset before loading the asset itself. We don't ship
|
||
// `.meta` files, so skip the check to avoid a flood of 404s.
|
||
.set(AssetPlugin {
|
||
meta_check: AssetMetaCheck::Never,
|
||
..default()
|
||
})
|
||
// `Functionality` makes wgpu adopt the *adapter's* real limits
|
||
// instead of the conservative `downlevel_webgl2_defaults()` that
|
||
// `WebGL2` priority forces. On the WebGL2 (Gl) backend the adapter
|
||
// already reports WebGL2-constrained features/limits — no storage
|
||
// buffers, etc., so shaders stay GLES-compatible on both Firefox and
|
||
// Chromium — but it reports the GPU's *true* `max_texture_dimension`
|
||
// (e.g. 16384) rather than 2048. The device is requested with exactly
|
||
// what the adapter offers, so creation can't fail, and the surface is
|
||
// no longer capped at 2048: large viewports (4K, etc.) render natively
|
||
// with no letterbox and no hardcoded cap.
|
||
.set(RenderPlugin {
|
||
render_creation: RenderCreation::Automatic(WgpuSettings {
|
||
priority: WgpuSettingsPriority::Functionality,
|
||
..default()
|
||
}),
|
||
..default()
|
||
}),
|
||
)
|
||
// LocalOnlyProvider disables cloud sync — correct for the web build
|
||
// since SyncPlugin is cfg-gated out on wasm32 anyway.
|
||
.add_plugins(CoreGamePlugin::new(Box::new(LocalOnlyProvider)))
|
||
.run();
|
||
}
|