feat(gpu): migrar a SDL3_GPU amb 2-pass rendering i post-processat
- Infraestructura GPU: GpuContext, GpuPipeline, GpuSpriteBatch, GpuTexture - Engine::render() migrat a 2-pass: sprites → offscreen R8G8B8A8 → swapchain + vignette - UI/text via software renderer (SDL3_ttf) + upload com a textura overlay GPU - CMakeLists.txt actualitzat per incloure subsistema gpu/ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL3/SDL_events.h> // for SDL_Event
|
||||
#include <SDL3/SDL_render.h> // for SDL_Renderer
|
||||
#include <SDL3/SDL_render.h> // for SDL_Renderer (ui_renderer_ software renderer)
|
||||
#include <SDL3/SDL_stdinc.h> // for Uint64
|
||||
#include <SDL3/SDL_surface.h> // for SDL_Surface (ui_surface_)
|
||||
#include <SDL3/SDL_video.h> // for SDL_Window
|
||||
|
||||
#include <array> // for array
|
||||
@@ -15,6 +16,10 @@
|
||||
#include "boids_mgr/boid_manager.hpp" // for BoidManager
|
||||
#include "defines.hpp" // for GravityDirection, ColorTheme, ShapeType
|
||||
#include "external/texture.hpp" // for Texture
|
||||
#include "gpu/gpu_context.hpp" // for GpuContext
|
||||
#include "gpu/gpu_pipeline.hpp" // for GpuPipeline
|
||||
#include "gpu/gpu_sprite_batch.hpp" // for GpuSpriteBatch
|
||||
#include "gpu/gpu_texture.hpp" // for GpuTexture
|
||||
#include "input/input_handler.hpp" // for InputHandler
|
||||
#include "scene/scene_manager.hpp" // for SceneManager
|
||||
#include "shapes_mgr/shape_manager.hpp" // for ShapeManager
|
||||
@@ -124,14 +129,32 @@ class Engine {
|
||||
std::unique_ptr<UIManager> ui_manager_; // Gestión de UI (HUD, FPS, notificaciones)
|
||||
std::unique_ptr<AppLogo> app_logo_; // Gestión de logo periódico en pantalla
|
||||
|
||||
// Recursos SDL
|
||||
// === SDL window ===
|
||||
SDL_Window* window_ = nullptr;
|
||||
SDL_Renderer* renderer_ = nullptr;
|
||||
|
||||
// === SDL_GPU rendering pipeline ===
|
||||
std::unique_ptr<GpuContext> gpu_ctx_; // Device + swapchain
|
||||
std::unique_ptr<GpuPipeline> gpu_pipeline_; // Sprite + postfx pipelines
|
||||
std::unique_ptr<GpuSpriteBatch> sprite_batch_; // Per-frame vertex/index batch
|
||||
std::unique_ptr<GpuTexture> offscreen_tex_; // Offscreen render target (Pass 1)
|
||||
std::unique_ptr<GpuTexture> white_tex_; // 1×1 white (background gradient)
|
||||
std::unique_ptr<GpuTexture> ui_tex_; // UI text overlay texture
|
||||
|
||||
// GPU sprite textures (one per ball skin, parallel to textures_/texture_names_)
|
||||
std::unique_ptr<GpuTexture> gpu_texture_; // Active GPU sprite texture
|
||||
std::vector<std::unique_ptr<GpuTexture>> gpu_textures_; // All GPU sprite textures
|
||||
|
||||
// === SDL_Renderer (software, for UI text via SDL3_ttf) ===
|
||||
// Renders to ui_surface_, then uploaded as gpu texture overlay.
|
||||
SDL_Renderer* ui_renderer_ = nullptr;
|
||||
SDL_Surface* ui_surface_ = nullptr;
|
||||
|
||||
// Legacy Texture objects — kept for ball physics sizing and AppLogo
|
||||
std::shared_ptr<Texture> texture_ = nullptr; // Textura activa actual
|
||||
std::vector<std::shared_ptr<Texture>> textures_; // Todas las texturas disponibles
|
||||
std::vector<std::string> texture_names_; // Nombres de texturas (sin extensión)
|
||||
size_t current_texture_index_ = 0; // Índice de textura activa
|
||||
int current_ball_size_ = 10; // Tamaño actual de pelotas (dinámico, se actualiza desde texture)
|
||||
int current_ball_size_ = 10; // Tamaño actual de pelotas (dinámico)
|
||||
|
||||
// Estado del simulador
|
||||
bool should_exit_ = false;
|
||||
@@ -143,12 +166,12 @@ class Engine {
|
||||
// Sistema de zoom dinámico
|
||||
int current_window_zoom_ = DEFAULT_WINDOW_ZOOM;
|
||||
|
||||
// V-Sync
|
||||
// V-Sync y fullscreen
|
||||
bool vsync_enabled_ = true;
|
||||
bool fullscreen_enabled_ = false;
|
||||
bool real_fullscreen_enabled_ = false;
|
||||
bool kiosk_mode_ = false;
|
||||
ScalingMode current_scaling_mode_ = ScalingMode::INTEGER; // Modo de escalado actual (F5)
|
||||
ScalingMode current_scaling_mode_ = ScalingMode::INTEGER;
|
||||
|
||||
// Resolución base (configurada por CLI o default)
|
||||
int base_screen_width_ = DEFAULT_SCREEN_WIDTH;
|
||||
@@ -164,15 +187,13 @@ class Engine {
|
||||
|
||||
// Sistema de temas (delegado a ThemeManager)
|
||||
std::unique_ptr<ThemeManager> theme_manager_;
|
||||
int theme_page_ = 0; // Página actual de temas (0 o 1) para acceso por Numpad
|
||||
int theme_page_ = 0;
|
||||
|
||||
// Modo de simulación actual (PHYSICS/SHAPE/BOIDS) — fuente de verdad para Engine
|
||||
// El estado de figuras (active_shape_, scale, etc.) está en ShapeManager
|
||||
// Modo de simulación actual (PHYSICS/SHAPE/BOIDS)
|
||||
SimulationMode current_mode_ = SimulationMode::PHYSICS;
|
||||
|
||||
// Sistema de Modo DEMO (auto-play) y LOGO
|
||||
// Toda la lógica DEMO/LOGO y su estado vive en StateManager
|
||||
int max_auto_scenario_ = 5; // Índice máximo en modos auto (resultado del benchmark)
|
||||
int max_auto_scenario_ = 5;
|
||||
|
||||
// Escenario custom (--custom-balls)
|
||||
int custom_scenario_balls_ = 0;
|
||||
@@ -180,19 +201,10 @@ class Engine {
|
||||
bool custom_auto_available_ = false;
|
||||
bool skip_benchmark_ = false;
|
||||
|
||||
// Batch rendering
|
||||
std::vector<SDL_Vertex> batch_vertices_;
|
||||
std::vector<int> batch_indices_;
|
||||
|
||||
// Bucket sort per z-ordering (SHAPE mode)
|
||||
static constexpr int DEPTH_SORT_BUCKETS = 256;
|
||||
std::array<std::vector<size_t>, DEPTH_SORT_BUCKETS> depth_buckets_;
|
||||
|
||||
// Configuración del sistema de texto (constantes configurables)
|
||||
static constexpr const char* TEXT_FONT_PATH = "data/fonts/determination.ttf";
|
||||
static constexpr int TEXT_BASE_SIZE = 24; // Tamaño base para 240p
|
||||
static constexpr bool TEXT_ANTIALIASING = true; // true = suavizado, false = píxeles nítidos
|
||||
|
||||
// Métodos principales del loop
|
||||
void calculateDeltaTime();
|
||||
void update();
|
||||
@@ -201,24 +213,30 @@ class Engine {
|
||||
// Benchmark de rendimiento (determina max_auto_scenario_ al inicio)
|
||||
void runPerformanceBenchmark();
|
||||
|
||||
// Métodos auxiliares privados (llamados por la interfaz pública)
|
||||
// Métodos auxiliares privados
|
||||
|
||||
// Sistema de cambio de sprites dinámico - Métodos privados
|
||||
void switchTextureInternal(bool show_notification); // Implementación interna del cambio de textura
|
||||
// Sistema de cambio de sprites dinámico
|
||||
void switchTextureInternal(bool show_notification);
|
||||
|
||||
// Sistema de zoom dinámico - Métodos privados
|
||||
// Sistema de zoom dinámico
|
||||
int calculateMaxWindowZoom() const;
|
||||
void setWindowZoom(int new_zoom);
|
||||
void zoomIn();
|
||||
void zoomOut();
|
||||
void updatePhysicalWindowSize(); // Actualizar tamaño físico real de ventana
|
||||
void updatePhysicalWindowSize();
|
||||
|
||||
// Rendering
|
||||
// Rendering (GPU path replaces addSpriteToBatch)
|
||||
void addSpriteToBatch(float x, float y, float w, float h, int r, int g, int b, float scale = 1.0f);
|
||||
|
||||
// Sistema de Figuras 3D - Métodos privados (thin wrappers a ShapeManager)
|
||||
void toggleShapeModeInternal(bool force_gravity_on_exit = true); // Delega a ShapeManager + sincroniza current_mode_
|
||||
void activateShapeInternal(ShapeType type); // Delega a ShapeManager + sets current_mode_ = SHAPE
|
||||
void updateShape(); // Delega a ShapeManager::update()
|
||||
void generateShape(); // Delega a ShapeManager::generateShape()
|
||||
// Sistema de Figuras 3D
|
||||
void toggleShapeModeInternal(bool force_gravity_on_exit = true);
|
||||
void activateShapeInternal(ShapeType type);
|
||||
void updateShape();
|
||||
void generateShape();
|
||||
|
||||
// GPU helpers
|
||||
bool loadGpuSpriteTexture(size_t index); // Upload one sprite texture to GPU
|
||||
void recreateOffscreenTexture(); // Recreate when resolution changes
|
||||
void renderUIToSurface(); // Render text/UI to ui_surface_
|
||||
void uploadUISurface(SDL_GPUCommandBuffer* cmd_buf); // Upload ui_surface_ → ui_tex_
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user