diff --git a/source/engine.cpp b/source/engine.cpp index 2306355..73c7fd1 100644 --- a/source/engine.cpp +++ b/source/engine.cpp @@ -718,34 +718,31 @@ void Engine::render() { // MODO FIGURA 3D: Ordenar por profundidad Z (Painter's Algorithm) // Las pelotas con menor depth_brightness (más lejos/oscuras) se renderizan primero - // Crear vector de índices para ordenamiento - std::vector render_order; - render_order.reserve(balls.size()); + // Bucket sort per profunditat Z (O(N) vs O(N log N)) for (size_t i = 0; i < balls.size(); i++) { - render_order.push_back(i); + int b = static_cast(balls[i]->getDepthBrightness() * (DEPTH_SORT_BUCKETS - 1)); + depth_buckets_[std::clamp(b, 0, DEPTH_SORT_BUCKETS - 1)].push_back(i); } - // Ordenar índices por profundidad Z (menor primero = fondo primero) - std::sort(render_order.begin(), render_order.end(), [&balls](size_t a, size_t b) { - return balls[a]->getDepthBrightness() < balls[b]->getDepthBrightness(); - }); + // Renderizar en orden de profundidad (bucket 0 = fons, bucket 255 = davant) + for (int b = 0; b < DEPTH_SORT_BUCKETS; b++) { + for (size_t idx : depth_buckets_[b]) { + SDL_FRect pos = balls[idx]->getPosition(); + Color color = theme_manager_->getInterpolatedColor(idx); // Usar color interpolado (LERP) + float brightness = balls[idx]->getDepthBrightness(); + float depth_scale = balls[idx]->getDepthScale(); - // Renderizar en orden de profundidad (fondo → frente) - for (size_t idx : render_order) { - SDL_FRect pos = balls[idx]->getPosition(); - Color color = theme_manager_->getInterpolatedColor(idx); // Usar color interpolado (LERP) - float brightness = balls[idx]->getDepthBrightness(); - float depth_scale = balls[idx]->getDepthScale(); + // Mapear brightness de 0-1 a rango MIN-MAX + float brightness_factor = (ROTOBALL_MIN_BRIGHTNESS + brightness * (ROTOBALL_MAX_BRIGHTNESS - ROTOBALL_MIN_BRIGHTNESS)) / 255.0f; - // Mapear brightness de 0-1 a rango MIN-MAX - float brightness_factor = (ROTOBALL_MIN_BRIGHTNESS + brightness * (ROTOBALL_MAX_BRIGHTNESS - ROTOBALL_MIN_BRIGHTNESS)) / 255.0f; + // Aplicar factor de brillo al color + int r_mod = static_cast(color.r * brightness_factor); + int g_mod = static_cast(color.g * brightness_factor); + int b_mod = static_cast(color.b * brightness_factor); - // Aplicar factor de brillo al color - int r_mod = static_cast(color.r * brightness_factor); - int g_mod = static_cast(color.g * brightness_factor); - int b_mod = static_cast(color.b * brightness_factor); - - addSpriteToBatch(pos.x, pos.y, pos.w, pos.h, r_mod, g_mod, b_mod, depth_scale); + addSpriteToBatch(pos.x, pos.y, pos.w, pos.h, r_mod, g_mod, b_mod, depth_scale); + } + depth_buckets_[b].clear(); // netejar per al proper frame } } else { // MODO PHYSICS: Renderizar en orden normal del vector (sin escala de profundidad) diff --git a/source/engine.hpp b/source/engine.hpp index 3e6b5fe..01bd665 100644 --- a/source/engine.hpp +++ b/source/engine.hpp @@ -223,6 +223,10 @@ class Engine { std::vector batch_vertices_; std::vector batch_indices_; + // Bucket sort per z-ordering (SHAPE mode) + static constexpr int DEPTH_SORT_BUCKETS = 256; + std::array, 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