refactor: constantes SCENE_BALLS_N y fix HUD overlay en SHAPE mode
- defines.hpp: añadir SCENE_BALLS_1..8 (topado en 50K), SCENARIO_COUNT, reconstruir BALL_COUNT_SCENARIOS con esas constantes - theme_manager: añadir max_ball_count_ y setMaxBallCount() para capturar colores hasta el máximo real (custom incluido), eliminando literal 50000 - engine.cpp: llamar setMaxBallCount() tras inicializar ThemeManager - gpu_sprite_batch: addFullscreenOverlay() escribe vértices directamente sin pasar por el guard de pushQuad(), igual que addBackground(); esto corrige el HUD/overlay invisible en SHAPE mode con escenario 8 (50K bolas) - Textos UI actualizados: tecla 8, help overlay y --skip-benchmark → 50.000 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -59,10 +59,22 @@ constexpr float BALL_SPAWN_MARGIN = 0.15f; // Margen lateral para spawn (0.25 =
|
|||||||
|
|
||||||
// Escenarios de número de pelotas (teclas 1-8)
|
// Escenarios de número de pelotas (teclas 1-8)
|
||||||
// Fase 1 (instanced rendering): límit pràctic ~100K a 60fps (physics bound)
|
// Fase 1 (instanced rendering): límit pràctic ~100K a 60fps (physics bound)
|
||||||
constexpr int BALL_COUNT_SCENARIOS[8] = {10, 50, 100, 500, 1000, 5000, 10000, 100000};
|
constexpr int SCENE_BALLS_1 = 10;
|
||||||
|
constexpr int SCENE_BALLS_2 = 50;
|
||||||
|
constexpr int SCENE_BALLS_3 = 100;
|
||||||
|
constexpr int SCENE_BALLS_4 = 500;
|
||||||
|
constexpr int SCENE_BALLS_5 = 1000;
|
||||||
|
constexpr int SCENE_BALLS_6 = 5000;
|
||||||
|
constexpr int SCENE_BALLS_7 = 10000;
|
||||||
|
constexpr int SCENE_BALLS_8 = 50000; // Máximo escenario estándar (tecla 8)
|
||||||
|
|
||||||
|
constexpr int SCENARIO_COUNT = 8;
|
||||||
|
constexpr int BALL_COUNT_SCENARIOS[SCENARIO_COUNT] = {
|
||||||
|
SCENE_BALLS_1, SCENE_BALLS_2, SCENE_BALLS_3, SCENE_BALLS_4,
|
||||||
|
SCENE_BALLS_5, SCENE_BALLS_6, SCENE_BALLS_7, SCENE_BALLS_8
|
||||||
|
};
|
||||||
|
|
||||||
// Límites de escenario para modos automáticos (índices en BALL_COUNT_SCENARIOS)
|
// Límites de escenario para modos automáticos (índices en BALL_COUNT_SCENARIOS)
|
||||||
// BALL_COUNT_SCENARIOS = {10, 50, 100, 500, 1000, 5000, 10000, 50000}
|
|
||||||
// 0 1 2 3 4 5 6 7
|
// 0 1 2 3 4 5 6 7
|
||||||
constexpr int DEMO_AUTO_MIN_SCENARIO = 2; // mínimo 100 bolas
|
constexpr int DEMO_AUTO_MIN_SCENARIO = 2; // mínimo 100 bolas
|
||||||
constexpr int DEMO_AUTO_MAX_SCENARIO = 7; // máximo sin restricción hardware (ajustado por benchmark)
|
constexpr int DEMO_AUTO_MAX_SCENARIO = 7; // máximo sin restricción hardware (ajustado por benchmark)
|
||||||
|
|||||||
@@ -282,6 +282,12 @@ bool Engine::initialize(int width, int height, int zoom, bool fullscreen, AppMod
|
|||||||
// Inicializar ThemeManager PRIMERO (requerido por Notifier y SceneManager)
|
// Inicializar ThemeManager PRIMERO (requerido por Notifier y SceneManager)
|
||||||
theme_manager_ = std::make_unique<ThemeManager>();
|
theme_manager_ = std::make_unique<ThemeManager>();
|
||||||
theme_manager_->initialize();
|
theme_manager_->initialize();
|
||||||
|
{
|
||||||
|
int max_balls = BALL_COUNT_SCENARIOS[DEMO_AUTO_MAX_SCENARIO];
|
||||||
|
if (custom_scenario_enabled_ && custom_scenario_balls_ > max_balls)
|
||||||
|
max_balls = custom_scenario_balls_;
|
||||||
|
theme_manager_->setMaxBallCount(max_balls);
|
||||||
|
}
|
||||||
|
|
||||||
// Inicializar SceneManager (gestión de bolas y física)
|
// Inicializar SceneManager (gestión de bolas y física)
|
||||||
scene_manager_ = std::make_unique<SceneManager>(current_screen_width_, current_screen_height_);
|
scene_manager_ = std::make_unique<SceneManager>(current_screen_width_, current_screen_height_);
|
||||||
|
|||||||
@@ -9,10 +9,10 @@
|
|||||||
|
|
||||||
bool GpuSpriteBatch::init(SDL_GPUDevice* device, int max_sprites) {
|
bool GpuSpriteBatch::init(SDL_GPUDevice* device, int max_sprites) {
|
||||||
max_sprites_ = max_sprites;
|
max_sprites_ = max_sprites;
|
||||||
// Pre-allocate GPU buffers large enough for (max_sprites_ + 1) quads.
|
// Pre-allocate GPU buffers large enough for (max_sprites_ + 2) quads.
|
||||||
// The +1 reserves a guaranteed slot for the fullscreen overlay.
|
// The +2 reserves one slot for the background quad and one for the fullscreen overlay.
|
||||||
Uint32 max_verts = static_cast<Uint32>(max_sprites_ + 1) * 4;
|
Uint32 max_verts = static_cast<Uint32>(max_sprites_ + 2) * 4;
|
||||||
Uint32 max_indices = static_cast<Uint32>(max_sprites_ + 1) * 6;
|
Uint32 max_indices = static_cast<Uint32>(max_sprites_ + 2) * 6;
|
||||||
|
|
||||||
Uint32 vb_size = max_verts * sizeof(GpuVertex);
|
Uint32 vb_size = max_verts * sizeof(GpuVertex);
|
||||||
Uint32 ib_size = max_indices * sizeof(uint32_t);
|
Uint32 ib_size = max_indices * sizeof(uint32_t);
|
||||||
@@ -55,8 +55,8 @@ bool GpuSpriteBatch::init(SDL_GPUDevice* device, int max_sprites) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
vertices_.reserve(static_cast<size_t>(max_sprites_ + 1) * 4);
|
vertices_.reserve(static_cast<size_t>(max_sprites_ + 2) * 4);
|
||||||
indices_.reserve(static_cast<size_t>(max_sprites_ + 1) * 6);
|
indices_.reserve(static_cast<size_t>(max_sprites_ + 2) * 6);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,10 +130,17 @@ void GpuSpriteBatch::addSprite(float x, float y, float w, float h,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GpuSpriteBatch::addFullscreenOverlay() {
|
void GpuSpriteBatch::addFullscreenOverlay() {
|
||||||
|
// El overlay es un slot reservado fuera del espacio de max_sprites_, igual que el background.
|
||||||
|
// Escribe directamente sin pasar por el guard de pushQuad().
|
||||||
overlay_index_offset_ = static_cast<int>(indices_.size());
|
overlay_index_offset_ = static_cast<int>(indices_.size());
|
||||||
size_t before = indices_.size();
|
uint32_t vi = static_cast<uint32_t>(vertices_.size());
|
||||||
pushQuad(-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
|
vertices_.push_back({ -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f });
|
||||||
overlay_index_count_ = static_cast<int>(indices_.size() - before); // 0 si pushQuad falló, 6 si ok
|
vertices_.push_back({ 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f });
|
||||||
|
vertices_.push_back({ 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f });
|
||||||
|
vertices_.push_back({ -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f });
|
||||||
|
indices_.push_back(vi + 0); indices_.push_back(vi + 1); indices_.push_back(vi + 2);
|
||||||
|
indices_.push_back(vi + 2); indices_.push_back(vi + 3); indices_.push_back(vi + 0);
|
||||||
|
overlay_index_count_ = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GpuSpriteBatch::uploadBatch(SDL_GPUDevice* device, SDL_GPUCommandBuffer* cmd_buf) {
|
bool GpuSpriteBatch::uploadBatch(SDL_GPUDevice* device, SDL_GPUCommandBuffer* cmd_buf) {
|
||||||
@@ -182,7 +189,8 @@ void GpuSpriteBatch::toNDC(float px, float py,
|
|||||||
void GpuSpriteBatch::pushQuad(float ndx0, float ndy0, float ndx1, float ndy1,
|
void GpuSpriteBatch::pushQuad(float ndx0, float ndy0, float ndx1, float ndy1,
|
||||||
float u0, float v0, float u1, float v1,
|
float u0, float v0, float u1, float v1,
|
||||||
float r, float g, float b, float a) {
|
float r, float g, float b, float a) {
|
||||||
if (vertices_.size() + 4 > static_cast<size_t>(max_sprites_) * 4) return;
|
// +1 reserva el slot del background que ya entró sin pasar por este guard.
|
||||||
|
if (vertices_.size() + 4 > static_cast<size_t>(max_sprites_ + 1) * 4) return;
|
||||||
uint32_t vi = static_cast<uint32_t>(vertices_.size());
|
uint32_t vi = static_cast<uint32_t>(vertices_.size());
|
||||||
|
|
||||||
// TL, TR, BR, BL
|
// TL, TR, BR, BL
|
||||||
|
|||||||
@@ -640,10 +640,10 @@ std::unique_ptr<ThemeSnapshot> ThemeManager::captureCurrentSnapshot() const {
|
|||||||
snapshot->name_en = themes_[current_theme_index_]->getNameEN();
|
snapshot->name_en = themes_[current_theme_index_]->getNameEN();
|
||||||
snapshot->name_es = themes_[current_theme_index_]->getNameES();
|
snapshot->name_es = themes_[current_theme_index_]->getNameES();
|
||||||
|
|
||||||
// Capturar colores de pelotas (suficientes para escenario máximo: 50,000)
|
// Capturar colores de pelotas para el máximo real de esta sesión
|
||||||
// Esto asegura LERP correcto incluso en escenarios grandes
|
// (SCENE_BALLS_8 o más si hay escenario custom)
|
||||||
snapshot->ball_colors.reserve(50000);
|
snapshot->ball_colors.reserve(max_ball_count_);
|
||||||
for (size_t i = 0; i < 50000; i++) {
|
for (int i = 0; i < max_ball_count_; i++) {
|
||||||
snapshot->ball_colors.push_back(
|
snapshot->ball_colors.push_back(
|
||||||
themes_[current_theme_index_]->getBallColor(i, 0.0f)
|
themes_[current_theme_index_]->getBallColor(i, 0.0f)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ class ThemeManager {
|
|||||||
|
|
||||||
// Inicialización
|
// Inicialización
|
||||||
void initialize(); // Inicializa 15 temas unificados (9 estáticos + 6 dinámicos)
|
void initialize(); // Inicializa 15 temas unificados (9 estáticos + 6 dinámicos)
|
||||||
|
void setMaxBallCount(int n) { max_ball_count_ = n; } // Máximo real (escenario 8 o custom si mayor)
|
||||||
|
|
||||||
// Interfaz unificada (PHASE 2 + PHASE 3)
|
// Interfaz unificada (PHASE 2 + PHASE 3)
|
||||||
void switchToTheme(int theme_index); // Cambia a tema 0-14 con transición LERP suave (PHASE 3)
|
void switchToTheme(int theme_index); // Cambia a tema 0-14 con transición LERP suave (PHASE 3)
|
||||||
@@ -99,6 +100,9 @@ class ThemeManager {
|
|||||||
// Snapshot del tema origen (capturado al iniciar transición)
|
// Snapshot del tema origen (capturado al iniciar transición)
|
||||||
std::unique_ptr<ThemeSnapshot> source_snapshot_; // nullptr si no hay transición
|
std::unique_ptr<ThemeSnapshot> source_snapshot_; // nullptr si no hay transición
|
||||||
|
|
||||||
|
// Máximo de bolas posible en esta sesión (max(SCENE_BALLS_8, custom_balls))
|
||||||
|
int max_ball_count_ = SCENE_BALLS_8;
|
||||||
|
|
||||||
// ========================================
|
// ========================================
|
||||||
// MÉTODOS PRIVADOS
|
// MÉTODOS PRIVADOS
|
||||||
// ========================================
|
// ========================================
|
||||||
|
|||||||
Reference in New Issue
Block a user