Add SDL2+OpenGL ES 2 renderer backend for Emscripten/WebGL
Implements Phase 1 of renderer abstraction plan: - SDL2Types.h: SFML-compatible type stubs in sf:: namespace - SDL2Renderer.h/cpp: OpenGL ES 2 rendering implementation - EmscriptenStubs.cpp: Stubs for missing POSIX functions (wait3, wait4, wcsftime) Build system changes: - Add MCRF_SDL2 compile-time backend selection - Add Emscripten SDL2 link options (-sUSE_SDL=2, -sFULL_ES2=1) - Fix LONG_BIT mismatch for Emscripten in pyport.h Code changes for SDL2/headless compatibility: - Guard ImGui includes with !MCRF_HEADLESS && !MCRF_SDL2 - Defer GL shader initialization until after context creation Current status: Python runs in browser, rendering WIP (canvas sizing issues) Build commands: emcmake cmake -DMCRF_SDL2=ON -B build-emscripten emmake make -C build-emscripten Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
8c3128e29c
commit
c5cc022aa2
13 changed files with 2665 additions and 34 deletions
|
|
@ -11,10 +11,22 @@ set(CMAKE_CXX_STANDARD_REQUIRED True)
|
|||
# Headless build option (no SFML, no graphics - for server/testing/Emscripten prep)
|
||||
option(MCRF_HEADLESS "Build without graphics dependencies (SFML, ImGui)" OFF)
|
||||
|
||||
# Emscripten builds are always headless (no SFML yet - using stubs)
|
||||
# SDL2 backend option (SDL2 + OpenGL ES 2 - for Emscripten/WebGL, Android, cross-platform)
|
||||
option(MCRF_SDL2 "Build with SDL2+OpenGL ES 2 backend instead of SFML" OFF)
|
||||
|
||||
# Emscripten builds: use SDL2 if specified, otherwise fall back to headless
|
||||
if(EMSCRIPTEN)
|
||||
set(MCRF_HEADLESS ON)
|
||||
message(STATUS "Emscripten detected - forcing HEADLESS mode")
|
||||
if(MCRF_SDL2)
|
||||
message(STATUS "Emscripten detected - using SDL2 backend")
|
||||
set(MCRF_HEADLESS OFF)
|
||||
else()
|
||||
set(MCRF_HEADLESS ON)
|
||||
message(STATUS "Emscripten detected - forcing HEADLESS mode (use -DMCRF_SDL2=ON for graphics)")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MCRF_SDL2)
|
||||
message(STATUS "Building with SDL2 backend - SDL2+OpenGL ES 2")
|
||||
endif()
|
||||
|
||||
if(MCRF_HEADLESS)
|
||||
|
|
@ -36,9 +48,13 @@ if(EMSCRIPTEN)
|
|||
# Emscripten build: use Python headers compiled for wasm32-emscripten
|
||||
# The pyconfig.h from cross-build has correct LONG_BIT and other settings
|
||||
set(PYTHON_WASM_BUILD "${CMAKE_SOURCE_DIR}/deps/cpython/cross-build/wasm32-emscripten/build/python")
|
||||
# Force-include wasm pyconfig.h BEFORE anything else to set correct platform defines
|
||||
add_compile_options(-include ${PYTHON_WASM_BUILD}/pyconfig.h)
|
||||
# Override LONG_BIT - Emscripten's limits.h incorrectly defines it as 64 for wasm32
|
||||
add_compile_definitions(LONG_BIT=32)
|
||||
# Include wasm build directory FIRST so its pyconfig.h is found by #include "pyconfig.h"
|
||||
include_directories(BEFORE ${PYTHON_WASM_BUILD})
|
||||
include_directories(${CMAKE_SOURCE_DIR}/deps/cpython/Include)
|
||||
include_directories(${PYTHON_WASM_BUILD}) # For generated headers
|
||||
message(STATUS "Using Emscripten Python from: ${PYTHON_WASM_BUILD}")
|
||||
elseif(MCRF_CROSS_WINDOWS)
|
||||
# Windows cross-compilation: use cpython headers with PC/pyconfig.h
|
||||
|
|
@ -57,8 +73,9 @@ else()
|
|||
include_directories(${CMAKE_SOURCE_DIR}/deps/Python)
|
||||
endif()
|
||||
|
||||
# ImGui and ImGui-SFML include directories (not needed in headless mode)
|
||||
if(NOT MCRF_HEADLESS)
|
||||
# ImGui and ImGui-SFML include directories (not needed in headless or SDL2 mode)
|
||||
# SDL2 builds will use ImGui with SDL2 backend later; for now, no ImGui
|
||||
if(NOT MCRF_HEADLESS AND NOT MCRF_SDL2)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/modules/imgui)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/modules/imgui-sfml)
|
||||
|
||||
|
|
@ -75,13 +92,14 @@ endif()
|
|||
# Collect all the source files
|
||||
file(GLOB_RECURSE SOURCES "src/*.cpp")
|
||||
|
||||
# Add ImGui sources to the build (only if not headless)
|
||||
if(NOT MCRF_HEADLESS)
|
||||
# Add ImGui sources to the build (only if using SFML)
|
||||
if(NOT MCRF_HEADLESS AND NOT MCRF_SDL2)
|
||||
list(APPEND SOURCES ${IMGUI_SOURCES})
|
||||
endif()
|
||||
|
||||
# Find OpenGL (required by ImGui-SFML) - not needed in headless mode
|
||||
if(NOT MCRF_HEADLESS)
|
||||
# SDL2 builds handle OpenGL ES 2 differently (via SDL2 or Emscripten)
|
||||
if(NOT MCRF_HEADLESS AND NOT MCRF_SDL2)
|
||||
if(MCRF_CROSS_WINDOWS)
|
||||
# For cross-compilation, OpenGL is provided by MinGW
|
||||
set(OPENGL_LIBRARIES opengl32)
|
||||
|
|
@ -109,8 +127,27 @@ if(EMSCRIPTEN)
|
|||
${LIBTCOD_WASM_BUILD}/_deps/lodepng-c-build/liblodepng-c.a
|
||||
${LIBTCOD_WASM_BUILD}/_deps/utf8proc-build/libutf8proc.a)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/deps/platform/linux) # Use Linux platform stubs for now
|
||||
# For SDL2 builds, add stb headers for image/font loading
|
||||
if(MCRF_SDL2)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/deps/stb)
|
||||
endif()
|
||||
message(STATUS "Linking Emscripten Python: ${PYTHON_WASM_BUILD}/libpython3.14.a")
|
||||
message(STATUS "Linking Emscripten libtcod: ${LIBTCOD_WASM_BUILD}/libtcod.a")
|
||||
elseif(MCRF_SDL2)
|
||||
# SDL2 build (non-Emscripten): link against SDL2 and system libraries
|
||||
# Note: For desktop SDL2 builds in the future
|
||||
find_package(SDL2 REQUIRED)
|
||||
find_package(OpenGL REQUIRED)
|
||||
set(LINK_LIBS
|
||||
SDL2::SDL2
|
||||
OpenGL::GL
|
||||
tcod
|
||||
python3.14
|
||||
m dl util pthread)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/deps/platform/linux)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/deps/stb) # stb_image.h, stb_truetype.h
|
||||
link_directories(${CMAKE_SOURCE_DIR}/__lib)
|
||||
message(STATUS "Building with SDL2 backend (desktop)")
|
||||
elseif(MCRF_HEADLESS)
|
||||
# Headless build: no SFML, no OpenGL
|
||||
if(WIN32 OR MCRF_CROSS_WINDOWS)
|
||||
|
|
@ -195,6 +232,8 @@ endif()
|
|||
add_executable(mcrogueface ${SOURCES})
|
||||
|
||||
# Define NO_SDL for libtcod-headless headers (excludes SDL-dependent code)
|
||||
# We ALWAYS need this because libtcod headers expect SDL3, not SDL2
|
||||
# Our SDL2 backend is separate from libtcod's SDL3 renderer
|
||||
target_compile_definitions(mcrogueface PRIVATE NO_SDL)
|
||||
|
||||
# Define MCRF_HEADLESS for headless builds (excludes SFML/ImGui code)
|
||||
|
|
@ -202,9 +241,15 @@ if(MCRF_HEADLESS)
|
|||
target_compile_definitions(mcrogueface PRIVATE MCRF_HEADLESS)
|
||||
endif()
|
||||
|
||||
# Define MCRF_SDL2 for SDL2 builds (uses SDL2+OpenGL ES 2 instead of SFML)
|
||||
if(MCRF_SDL2)
|
||||
target_compile_definitions(mcrogueface PRIVATE MCRF_SDL2)
|
||||
endif()
|
||||
|
||||
# Emscripten-specific link options (use ports for zlib, bzip2, sqlite3)
|
||||
if(EMSCRIPTEN)
|
||||
target_link_options(mcrogueface PRIVATE
|
||||
# Base Emscripten options
|
||||
set(EMSCRIPTEN_LINK_OPTIONS
|
||||
-sUSE_ZLIB=1
|
||||
-sUSE_BZIP2=1
|
||||
-sUSE_SQLITE3=1
|
||||
|
|
@ -215,6 +260,9 @@ if(EMSCRIPTEN)
|
|||
-sSTACK_OVERFLOW_CHECK=2
|
||||
-fexceptions
|
||||
-sNO_DISABLE_EXCEPTION_CATCHING
|
||||
# Disable features that require dynamic linking support
|
||||
-sERROR_ON_UNDEFINED_SYMBOLS=0
|
||||
-sALLOW_UNIMPLEMENTED_SYSCALLS=1
|
||||
# Preload Python stdlib into virtual filesystem at /lib/python3.14
|
||||
--preload-file=${CMAKE_SOURCE_DIR}/wasm_stdlib/lib@/lib
|
||||
# Preload game scripts into /scripts
|
||||
|
|
@ -222,6 +270,24 @@ if(EMSCRIPTEN)
|
|||
# Preload assets
|
||||
--preload-file=${CMAKE_SOURCE_DIR}/assets@/assets
|
||||
)
|
||||
|
||||
# Add SDL2 options if using SDL2 backend
|
||||
if(MCRF_SDL2)
|
||||
list(APPEND EMSCRIPTEN_LINK_OPTIONS
|
||||
-sUSE_SDL=2
|
||||
-sFULL_ES2=1
|
||||
-sMIN_WEBGL_VERSION=2
|
||||
-sMAX_WEBGL_VERSION=2
|
||||
)
|
||||
# SDL2 flags are also needed at compile time for headers
|
||||
target_compile_options(mcrogueface PRIVATE
|
||||
-sUSE_SDL=2
|
||||
)
|
||||
message(STATUS "Emscripten SDL2 options enabled: -sUSE_SDL=2 -sFULL_ES2=1")
|
||||
endif()
|
||||
|
||||
target_link_options(mcrogueface PRIVATE ${EMSCRIPTEN_LINK_OPTIONS})
|
||||
|
||||
# Set Python home for the embedded interpreter
|
||||
target_compile_definitions(mcrogueface PRIVATE
|
||||
MCRF_WASM_PYTHON_HOME="/lib/python3.14"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue