- ra3.webgl: a Web peer of Vulkan/Direct3D (SDL3 canvas + GLES3/WebGL2), with 2D blit and the GPU terrain raymarch; GLSL ES shaders; null fallback off Emscripten. backend::webgl + default_backend() (webgl under Emscripten). - Emscripten toolchain + Dockerfile.wasm + scripts/build-wasm.sh; import std, global -fexceptions, and Asyncify so the blocking frame loop yields to the browser (display::sleep_frame calls emscripten_sleep). - apps/web/shell.html + apps/web/serve.py (Range-capable dev server). - Assets: browsers forbid synchronous on-demand reads on the main thread (and FS.createLazyFile / the WasmFS fetch backend are worker-only; SDL3's Emscripten backend is main-thread DOM only, so the engine cannot run in a worker). The wasm build therefore preloads a compact per-map set via OPENRA3_WEB_ASSETS. - New openra3 textures --map ID lists the loose terrain TGAs a map resolves to (terrain::resolve_texture_files, shared with load_textures_from_dir). - Fixes: webgl heightmap used GL_R16 = 0x8229 (that is R8) -> upload rejected, terrain flattened to water; now 0x822A. Logger uses a stdout console sink on the web (stderr maps to console.error); a GL error check logs bad uploads. - CI: wasm image + build jobs.
47 lines
2.4 KiB
CMake
47 lines
2.4 KiB
CMake
# WebAssembly cross-build via Emscripten.
|
|
#
|
|
# Includes Emscripten's own platform toolchain (found through $EMSDK, set by the
|
|
# emsdk image / `emsdk_env.sh`) and then layers the project's requirements:
|
|
#
|
|
# * C++26 `import std;`. Emscripten ships the libc++ `std` module source and a
|
|
# modules.json in its sysroot; its toolchain wires that up, but only if
|
|
# `CMAKE_CXX_MODULE_STD` is on and no std-modules JSON has been set yet, so
|
|
# both are arranged before Emscripten.cmake is included and before the
|
|
# compiler is probed.
|
|
# * Global `-fexceptions`. Emscripten disables exceptions by default, and the
|
|
# libc++ `std` module must be built with the same setting as its consumers,
|
|
# or clang rejects the prebuilt module ("configuration mismatch"). The engine
|
|
# throws, so exceptions are enabled everywhere.
|
|
# * The SDL3 web port (`-sUSE_SDL=3`) is attached by CMake to the SDL interface
|
|
# target, not here, so only the targets that use SDL pay for it.
|
|
|
|
# `import std` support: the gate and the module switch must be in place before
|
|
# Emscripten.cmake runs and before the compiler is probed.
|
|
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "d0edc3af-4c50-42ea-a356-e2862fe7a444")
|
|
set(CMAKE_CXX_MODULE_STD ON)
|
|
# Let Emscripten.cmake point CMake at its own sysroot modules.json.
|
|
unset(CMAKE_CXX_STDLIB_MODULES_JSON)
|
|
|
|
if(DEFINED ENV{EMSDK})
|
|
set(OPENRA3_EMSCRIPTEN_CMAKE "$ENV{EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake")
|
|
elseif(DEFINED ENV{EMSCRIPTEN_ROOT})
|
|
set(OPENRA3_EMSCRIPTEN_CMAKE "$ENV{EMSCRIPTEN_ROOT}/cmake/Modules/Platform/Emscripten.cmake")
|
|
endif()
|
|
if(NOT EXISTS "${OPENRA3_EMSCRIPTEN_CMAKE}")
|
|
message(FATAL_ERROR "Emscripten.cmake not found (set EMSDK); looked at '${OPENRA3_EMSCRIPTEN_CMAKE}'")
|
|
endif()
|
|
include("${OPENRA3_EMSCRIPTEN_CMAKE}")
|
|
|
|
# Exceptions are used by the engine; keep them on globally so the std module and
|
|
# its consumers agree.
|
|
#
|
|
# Asyncify turns `emscripten_sleep` (used by display::sleep_frame on Emscripten)
|
|
# into a yield to the browser: the engine's frame loops are blocking, and
|
|
# without yielding the page freezes and never paints.
|
|
set(CMAKE_CXX_FLAGS_INIT "-fexceptions -sASYNCIFY=1")
|
|
set(CMAKE_C_FLAGS_INIT "-sASYNCIFY=1")
|
|
set(CMAKE_EXE_LINKER_FLAGS_INIT
|
|
"-fexceptions -sDISABLE_EXCEPTION_CATCHING=0 -sALLOW_MEMORY_GROWTH=1 -sASYNCIFY=1")
|
|
set(CMAKE_SHARED_LINKER_FLAGS_INIT
|
|
"-fexceptions -sDISABLE_EXCEPTION_CATCHING=0 -sALLOW_MEMORY_GROWTH=1 -sASYNCIFY=1")
|