diff --git a/source/engine.cpp b/source/engine.cpp index b4bca1b..cb8d4c6 100644 --- a/source/engine.cpp +++ b/source/engine.cpp @@ -8,7 +8,7 @@ #include // for SDL_GetTicks #include // for SDL_CreateWindow, SDL_DestroyWindow, SDL_GetDisplayBounds -#include // for std::min, std::max +#include // for std::min, std::max, std::sort #include // for sqrtf, acosf, cosf, sinf (funciones matemáticas) #include // for rand, srand #include // for time @@ -319,16 +319,32 @@ void Engine::render() { batch_vertices_.clear(); batch_indices_.clear(); - // Recopilar datos de todas las bolas para batch rendering - for (auto &ball : balls_) { - SDL_FRect pos = ball->getPosition(); - Color color = ball->getColor(); + if (current_mode_ == SimulationMode::ROTOBALL) { + // MODO ROTOBALL: Ordenar por profundidad Z (Painter's Algorithm) + // Las pelotas con menor depth_brightness (más lejos/oscuras) se renderizan primero - // En modo RotoBall, modular color según profundidad Z - if (current_mode_ == SimulationMode::ROTOBALL) { - float brightness = ball->getDepthBrightness(); - // Mapear brightness de 0-1 a rango ROTOBALL_MIN_BRIGHTNESS - ROTOBALL_MAX_BRIGHTNESS - float brightness_factor = (ROTOBALL_MIN_BRIGHTNESS + brightness * (ROTOBALL_MAX_BRIGHTNESS - ROTOBALL_MIN_BRIGHTNESS)) / 255.0f; + // Crear vector de índices para ordenamiento + std::vector render_order; + render_order.reserve(balls_.size()); + for (size_t i = 0; i < balls_.size(); i++) { + render_order.push_back(i); + } + + // Ordenar índices por profundidad Z (menor primero = fondo primero) + std::sort(render_order.begin(), render_order.end(), + [this](size_t a, size_t b) { + return balls_[a]->getDepthBrightness() < balls_[b]->getDepthBrightness(); + }); + + // Renderizar en orden de profundidad (fondo → frente) + for (size_t idx : render_order) { + SDL_FRect pos = balls_[idx]->getPosition(); + Color color = balls_[idx]->getColor(); + float brightness = balls_[idx]->getDepthBrightness(); + + // 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); @@ -336,8 +352,12 @@ void Engine::render() { int b_mod = static_cast(color.b * brightness_factor); addSpriteToBatch(pos.x, pos.y, pos.w, pos.h, r_mod, g_mod, b_mod); - } else { - // Modo física normal + } + } else { + // MODO PHYSICS: Renderizar en orden normal del vector + 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); } }