fad4006f60
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
173 lines
5.5 KiB
Markdown
173 lines
5.5 KiB
Markdown
---
|
|
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 <SDL3/SDL.h>
|
|
#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.
|