docs: detalla el pipeline de shaders i la física al document d'arquitectura
This commit is contained in:
+80
-24
@@ -378,19 +378,41 @@ OFF, la escena offscreen sale tal cual (passthrough), útil para A/B testing.
|
|||||||
- **[Curtain](source/core/graphics/curtain.hpp)** — cortinilla negra para
|
- **[Curtain](source/core/graphics/curtain.hpp)** — cortinilla negra para
|
||||||
transiciones; se pinta siempre la última.
|
transiciones; se pinta siempre la última.
|
||||||
|
|
||||||
### 5.5 Shaders
|
### 5.5 Shaders: fuentes, compilación y selección
|
||||||
|
|
||||||
Las fuentes GLSL viven en [shaders/](shaders/) (`line.vert/frag`, `bloom.frag`,
|
Las fuentes GLSL viven en [shaders/](shaders/): `line.vert.glsl`, `line.frag.glsl`,
|
||||||
`postfx.vert/frag`). Se compilan a SPIR-V (Linux/Windows) y MSL (macOS) y se
|
`postfx.vert.glsl`, `postfx.frag.glsl`, `bloom.frag.glsl`. **No se cargan de disco en
|
||||||
**embeben** como cabeceras en el binario: ver
|
runtime**: se embeben como arrays/strings en el binario.
|
||||||
[gpu/spv/](source/core/rendering/gpu/spv/) y [gpu/msl/](source/core/rendering/gpu/msl/).
|
|
||||||
La selección por plataforma la hace el `GpuDevice`. No se cargan shaders de disco
|
|
||||||
en runtime.
|
|
||||||
|
|
||||||
> No verificado en detalle: los pormenores del pipeline de compilación de shaders
|
**Pipeline de compilación (SPIR-V, Linux/Windows).** Lo orquesta
|
||||||
> (qué target de CMake genera los `.spv.h`/`.msl.h`). Los headers embebidos existen
|
[CMakeLists.txt:139-187](CMakeLists.txt#L139). La lógica clave:
|
||||||
> y se referencian desde las pipelines; el mecanismo exacto de generación habría que
|
|
||||||
> confirmarlo en [CMakeLists.txt](CMakeLists.txt) y [tools/shaders/](tools/shaders/).
|
- Para cada `.glsl` hay un header destino en
|
||||||
|
[gpu/spv/](source/core/rendering/gpu/spv/) (p. ej. `line_vert_spv.h`).
|
||||||
|
- CMake busca `glslc` (`find_program(GLSLC_EXE ...)`). Hay **tres caminos**:
|
||||||
|
1. `glslc` presente → un `add_custom_command` regenera los headers SPV cuando
|
||||||
|
cambian los `.glsl`, vía el target `shaders` del que depende el ejecutable.
|
||||||
|
2. `glslc` ausente pero **los headers ya están commiteados** → se usan tal cual
|
||||||
|
(los `.spv.h` están versionados en el repo).
|
||||||
|
3. `glslc` ausente **y** faltan headers → `FATAL_ERROR` pidiendo instalar
|
||||||
|
`shaderc`/`vulkan-sdk`.
|
||||||
|
- La conversión binario→header la hace el script
|
||||||
|
[tools/shaders/compile_spirv.cmake](tools/shaders/compile_spirv.cmake): invoca
|
||||||
|
`glslc -O -fshader-stage=<vert|frag>` para producir el `.spv`, lee el binario como
|
||||||
|
hex (`file(READ ... HEX)`) y escribe un header con
|
||||||
|
`static const uint8_t LINE_VERT_SPV[] = { 0x.., ... };` y su `_SIZE`. Es
|
||||||
|
multiplataforma puro CMake (no necesita `bash` ni `xxd`).
|
||||||
|
|
||||||
|
**MSL (macOS).** Los headers Metal en [gpu/msl/](source/core/rendering/gpu/msl/)
|
||||||
|
(`line_vert.msl.h`, etc.) están **escritos a mano** (no los genera CMake), como
|
||||||
|
strings literales C++.
|
||||||
|
|
||||||
|
**Selección SPV vs MSL: es _compile-time_, no runtime.** La hace
|
||||||
|
[shader_factory.hpp](source/core/rendering/gpu/shader_factory.hpp) con `#ifdef __APPLE__`:
|
||||||
|
en Apple expone `createShaderMSL(...)` (`SDL_GPU_SHADERFORMAT_MSL`), y en el resto
|
||||||
|
`createShaderSPIRV(...)` (`SDL_GPU_SHADERFORMAT_SPIRV`). Cada pipeline llama al helper
|
||||||
|
disponible con el header embebido correspondiente. (Es decir: no es `GpuDevice` quien
|
||||||
|
elige el backend de shader, sino el preprocesador al compilar.)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -637,6 +659,43 @@ primer toque y muere al segundo durante ese estado.
|
|||||||
[StageLoader](source/game/stage_system/stage_loader.hpp) — modelo y carga del
|
[StageLoader](source/game/stage_system/stage_loader.hpp) — modelo y carga del
|
||||||
YAML de stages.
|
YAML de stages.
|
||||||
|
|
||||||
|
### 10.6 Dos capas de colisión: física vs gameplay
|
||||||
|
|
||||||
|
Conviene no confundirlas, porque conviven:
|
||||||
|
|
||||||
|
**1. Física** — [PhysicsWorld](source/core/physics/physics_world.hpp) /
|
||||||
|
[physics_world.cpp](source/core/physics/physics_world.cpp). Es un mundo 2D
|
||||||
|
minimalista de arcade. Cada frame, `update(dt)` hace tres pasos:
|
||||||
|
|
||||||
|
1. **Integración** semi-implícita de Euler con damping exponencial
|
||||||
|
(`v += (F·invMass)·dt; v *= exp(-damping·dt); x += v·dt`) sobre cada
|
||||||
|
[RigidBody](source/core/physics/rigid_body.hpp) no estático. Un cuerpo con
|
||||||
|
`mass=0` (`inverse_mass=0`) es estático (masa infinita).
|
||||||
|
2. **Rebote contra los bordes** del `PLAYAREA` (`resolveBoundsCollisions`): reposiciona
|
||||||
|
el cuerpo dentro del rect y refleja la componente normal de la velocidad por su
|
||||||
|
`restitution`. Antes de reflejar, invoca un `BoundsHitCallback` opcional con la
|
||||||
|
velocidad de impacto entrante (lo usa GameScene para los efectos de borde).
|
||||||
|
3. **Colisiones cuerpo-cuerpo** (`resolveBodyCollisions`): broadphase trivial
|
||||||
|
**O(n²)** (suficiente para ~23 cuerpos), círculo-círculo, con corrección posicional
|
||||||
|
de penetración + **impulso elástico** `j = -(1+e)(v_rel·n) / (1/mₐ + 1/m_b)`
|
||||||
|
(referencia Box2D / Chris Hecker, en `resolveBodyPair`). Los cuerpos con `radius=0`
|
||||||
|
(las balas, cinemáticas puras) **no** participan aquí.
|
||||||
|
|
||||||
|
Los `RigidBody` los poseen las entidades; el mundo solo guarda punteros no-owning
|
||||||
|
(`addBody`/`removeBody`).
|
||||||
|
|
||||||
|
**2. Gameplay** — [collision_system.cpp](source/game/systems/collision_system.cpp)
|
||||||
|
(ver [§10.4](#104-colisiones)), que decide *qué pasa* (daño, score, muerte). Usa los
|
||||||
|
helpers de [collision.hpp](source/core/physics/collision.hpp): `checkCollision`
|
||||||
|
(círculo-círculo discreto, distancia al cuadrado sin `sqrt`) y `checkCollisionSwept`
|
||||||
|
(segment-círculo, para que una bala rápida no atraviese un enemigo entre frames —
|
||||||
|
*anti-tunneling*). Estos checks usan el `collision_radius` de la **entidad**
|
||||||
|
(con amplificador opcional de hitbox), no el `radius` del body.
|
||||||
|
|
||||||
|
En resumen: la **física** mueve y rebota los cuerpos; el **gameplay** detecta los
|
||||||
|
contactos relevantes para las reglas. Una bala no rebota físicamente (radius 0) pero sí
|
||||||
|
provoca daño vía el check *swept*.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 11. IA del modo demo (attract)
|
## 11. IA del modo demo (attract)
|
||||||
@@ -765,18 +824,15 @@ Viven en [game/effects/](source/game/effects/) y son managers con pools:
|
|||||||
|
|
||||||
### Notas de honestidad sobre la cobertura
|
### Notas de honestidad sobre la cobertura
|
||||||
|
|
||||||
- Las secciones de **render** ([§5](#5-renderizado-de-la-lógica-al-píxel)), **bucle**
|
- Todas las secciones se verificaron leyendo directamente los ficheros y firmas
|
||||||
([§3](#3-bucle-principal)), **escenas** ([§4](#4-sistema-de-escenas)), **eventos
|
citados, incluyendo el **pipeline de compilación de shaders**
|
||||||
globales** ([§9](#9-comunicación-entre-módulos)), **GameScene/IA demo**
|
([§5.5](#55-shaders-fuentes-compilación-y-selección): `CMakeLists.txt` +
|
||||||
([§10](#10-lógica-del-juego)–[§11](#11-ia-del-modo-demo-attract)) se verificaron
|
`tools/shaders/compile_spirv.cmake` + `shader_factory.hpp`) y el interior de la
|
||||||
leyendo directamente los ficheros y firmas citados.
|
**física** ([§10.6](#106-dos-capas-de-colisión-física-vs-gameplay):
|
||||||
- El **pipeline de compilación de shaders** (cómo se generan los `.spv.h`/`.msl.h`)
|
`physics_world.cpp` + `collision.hpp` + `rigid_body.hpp`).
|
||||||
no se ha trazado al detalle; los headers embebidos existen y se usan, pero el
|
- Lo que **no** se ha trazado a fondo y queda como lectura directa del código si hace
|
||||||
paso de build exacto queda por confirmar en [CMakeLists.txt](CMakeLists.txt) /
|
falta: los detalles finos de animación de cada overlay (curvas de easing del
|
||||||
[tools/shaders/](tools/shaders/).
|
`Notifier`/`ServiceMenu`) y la coreografía interna completa de `LogoScene` y
|
||||||
- El detalle interno de la **PhysicsWorld** (algoritmo de resolución de colisiones
|
`TitleScene` (más allá de sus estados). Son descriptivos, no estructurales.
|
||||||
físicas) se ha descrito a alto nivel; para el detalle, ver
|
|
||||||
[physics_world.cpp](source/core/physics/physics_world.cpp) y
|
|
||||||
[collision.hpp](source/core/physics/collision.hpp).
|
|
||||||
</content>
|
</content>
|
||||||
</invoke>
|
</invoke>
|
||||||
|
|||||||
Reference in New Issue
Block a user