NUEVAS CARACTERÍSTICAS: - Zoom por profundidad Z: Escala sprites según distancia (0.5x-1.5x) - Toggle con Numpad / (KP_DIVIDE) para activar/desactivar perspectiva - Fix transición figura→física: Reset automático de depth_scale a 1.0 - Texto informativo: "DEPTH ZOOM ON/OFF" IMPLEMENTACIÓN TÉCNICA: - Ball class: Nueva variable depth_scale_ (0.5-1.5) - Ball class: Getters/setters getDepthScale() / setDepthScale() - Engine::addSpriteToBatch(): Parámetro scale con valor defecto 1.0 - Engine::addSpriteToBatch(): Cálculo de vértices escalados centrados - Engine::updateShape(): Cálculo depth_scale = 0.5 + z_normalized * 1.0 - Engine::render(): Pasa depth_scale al batch en modo SHAPE - Engine::toggleShapeMode(): Reset depth_scale en salida de figura - Engine: Variable depth_zoom_enabled_ (true por defecto) - Batch rendering: Mantiene performance (sin llamadas individuales) EFECTO VISUAL: - Pelotas lejanas (Z-): Pequeñas (50%) y oscuras - Pelotas medias (Z=0): Normales (100%) y brillo medio - Pelotas cercanas (Z+): Grandes (150%) y brillantes - Perspectiva 3D realista combinada con Z-sorting CONTROLES: - Numpad /: Toggle zoom por profundidad (solo en modo SHAPE) - Por defecto: ACTIVADO para máximo realismo 3D README ACTUALIZADO: - Añadida tecla KP_/ a tabla de controles - Actualizada sección "Características Técnicas" - Añadida línea "Zoom por profundidad" en características - Actualizada sección "Uso" con control de perspectiva 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
490 lines
18 KiB
Markdown
490 lines
18 KiB
Markdown
# ViBe3 Physics - Simulador de Sprites con Fisica
|
|
|
|
**ViBe3 Physics** es una demo experimental de **vibe-coding** que implementa **nuevas fisicas** expandiendo sobre el sistema de delta time. Utiliza **SDL3** para mostrar sprites (pelotas) rebotando con fisica avanzada independiente del framerate.
|
|
|
|
El nombre refleja su proposito: **ViBe** (vibe-coding experimental) + **Physics** (nuevas fisicas experimentales). La demo sirve como sandbox para probar bucles de juego con timing independiente y renderizado optimizado.
|
|
|
|
## 🎯 Caracteristicas Actuales
|
|
|
|
- **Simulacion de fisica**: Gravedad, rebotes y colisiones con perdida de energia
|
|
- **Multiples escenarios**: 8 configuraciones predefinidas (1 a 100,000 pelotas)
|
|
- **Sistema de temas visuales**: 5 temas de colores con fondos degradados y paletas tematicas
|
|
- **Sistema de zoom dinamico**: F1/F2 para ajustar el zoom de ventana (1x-10x)
|
|
- **Modos fullscreen**: F3 para fullscreen normal, F4 para real fullscreen con resolucion nativa
|
|
- **Gravedad multidireccional**: Gravedad hacia abajo, arriba, izquierda o derecha
|
|
- **Interactividad**: Controles de teclado para modificar el comportamiento
|
|
- **Renderizado batch optimizado**: Sistema de batch rendering con SDL_RenderGeometry para 50K+ sprites
|
|
- **Colores tematicos**: Paletas de 8 colores por tema aplicadas proceduralmente
|
|
- **Monitor de rendimiento**: Contador FPS en tiempo real
|
|
- **Control V-Sync**: Activacion/desactivacion dinamica del V-Sync
|
|
|
|
## 🎮 Controles
|
|
|
|
### Controles de Sistema
|
|
| Tecla | Accion |
|
|
|-------|--------|
|
|
| `H` | **Alternar debug display (FPS, V-Sync, valores fisica)** |
|
|
| `V` | **Alternar V-Sync ON/OFF** |
|
|
| `ESC` | Salir del programa |
|
|
|
|
### Controles de Ventana
|
|
| Tecla | Accion |
|
|
|-------|--------|
|
|
| `F1` | **Zoom out (reducir zoom ventana)** |
|
|
| `F2` | **Zoom in (aumentar zoom ventana)** |
|
|
| `F3` | **Toggle fullscreen normal** |
|
|
| `F4` | **Toggle real fullscreen (resolucion nativa)** |
|
|
|
|
### Controles de Temas
|
|
| Tecla | Accion |
|
|
|-------|--------|
|
|
| `KP_1` | **Tema ATARDECER (colores calidos)** |
|
|
| `KP_2` | **Tema OCEANO (azules y cianes)** |
|
|
| `KP_3` | **Tema NEON (colores vibrantes)** |
|
|
| `KP_4` | **Tema BOSQUE (verdes naturales)** |
|
|
| `KP_5` | **Tema RGB (fondo blanco, colores matematicos)** |
|
|
| `B` | **Ciclar entre todos los temas** |
|
|
|
|
### Controles de Simulacion
|
|
| Tecla | Accion |
|
|
|-------|--------|
|
|
| `1-8` | Cambiar numero de pelotas (1, 10, 100, 500, 1K, 10K, 50K, 100K) |
|
|
| `ESPACIO` | Impulsar todas las pelotas hacia arriba |
|
|
| `↑` | **Gravedad hacia ARRIBA (sale de figura con gravedad)** |
|
|
| `↓` | **Gravedad hacia ABAJO (sale de figura con gravedad)** |
|
|
| `←` | **Gravedad hacia IZQUIERDA (sale de figura con gravedad)** |
|
|
| `→` | **Gravedad hacia DERECHA (sale de figura con gravedad)** |
|
|
| `G` | **Alternar gravedad ON/OFF / Sale de figura SIN gravedad** |
|
|
|
|
### Controles de Figuras 3D
|
|
| Tecla | Accion |
|
|
|-------|--------|
|
|
| `F` | **Toggle entre modo FISICA ↔ última FIGURA 3D** |
|
|
| `Q` | **Activar figura ESFERA (Fibonacci Sphere)** |
|
|
| `W` | **Activar figura WAVE GRID (pendiente)** |
|
|
| `E` | **Activar figura HELIX (pendiente)** |
|
|
| `R` | **Activar figura TORUS (pendiente)** |
|
|
| `T` | **Activar figura CUBO (rotación triple XYZ)** |
|
|
| `Y` | **Activar figura CYLINDER (pendiente)** |
|
|
| `U` | **Activar figura ICOSAHEDRON (pendiente)** |
|
|
| `I` | **Activar figura ATOM (pendiente)** |
|
|
| `KP_+` | **Aumentar escala de figura (+10%)** |
|
|
| `KP_-` | **Reducir escala de figura (-10%)** |
|
|
| `KP_*` | **Reset escala de figura a 100%** |
|
|
| `KP_/` | **Toggle zoom por profundidad Z (perspectiva ON/OFF)** |
|
|
|
|
## 📊 Informacion en Pantalla
|
|
|
|
- **Centro**: Numero de pelotas activas en **blanco** (temporal)
|
|
- **Centro**: Nombre del tema activo en **color tematico** (temporal, debajo del contador)
|
|
|
|
### Debug Display (Tecla `H`)
|
|
|
|
Cuando se activa el debug display con la tecla `H`:
|
|
|
|
- **Esquina superior izquierda**: Estado V-Sync (VSYNC ON/OFF) en **cian**
|
|
- **Esquina superior derecha**: Contador FPS en tiempo real en **amarillo**
|
|
- **Lineas 3-5**: Valores fisica primera pelota (GRAV, VY, SURFACE, LOSS) en **magenta**
|
|
- **Linea 6**: Dirección de gravedad actual (GRAVITY UP/DOWN/LEFT/RIGHT) en **amarillo**
|
|
- **Linea 7**: Tema activo (THEME SUNSET/OCEAN/NEON/FOREST/RGB) en **amarillo claro**
|
|
- **Linea 8**: Modo de simulación (MODE PHYSICS/SPHERE/CUBE/etc.) en **verde claro**
|
|
|
|
## 🎨 Sistema de Temas de Colores
|
|
|
|
**ViBe1 Delta** incluye 5 temas visuales que transforman completamente la apariencia del simulador:
|
|
|
|
### Temas Disponibles
|
|
|
|
| Tecla | Tema | Descripcion | Fondo | Paleta de Pelotas |
|
|
|-------|------|-------------|-------|-------------------|
|
|
| `KP_1` | **ATARDECER** | Colores calidos de puesta de sol | Degradado naranja-rojo | Tonos naranjas, rojos y amarillos |
|
|
| `KP_2` | **OCEANO** | Ambiente marino refrescante | Degradado azul-cian | Azules, cianes y verdes agua |
|
|
| `KP_3` | **NEON** | Colores vibrantes futuristas | Degradado magenta-cian | Magentas, cianes y rosas brillantes |
|
|
| `KP_4` | **BOSQUE** | Naturaleza verde relajante | Degradado verde oscuro-claro | Verdes naturales y tierra |
|
|
| `KP_5` | **RGB** | Colores matematicos puros | Fondo blanco solido | RGB puros y subdivisiones matematicas |
|
|
|
|
### Controles de Temas
|
|
|
|
- **Seleccion directa**: Usa `KP_1`, `KP_2`, `KP_3`, `KP_4` o `KP_5` para cambiar inmediatamente al tema deseado
|
|
- **Ciclado secuencial**: Presiona `B` para avanzar al siguiente tema en orden
|
|
- **Indicador visual**: El nombre del tema aparece temporalmente en el centro de la pantalla con colores tematicos
|
|
- **Regeneracion automatica**: Las pelotas adoptan automaticamente la nueva paleta de colores al cambiar tema
|
|
|
|
### Detalles Tecnicos
|
|
|
|
- **Fondos degradados**: Implementados con `SDL_RenderGeometry` usando vertices con colores interpolados
|
|
- **Paletas tematicas**: 8 colores unicos por tema aplicados aleatoriamente a las pelotas
|
|
- **Rendimiento optimizado**: El cambio de tema solo regenera los colores, manteniendo la fisica
|
|
- **Compatibilidad completa**: Funciona con todos los escenarios (1 a 100,000 pelotas)
|
|
|
|
## 🎯 Sistema de Figuras 3D - Efectos Demoscene
|
|
|
|
**ViBe3 Physics** incluye un sistema polimórfico de figuras 3D que convierte las pelotas en formas geométricas rotantes proyectadas en 2D.
|
|
|
|
### Figuras Implementadas
|
|
|
|
#### 🌐 ESFERA (Tecla Q)
|
|
- **Algoritmo**: Fibonacci Sphere - distribución uniforme de puntos
|
|
- **Rotación**: Dual (ejes X e Y)
|
|
- **Efecto**: Esfera rotante clásica estilo demoscene
|
|
|
|
#### 🎲 CUBO (Tecla T)
|
|
- **Distribución inteligente**:
|
|
- 1-8 pelotas: Solo vértices (8 puntos)
|
|
- 9-26 pelotas: Vértices + centros de caras + aristas (26 puntos)
|
|
- 27+ pelotas: Grid volumétrico 3D uniforme
|
|
- **Rotación**: Triple (ejes X, Y y Z simultáneos)
|
|
- **Efecto**: Cubo Rubik rotante
|
|
|
|
#### 🔮 Figuras Futuras (Pendientes)
|
|
- **W - WAVE GRID**: Malla ondeante 3D
|
|
- **E - HELIX**: Espiral helicoidal
|
|
- **R - TORUS**: Donut/toroide
|
|
- **Y - CYLINDER**: Cilindro rotante
|
|
- **U - ICOSAHEDRON**: Poliedro D20
|
|
- **I - ATOM**: Núcleo con órbitas electrónicas
|
|
|
|
### Características Técnicas
|
|
|
|
- **Física de atracción**: Sistema spring-damper (Hooke's Law) para transición suave
|
|
- **Profundidad Z simulada**: Color modulado según distancia (oscuro=fondo, brillante=frente)
|
|
- **Zoom por profundidad**: Perspectiva 3D con escala variable (50%-150% según Z)
|
|
- **Z-sorting**: Painter's Algorithm para oclusión correcta
|
|
- **Escala dinámica**: Control manual con Numpad +/- (30% - 300%)
|
|
- **Protección de clipping**: Escala limitada automáticamente según resolución
|
|
- **Sin sprites adicionales**: Usa `SDL_SetTextureColorMod` y vértices escalados para efectos 3D
|
|
|
|
### Parámetros Físicos (defines.h)
|
|
|
|
```cpp
|
|
// Física compartida entre todas las figuras
|
|
ROTOBALL_SPRING_K = 300.0f; // Rigidez del resorte (N/m)
|
|
ROTOBALL_DAMPING_BASE = 35.0f; // Amortiguación crítica
|
|
ROTOBALL_DAMPING_NEAR = 80.0f; // Absorción cerca del punto
|
|
|
|
// Esfera
|
|
ROTOBALL_RADIUS_FACTOR = 0.333f; // 33% de altura de pantalla
|
|
ROTOBALL_ROTATION_SPEED_Y = 1.5f; // rad/s (eje Y)
|
|
ROTOBALL_ROTATION_SPEED_X = 0.8f; // rad/s (eje X)
|
|
|
|
// Cubo
|
|
CUBE_SIZE_FACTOR = 0.25f; // 25% de altura de pantalla
|
|
CUBE_ROTATION_SPEED_X = 0.5f; // rad/s
|
|
CUBE_ROTATION_SPEED_Y = 0.7f; // rad/s
|
|
CUBE_ROTATION_SPEED_Z = 0.3f; // rad/s
|
|
|
|
// Control manual de escala
|
|
SHAPE_SCALE_MIN = 0.3f; // Mínimo 30%
|
|
SHAPE_SCALE_MAX = 3.0f; // Máximo 300%
|
|
SHAPE_SCALE_STEP = 0.1f; // Incremento 10%
|
|
```
|
|
|
|
### Cómo Funciona
|
|
|
|
1. **Generación**: Algoritmo específico distribuye puntos en forma 3D
|
|
2. **Rotación**: Matrices de rotación 3D aplicadas en tiempo real
|
|
3. **Escala**: Factor manual multiplicado a coordenadas y física
|
|
4. **Proyección**: Coordenadas 3D → 2D (ortográfica)
|
|
5. **Z-sorting**: Ordenar pelotas por profundidad (fondo primero)
|
|
6. **Profundidad**: Componente Z controla brillo del color
|
|
7. **Renderizado**: Batch rendering con color modulado
|
|
|
|
### Uso
|
|
|
|
- **Activación**: Presiona Q/W/E/R/T/Y/U/I para figura específica, o F para toggle
|
|
- **Escala**: Usa Numpad +/- para ajustar tamaño, * para reset
|
|
- **Perspectiva**: Numpad / para activar/desactivar zoom por profundidad (ON por defecto)
|
|
- **Salir**: G (sin gravedad), cursores (con gravedad), F (toggle), o 1-8 (cambiar escenario)
|
|
- **Compatible**: Funciona con 1-100,000 pelotas
|
|
- **Temas**: Mantiene paleta de colores activa
|
|
|
|
## 🏗️ Estructura del Proyecto
|
|
|
|
```
|
|
vibe3_physics/
|
|
├── source/
|
|
│ ├── main.cpp # Bucle principal y logica del juego
|
|
│ ├── engine.h/cpp # Motor principal con loop y rendering
|
|
│ ├── ball.h/cpp # Clase Ball - fisica de pelotas
|
|
│ ├── defines.h # Constantes y configuracion
|
|
│ ├── shapes/ # Sistema polimorfico de figuras 3D
|
|
│ │ ├── shape.h # Interfaz abstracta Shape
|
|
│ │ ├── sphere_shape.h/cpp # Fibonacci Sphere
|
|
│ │ └── cube_shape.h/cpp # Cubo rotante triple
|
|
│ └── external/ # Utilidades y bibliotecas externas
|
|
│ ├── sprite.h/cpp # Clase Sprite - renderizado de texturas
|
|
│ ├── texture.h/cpp # Clase Texture - gestion de imagenes
|
|
│ ├── dbgtxt.h # Sistema de debug para texto en pantalla
|
|
│ └── stb_image.h # Biblioteca para cargar imagenes
|
|
├── data/
|
|
│ └── ball.png # Textura de la pelota (10x10 pixeles)
|
|
├── CMakeLists.txt # Configuracion de CMake
|
|
├── Makefile # Configuracion de Make
|
|
├── CLAUDE.md # Seguimiento de desarrollo
|
|
└── .gitignore # Archivos ignorados por Git
|
|
```
|
|
|
|
## 🔧 Requisitos del Sistema
|
|
|
|
- **SDL3** (Simple DirectMedia Layer 3)
|
|
- **C++20** compatible compiler
|
|
- **CMake 3.20+** o **Make**
|
|
- Plataforma: Windows, Linux, macOS
|
|
|
|
### Instalacion de SDL3
|
|
|
|
#### Windows (MinGW)
|
|
```bash
|
|
# Usando vcpkg o compilar desde fuente
|
|
vcpkg install sdl3
|
|
```
|
|
|
|
#### Linux
|
|
```bash
|
|
# Ubuntu/Debian
|
|
sudo apt install libsdl3-dev
|
|
# Arch Linux
|
|
sudo pacman -S sdl3
|
|
```
|
|
|
|
#### macOS
|
|
```bash
|
|
brew install sdl3
|
|
```
|
|
|
|
## 🚀 Compilacion
|
|
|
|
### Opcion 1: CMake (Recomendado)
|
|
```bash
|
|
mkdir build && cd build
|
|
cmake ..
|
|
make
|
|
```
|
|
|
|
### Opcion 2: Make directo
|
|
```bash
|
|
make
|
|
```
|
|
|
|
## ▶️ Ejecucion
|
|
|
|
```bash
|
|
# Desde la raiz del proyecto
|
|
./vibe3_physics # Linux/macOS
|
|
./vibe3_physics.exe # Windows
|
|
```
|
|
|
|
## 📊 Detalles Tecnicos
|
|
|
|
### Configuracion Actual
|
|
- **Resolucion**: 640x360 pixeles (escalado x2 = 1280x720)
|
|
- **Sistema de timing**: Delta time independiente del framerate
|
|
- **Fisica**: Gravedad constante (0.2f), rebotes con perdida de energia
|
|
- **Tamaño de pelota**: 10x10 pixeles
|
|
- **V-Sync**: Activado por defecto, controlable dinamicamente
|
|
|
|
### Arquitectura del Codigo
|
|
|
|
1. **main.cpp**: Contiene el bucle principal con cuatro fases:
|
|
- `calculateDeltaTime()`: Calcula tiempo transcurrido entre frames
|
|
- `update()`: Actualiza la logica del juego usando delta time + calculo FPS
|
|
- `checkEvents()`: Procesa eventos de entrada
|
|
- `render()`: Renderiza la escena + overlays informativos
|
|
|
|
2. **Ball**: Maneja la fisica de cada pelota individual con timing basado en delta time
|
|
3. **Sprite**: Sistema de renderizado de texturas con filtro nearest neighbor
|
|
4. **Texture**: Gestion de carga y renderizado de imagenes con filtro pixel-perfect
|
|
|
|
## ✅ Migracion a Delta Time (COMPLETADO)
|
|
|
|
### Sistema Anterior (Frame-Based)
|
|
|
|
El sistema original estaba **acoplado a 60 FPS** con logica dependiente del framerate:
|
|
|
|
```cpp
|
|
// Sistema ANTIGUO en update()
|
|
if (SDL_GetTicks() - ticks > DEMO_SPEED) { // DEMO_SPEED = 1000/60 = 16.67ms
|
|
// Solo aqui se actualizaba la fisica cada 16.67ms
|
|
for (auto &ball : balls) {
|
|
ball->update(); // Sin parametros de tiempo
|
|
}
|
|
ticks = SDL_GetTicks();
|
|
}
|
|
```
|
|
|
|
**Problemas del sistema anterior:**
|
|
- Velocidad inconsistente entre diferentes refresh rates (60Hz vs 75Hz vs 144Hz)
|
|
- Logica de fisica acoplada a framerate fijo
|
|
- V-Sync ON/OFF cambiaba la velocidad del juego
|
|
- Rendimiento inconsistente en diferentes hardware
|
|
|
|
### Sistema Actual (Delta Time)
|
|
|
|
**Implementacion delta time** para simulacion independiente del framerate:
|
|
|
|
```cpp
|
|
// Sistema NUEVO - Variables globales
|
|
Uint64 last_frame_time = 0;
|
|
float delta_time = 0.0f;
|
|
|
|
// Calculo de delta time
|
|
void calculateDeltaTime() {
|
|
Uint64 current_time = SDL_GetTicks();
|
|
if (last_frame_time == 0) {
|
|
last_frame_time = current_time;
|
|
delta_time = 1.0f / 60.0f; // Primer frame a 60 FPS
|
|
return;
|
|
}
|
|
|
|
delta_time = (current_time - last_frame_time) / 1000.0f; // Convertir a segundos
|
|
last_frame_time = current_time;
|
|
|
|
// Limitar delta time para evitar saltos grandes
|
|
if (delta_time > 0.05f) {
|
|
delta_time = 1.0f / 60.0f; // Fallback a 60 FPS
|
|
}
|
|
}
|
|
|
|
// Bucle principal actualizado
|
|
while (!should_exit) {
|
|
calculateDeltaTime(); // 1. Calcular tiempo transcurrido
|
|
update(); // 2. Actualizar logica (usa delta_time)
|
|
checkEvents(); // 3. Procesar entrada
|
|
render(); // 4. Renderizar escena
|
|
}
|
|
```
|
|
|
|
### Conversion de Fisica: Frame-Based → Time-Based
|
|
|
|
#### 1. Conversion de Velocidades
|
|
|
|
```cpp
|
|
// En Ball::Ball() constructor
|
|
// ANTES: velocidades en pixeles/frame
|
|
vx_ = vx;
|
|
vy_ = vy;
|
|
|
|
// AHORA: convertir a pixeles/segundo (x60)
|
|
vx_ = vx * 60.0f;
|
|
vy_ = vy * 60.0f;
|
|
```
|
|
|
|
#### 2. Conversion de Gravedad (Aceleracion)
|
|
|
|
```cpp
|
|
// En Ball::Ball() constructor
|
|
// ANTES: gravedad en pixeles/frame²
|
|
gravity_force_ = GRAVITY_FORCE;
|
|
|
|
// AHORA: convertir a pixeles/segundo² (x60²)
|
|
gravity_force_ = GRAVITY_FORCE * 60.0f * 60.0f; // 3600x multiplicador
|
|
```
|
|
|
|
**¿Por que 60² para gravedad?**
|
|
- Velocidad: `pixeles/frame * frame/segundo = pixeles/segundo` → **x60**
|
|
- Aceleracion: `pixeles/frame² * frame²/segundo² = pixeles/segundo²` → **x60²**
|
|
|
|
#### 3. Aplicacion de Delta Time en Fisica
|
|
|
|
```cpp
|
|
// En Ball::update(float deltaTime)
|
|
// ANTES: incrementos fijos por frame
|
|
vy_ += gravity_force_;
|
|
pos_.x += vx_;
|
|
pos_.y += vy_;
|
|
|
|
// AHORA: incrementos proporcionales al tiempo transcurrido
|
|
vy_ += gravity_force_ * deltaTime; // Aceleracion * tiempo
|
|
pos_.x += vx_ * deltaTime; // Velocidad * tiempo
|
|
pos_.y += vy_ * deltaTime;
|
|
```
|
|
|
|
### Valores de Debug: Antes vs Ahora
|
|
|
|
| Parametro | Sistema Anterior | Sistema Delta Time | Razon |
|
|
|-----------|------------------|-------------------|-------|
|
|
| **Velocidad X/Y** | 1.0 - 3.0 pixeles/frame | 60.0 - 180.0 pixeles/segundo | x60 conversion |
|
|
| **Gravedad** | 0.2 pixeles/frame² | 720.0 pixeles/segundo² | x3600 conversion |
|
|
| **Debug Display** | No disponible | GRAV: 720.000000 VY: -140.5 FLOOR: NO | Valores en tiempo real |
|
|
|
|
### Beneficios Conseguidos
|
|
|
|
- ✅ **Velocidad consistente** entre 60Hz, 75Hz, 144Hz y otros refresh rates
|
|
- ✅ **V-Sync independiente**: misma velocidad con V-Sync ON/OFF
|
|
- ✅ **Fisica precisa**: gravedad y movimiento calculados correctamente
|
|
- ✅ **Escalabilidad**: preparado para futuras optimizaciones
|
|
- ✅ **Debug en tiempo real**: monitoreo de valores de fisica
|
|
|
|
### Sistema de Debug Implementado
|
|
|
|
```cpp
|
|
// Debug display para primera pelota
|
|
if (!balls.empty()) {
|
|
std::string debug_text = "GRAV: " + std::to_string(balls[0]->getGravityForce()) +
|
|
" VY: " + std::to_string(balls[0]->getVelocityY()) +
|
|
" FLOOR: " + (balls[0]->isOnFloor() ? "YES" : "NO");
|
|
dbg_print(8, 24, debug_text.c_str(), 255, 0, 255); // Magenta
|
|
}
|
|
```
|
|
|
|
## 🚀 Sistema de Batch Rendering
|
|
|
|
### **Problema Original**
|
|
El renderizado individual de sprites era el principal cuello de botella:
|
|
- **50,000 bolas**: 50,000 llamadas `SDL_RenderTexture()` por frame
|
|
- **Resultado**: ~10 FPS (inutilizable)
|
|
|
|
### **Solución Implementada: SDL_RenderGeometry**
|
|
Batch rendering que agrupa todos los sprites en una sola llamada:
|
|
|
|
```cpp
|
|
// Recopilar datos de todas las bolas
|
|
for (auto &ball : balls) {
|
|
SDL_FRect pos = ball->getPosition();
|
|
Color color = ball->getColor();
|
|
addSpriteToBatch(pos.x, pos.y, pos.w, pos.h, color.r, color.g, color.b);
|
|
}
|
|
|
|
// Renderizar TODAS las bolas en una sola llamada
|
|
SDL_RenderGeometry(renderer, texture->getSDLTexture(),
|
|
batch_vertices.data(), batch_vertices.size(),
|
|
batch_indices.data(), batch_indices.size());
|
|
```
|
|
|
|
### **Arquitectura del Batch**
|
|
1. **Vértices**: 4 vértices por sprite (quad) con posición, UV y color
|
|
2. **Índices**: 6 índices por sprite (2 triángulos)
|
|
3. **Acumulación**: Todos los sprites se acumulan en vectores globales
|
|
4. **Renderizado**: Una sola llamada `SDL_RenderGeometry` por frame
|
|
|
|
### **Rendimiento Conseguido**
|
|
- **50,000 bolas**: >75 FPS constante (mejora de 750%)
|
|
- **100,000 bolas**: Fluido y jugable
|
|
- **Escalabilidad**: Preparado para renderizado masivo de sprites
|
|
|
|
## 🛠️ Desarrollo
|
|
|
|
Para contribuir al proyecto:
|
|
|
|
1. Fork del repositorio
|
|
2. Crear rama de feature (`git checkout -b feature/nueva-caracteristica`)
|
|
3. Commit de cambios (`git commit -am 'Añadir nueva caracteristica'`)
|
|
4. Push a la rama (`git push origin feature/nueva-caracteristica`)
|
|
5. Crear Pull Request
|
|
|
|
## 📝 Notas Tecnicas
|
|
|
|
- El proyecto usa **smart pointers** (unique_ptr, shared_ptr) para gestion de memoria
|
|
- **RAII** para recursos SDL
|
|
- **Separacion de responsabilidades** entre clases
|
|
- **Configuracion multiplataforma** (Windows, Linux, macOS)
|
|
- **Filtro nearest neighbor** para texturas pixel-perfect
|
|
- **Sistema de metricas** en tiempo real (FPS, V-Sync)
|
|
|
|
## 🐛 Problemas Conocidos
|
|
|
|
Ninguno conocido. El sistema esta completamente funcional con delta time implementado.
|
|
|
|
---
|
|
|
|
*Proyecto desarrollado como base para experimentacion con game loops y fisica en tiempo real usando SDL3.* |