v0.7.0: SDL-free wasm worker backend (WebGPU + WebGL2) with on-demand assets

The engine now runs on a plain Web Worker (no SDL, no PROXY_TO_PTHREAD: in a pthread Emscripten proxies every filesystem syscall to the main browser thread, where synchronous XHR - and thus FS.createLazyFile - is forbidden). A page/worker pair transfers an OffscreenCanvas and forwards DOM input; assets load lazily from an embedded manifest, so entering a map fetches only that map and its tiles.

Presentation: ra3.webgpu (WebGPU via Emscripten's emdawnwebgpu port, WGSL shaders, the default on wasm) and ra3.wasmgl (WebGL2, GLSL ES). The legacy SDL ra3.webgl backend is removed.
This commit is contained in:
EnderTheCoder
2026-09-29 12:08:07 +08:00
parent 70d4beca4f
commit 889ce945f2
27 changed files with 2161 additions and 639 deletions
+38
View File
@@ -0,0 +1,38 @@
// WebGPU counterpart of the 2D image path (the WGSL port of
// webgl_scene_vert/frag.glsl and the Vulkan scene shaders).
//
// Bind group 0: uniform { rect: vec4<f32>; }, the scene texture and a sampler.
// WebGPU clip space is +Y up, matching GL, so the vertex flips Y the same way.
struct SceneUniforms {
rect: vec4<f32>, // xy = top-left (0..1), zw = size (0..1)
};
@group(0) @binding(0) var<uniform> u_scene: SceneUniforms;
@group(0) @binding(1) var u_scene_tex: texture_2d<f32>;
@group(0) @binding(2) var u_scene_samp: sampler;
struct SceneOut {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
};
@vertex
fn vs_main(@builtin(vertex_index) vertex_index: u32) -> SceneOut {
let p = vec2<f32>(f32((vertex_index << 1u) & 2u), f32(vertex_index & 2u));
var out: SceneOut;
out.uv = (p - u_scene.rect.xy) / u_scene.rect.zw;
out.position = vec4<f32>(p.x * 2.0 - 1.0, 1.0 - p.y * 2.0, 0.0, 1.0);
return out;
}
@fragment
fn fs_main(in: SceneOut) -> @location(0) vec4<f32> {
// Only the destination rect is drawn; outside it the previous contents stay.
if (in.uv.x < 0.0 || in.uv.x > 1.0 || in.uv.y < 0.0 || in.uv.y > 1.0) {
discard;
}
// The image is 0xAARRGGBB (BGRA in memory); swizzle it back.
let c = textureSampleLevel(u_scene_tex, u_scene_samp, in.uv, 0.0);
return vec4<f32>(c.b, c.g, c.r, c.a);
}