--- id: "0072a" title: "gamedev — smoke SDL3 + sokol_gfx + ImGui (PC + WASM)" status: pendiente type: feature domain: - cpp-stack - gamedev scope: multi-app priority: alta depends: [] blocks: [] related: [] created: 2026-05-10 updated: 2026-05-17 tags: - gamedev - cpp - wasm --- ## Objetivo Validar de forma temprana que el stack SDL3 + sokol_gfx + Dear ImGui compila y corre en PC (Windows + Linux) y WASM (Emscripten) con un binario "Hello sprite + shader" antes de invertir tiempo en runtime real. ## Salida esperada App `cpp/apps/engine_smoke/` que: 1. Abre ventana SDL3 (1280x720, redimensionable). 2. Inicializa sokol_gfx (GL en desktop, WebGL2 en WASM). 3. Pinta: - Un quad con textura cargada via `stbi_load` (ya en stack). - Un fullscreen shader (gradiente animado). - Un panel ImGui con FPS y boton "exit". 4. Compila a: - `engine_smoke.exe` (Windows, MSVC o MinGW) - `engine_smoke` (Linux, gcc/clang) - `engine_smoke.html` + `engine_smoke.wasm` + `engine_smoke.js` (Emscripten) 5. WASM gzip ≤ **1.5 MB** (objetivo agresivo de Fase 0). Si no se cumple, documentar de donde viene el peso y plan de reduccion. ## Tareas ### 1. Vendoring de dependencias `cpp/vendor/` ya existe. Añadir: - `sokol/` — `sokol_gfx.h`, `sokol_app.h` NO (usamos SDL3), `sokol_log.h`, `sokol_glue.h` adaptado para SDL3 (init manual del contexto). - `sdl3/` — clonar build estatico de SDL 3.x. - ImGui ya esta en `cpp/vendor/imgui/`. Añadir backends `imgui_impl_sdl3.cpp` + `imgui_impl_sokol.cpp`. Si no existe oficial sokol backend, escribir uno minimo (~200 lineas). ### 2. CMake ```cmake # cpp/apps/engine_smoke/CMakeLists.txt add_executable(engine_smoke main.cpp) target_link_libraries(engine_smoke PRIVATE SDL3::SDL3 imgui) target_compile_definitions(engine_smoke PRIVATE SOKOL_GLCORE) if(EMSCRIPTEN) target_link_options(engine_smoke PRIVATE -sUSE_WEBGL2=1 -sFULL_ES3=1 -sALLOW_MEMORY_GROWTH=1 -sINITIAL_MEMORY=33554432 # 32MB --shell-file=${CMAKE_CURRENT_SOURCE_DIR}/shell.html ) endif() ``` NO usar `add_imgui_app` (esa macro asume GLFW + framework desktop). Esta app es deliberadamente standalone para no contaminar `fn_framework` hasta que validemos el stack. ### 3. main.cpp minimo ```cpp #include #define SOKOL_IMPL #include "sokol_gfx.h" #include "imgui.h" #include "imgui_impl_sdl3.h" #include "imgui_impl_sokol.h" int main(int, char**) { SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); SDL_Window* win = SDL_CreateWindow("engine_smoke", 1280, 720, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); SDL_GLContext ctx = SDL_GL_CreateContext(win); sg_setup({ .environment = sokol_glue_env() }); ImGui::CreateContext(); ImGui_ImplSDL3_InitForOpenGL(win, ctx); ImGui_ImplSokol_Init(); bool running = true; while (running) { SDL_Event e; while (SDL_PollEvent(&e)) { ImGui_ImplSDL3_ProcessEvent(&e); if (e.type == SDL_EVENT_QUIT) running = false; } // render: clear, sprite quad, fullscreen shader, ImGui overlay sg_begin_pass({ .swapchain = sokol_glue_swapchain() }); // ... pipeline + draw calls ImGui_ImplSokol_NewFrame(); ImGui_ImplSDL3_NewFrame(); ImGui::NewFrame(); ImGui::Begin("Smoke"); ImGui::Text("FPS: %.1f", ImGui::GetIO().Framerate); if (ImGui::Button("exit")) running = false; ImGui::End(); ImGui::Render(); ImGui_ImplSokol_RenderDrawData(ImGui::GetDrawData()); sg_end_pass(); sg_commit(); SDL_GL_SwapWindow(win); } sg_shutdown(); return 0; } ``` ### 4. Shell HTML para WASM `shell.html` minimo: canvas + loader. Sin Bootstrap, sin nada extra. Ver Emscripten template default y stripear. ### 5. Pipeline de build Funcion bash nueva: `bash/functions/pipelines/build_wasm_cpp_app.sh` que: 1. Verifica `emcc` instalado (descarga `emsdk` si falta). 2. `emcmake cmake -B build/wasm -S cpp/apps/engine_smoke` 3. `cmake --build build/wasm --target engine_smoke` 4. Reporta tamaños raw + gzip de `.wasm`, `.js`, `.html`. 5. Falla si supera budget. ### 6. e2e_checks en `app.md` ```yaml e2e_checks: - id: build_pc cmd: "cmake --build build --target engine_smoke -j" timeout_s: 300 - id: build_wasm cmd: "bash bash/functions/pipelines/build_wasm_cpp_app.sh engine_smoke" timeout_s: 600 - id: size_budget_wasm cmd: "test $(stat -c%s build/wasm/engine_smoke.wasm.gz) -lt 1572864" # 1.5 MB ``` ## Decisiones a documentar - ¿`sokol_gfx` o usar GL directo? — sokol_gfx, abstrae backend mobile despues sin tocar codigo de juego. - ¿`sokol_app` o `SDL3` para windowing? — SDL3, mejor soporte mobile + audio + gamepad. - ¿Imgui-sokol backend oficial? — verificar `floooh/sokol-samples` repo. Si no, escribirlo (renderable en una sesion, ~200 LoC). ## Criterio de exito - [x] Compila en Linux + Windows (MSVC). - [x] Compila en WASM con emscripten ≥3.1.50. - [x] WASM gzip ≤ 1.5 MB. - [x] Sprite + shader + ImGui visibles en navegador (Chrome + Firefox). - [x] FPS estable ≥60 en navegador moderno. ## Riesgos - Backend ImGui+sokol — si no hay oficial, escribir uno (no bloqueante). - SDL3 still relativamente nuevo (release oct 2024). Si bugs gordos, fallback a SDL2. - Emscripten + sokol_gfx WebGL2 — verificado en `floooh/sokol-samples`, debe funcionar. ## No-objetivos (Fase 0) - NO audio funcional aun. - NO touch input. - NO build mobile (Android/iOS). - NO integracion con `fn_framework`. - NO assets reales.