feat(postfx): redisseny sistema PostFX (X/F5/F6, --postfx CLI)
- X cicla 4 efectes (Vinyeta/Scanlines/Cromàtica/Complet), sempre activa PostFX - F5 fa toggle PostFX on/off mantenint l'efecte seleccionat - F6 hereta el toggle d'integer scaling (abans F5) - Arrencada per defecte sense postprocés (tot a 0) - --postfx <vinyeta|scanlines|cromatica|complet> per activar des de CLI Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1013,23 +1013,52 @@ void Engine::toggleRealFullscreen() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Engine::applyPostFXPreset(int mode) {
|
||||||
|
static constexpr float presets[4][3] = {
|
||||||
|
{1.5f, 0.0f, 0.0f}, // 0: Vinyeta
|
||||||
|
{1.5f, 0.0f, 0.8f}, // 1: Scanlines
|
||||||
|
{1.5f, 1.0f, 0.0f}, // 2: Cromàtica
|
||||||
|
{1.5f, 1.0f, 0.8f}, // 3: Complet
|
||||||
|
};
|
||||||
|
postfx_uniforms_.vignette_strength = presets[mode][0];
|
||||||
|
postfx_uniforms_.chroma_strength = presets[mode][1];
|
||||||
|
postfx_uniforms_.scanline_strength = presets[mode][2];
|
||||||
|
}
|
||||||
|
|
||||||
void Engine::handlePostFXCycle() {
|
void Engine::handlePostFXCycle() {
|
||||||
static constexpr float presets[5][3] = {
|
static constexpr const char* names[4] = {
|
||||||
{1.5f, 0.0f, 0.0f}, {1.5f, 0.0f, 0.8f},
|
|
||||||
{1.5f, 1.0f, 0.0f}, {1.5f, 1.0f, 0.8f},
|
|
||||||
{0.0f, 0.0f, 0.0f}
|
|
||||||
};
|
|
||||||
static constexpr const char* names[5] = {
|
|
||||||
"PostFX: Vinyeta", "PostFX: Scanlines",
|
"PostFX: Vinyeta", "PostFX: Scanlines",
|
||||||
"PostFX: Cromàtica", "PostFX: Complet", "PostFX: Desactivat"
|
"PostFX: Cromàtica", "PostFX: Complet"
|
||||||
};
|
};
|
||||||
postfx_effect_mode_ = (postfx_effect_mode_ + 1) % 5;
|
postfx_effect_mode_ = (postfx_effect_mode_ + 1) % 4;
|
||||||
postfx_uniforms_.vignette_strength = presets[postfx_effect_mode_][0];
|
postfx_enabled_ = true;
|
||||||
postfx_uniforms_.chroma_strength = presets[postfx_effect_mode_][1];
|
applyPostFXPreset(postfx_effect_mode_);
|
||||||
postfx_uniforms_.scanline_strength = presets[postfx_effect_mode_][2];
|
|
||||||
showNotificationForAction(names[postfx_effect_mode_]);
|
showNotificationForAction(names[postfx_effect_mode_]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Engine::handlePostFXToggle() {
|
||||||
|
static constexpr const char* names[4] = {
|
||||||
|
"PostFX: Vinyeta", "PostFX: Scanlines",
|
||||||
|
"PostFX: Cromàtica", "PostFX: Complet"
|
||||||
|
};
|
||||||
|
postfx_enabled_ = !postfx_enabled_;
|
||||||
|
if (postfx_enabled_) {
|
||||||
|
applyPostFXPreset(postfx_effect_mode_);
|
||||||
|
showNotificationForAction(names[postfx_effect_mode_]);
|
||||||
|
} else {
|
||||||
|
postfx_uniforms_.vignette_strength = 0.0f;
|
||||||
|
postfx_uniforms_.chroma_strength = 0.0f;
|
||||||
|
postfx_uniforms_.scanline_strength = 0.0f;
|
||||||
|
showNotificationForAction("PostFX: Desactivat");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Engine::setInitialPostFX(int mode) {
|
||||||
|
postfx_effect_mode_ = mode;
|
||||||
|
postfx_enabled_ = true;
|
||||||
|
applyPostFXPreset(mode);
|
||||||
|
}
|
||||||
|
|
||||||
void Engine::toggleIntegerScaling() {
|
void Engine::toggleIntegerScaling() {
|
||||||
// Solo permitir cambio si estamos en modo fullscreen normal (F3)
|
// Solo permitir cambio si estamos en modo fullscreen normal (F3)
|
||||||
if (!fullscreen_enabled_) {
|
if (!fullscreen_enabled_) {
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ class Engine {
|
|||||||
|
|
||||||
// PostFX presets
|
// PostFX presets
|
||||||
void handlePostFXCycle();
|
void handlePostFXCycle();
|
||||||
|
void handlePostFXToggle();
|
||||||
|
void setInitialPostFX(int mode);
|
||||||
|
|
||||||
// Modo kiosko
|
// Modo kiosko
|
||||||
void setKioskMode(bool enabled) { kiosk_mode_ = enabled; }
|
void setKioskMode(bool enabled) { kiosk_mode_ = enabled; }
|
||||||
@@ -170,8 +172,9 @@ class Engine {
|
|||||||
float delta_time_ = 0.0f;
|
float delta_time_ = 0.0f;
|
||||||
|
|
||||||
// PostFX uniforms (passed to GPU each frame)
|
// PostFX uniforms (passed to GPU each frame)
|
||||||
PostFXUniforms postfx_uniforms_ = {1.5f, 0.0f, 0.0f, 0.0f};
|
PostFXUniforms postfx_uniforms_ = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
int postfx_effect_mode_ = 0;
|
int postfx_effect_mode_ = 0;
|
||||||
|
bool postfx_enabled_ = false;
|
||||||
|
|
||||||
// Sistema de zoom dinámico
|
// Sistema de zoom dinámico
|
||||||
int current_window_zoom_ = DEFAULT_WINDOW_ZOOM;
|
int current_window_zoom_ = DEFAULT_WINDOW_ZOOM;
|
||||||
@@ -244,6 +247,9 @@ class Engine {
|
|||||||
void updateShape();
|
void updateShape();
|
||||||
void generateShape();
|
void generateShape();
|
||||||
|
|
||||||
|
// PostFX helper
|
||||||
|
void applyPostFXPreset(int mode);
|
||||||
|
|
||||||
// GPU helpers
|
// GPU helpers
|
||||||
bool loadGpuSpriteTexture(size_t index); // Upload one sprite texture to GPU
|
bool loadGpuSpriteTexture(size_t index); // Upload one sprite texture to GPU
|
||||||
void recreateOffscreenTexture(); // Recreate when resolution changes
|
void recreateOffscreenTexture(); // Recreate when resolution changes
|
||||||
|
|||||||
@@ -254,8 +254,13 @@ bool InputHandler::processEvents(Engine& engine) {
|
|||||||
else engine.toggleRealFullscreen();
|
else engine.toggleRealFullscreen();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Toggle escalado entero/estirado (solo en fullscreen F3)
|
// Toggle PostFX activo/inactivo
|
||||||
case SDLK_F5:
|
case SDLK_F5:
|
||||||
|
engine.handlePostFXToggle();
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Toggle escalado entero/estirado (solo en fullscreen F3)
|
||||||
|
case SDLK_F6:
|
||||||
engine.toggleIntegerScaling();
|
engine.toggleIntegerScaling();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ void printHelp() {
|
|||||||
std::cout << " --custom-balls <n> Activa escenario custom (tecla 9) con N pelotas\n";
|
std::cout << " --custom-balls <n> Activa escenario custom (tecla 9) con N pelotas\n";
|
||||||
std::cout << " --skip-benchmark Salta el benchmark y usa el máximo de bolas (50000)\n";
|
std::cout << " --skip-benchmark Salta el benchmark y usa el máximo de bolas (50000)\n";
|
||||||
std::cout << " --max-balls <n> Limita el máximo de bolas en modos DEMO/DEMO_LITE\n";
|
std::cout << " --max-balls <n> Limita el máximo de bolas en modos DEMO/DEMO_LITE\n";
|
||||||
|
std::cout << " --postfx <efecto> Arrancar con PostFX activo: vinyeta, scanlines, cromatica, complet\n";
|
||||||
std::cout << " --help Mostrar esta ayuda\n\n";
|
std::cout << " --help Mostrar esta ayuda\n\n";
|
||||||
std::cout << "Ejemplos:\n";
|
std::cout << "Ejemplos:\n";
|
||||||
std::cout << " vibe3_physics # 320x240 zoom 3 (ventana 960x720)\n";
|
std::cout << " vibe3_physics # 320x240 zoom 3 (ventana 960x720)\n";
|
||||||
@@ -45,6 +46,7 @@ int main(int argc, char* argv[]) {
|
|||||||
bool kiosk_mode = false;
|
bool kiosk_mode = false;
|
||||||
bool skip_benchmark = false;
|
bool skip_benchmark = false;
|
||||||
int max_balls_override = 0;
|
int max_balls_override = 0;
|
||||||
|
int initial_postfx = -1;
|
||||||
AppMode initial_mode = AppMode::SANDBOX; // Modo inicial (default: SANDBOX)
|
AppMode initial_mode = AppMode::SANDBOX; // Modo inicial (default: SANDBOX)
|
||||||
|
|
||||||
// Parsear argumentos
|
// Parsear argumentos
|
||||||
@@ -124,6 +126,25 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
} else if (strcmp(argv[i], "--skip-benchmark") == 0) {
|
} else if (strcmp(argv[i], "--skip-benchmark") == 0) {
|
||||||
skip_benchmark = true;
|
skip_benchmark = true;
|
||||||
|
} else if (strcmp(argv[i], "--postfx") == 0) {
|
||||||
|
if (i + 1 < argc) {
|
||||||
|
std::string fx = argv[++i];
|
||||||
|
if (fx == "vinyeta") {
|
||||||
|
initial_postfx = 0;
|
||||||
|
} else if (fx == "scanlines") {
|
||||||
|
initial_postfx = 1;
|
||||||
|
} else if (fx == "cromatica") {
|
||||||
|
initial_postfx = 2;
|
||||||
|
} else if (fx == "complet") {
|
||||||
|
initial_postfx = 3;
|
||||||
|
} else {
|
||||||
|
std::cerr << "Error: --postfx '" << fx << "' no válido. Usa: vinyeta, scanlines, cromatica, complet\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::cerr << "Error: --postfx requiere un valor\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
} else if (strcmp(argv[i], "--max-balls") == 0) {
|
} else if (strcmp(argv[i], "--max-balls") == 0) {
|
||||||
if (i + 1 < argc) {
|
if (i + 1 < argc) {
|
||||||
int n = atoi(argv[++i]);
|
int n = atoi(argv[++i]);
|
||||||
@@ -158,6 +179,9 @@ int main(int argc, char* argv[]) {
|
|||||||
else if (skip_benchmark)
|
else if (skip_benchmark)
|
||||||
engine.setSkipBenchmark();
|
engine.setSkipBenchmark();
|
||||||
|
|
||||||
|
if (initial_postfx >= 0)
|
||||||
|
engine.setInitialPostFX(initial_postfx);
|
||||||
|
|
||||||
if (!engine.initialize(width, height, zoom, fullscreen, initial_mode)) {
|
if (!engine.initialize(width, height, zoom, fullscreen, initial_mode)) {
|
||||||
std::cout << "¡Error al inicializar el engine!" << std::endl;
|
std::cout << "¡Error al inicializar el engine!" << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user