#include "rendering/sky_system.hpp" #include "rendering/skybox.hpp" #include "rendering/celestial.hpp" #include "rendering/starfield.hpp" #include "rendering/clouds.hpp" #include "rendering/lens_flare.hpp" #include "rendering/camera.hpp" #include "core/logger.hpp" namespace wowee { namespace rendering { SkySystem::SkySystem() = default; SkySystem::~SkySystem() { shutdown(); } bool SkySystem::initialize() { if (initialized_) { LOG_WARNING("SkySystem already initialized"); return true; } LOG_INFO("Initializing sky system"); // Initialize skybox (authoritative) skybox_ = std::make_unique(); if (!skybox_->initialize()) { LOG_ERROR("Failed to initialize skybox"); return false; } // Initialize celestial bodies (sun + 2 moons) celestial_ = std::make_unique(); if (!celestial_->initialize()) { LOG_ERROR("Failed to initialize celestial bodies"); return false; } // Initialize procedural stars (FALLBACK only) starField_ = std::make_unique(); if (!starField_->initialize()) { LOG_ERROR("Failed to initialize star field"); return false; } // Default: disabled (skybox is authoritative) starField_->setEnabled(false); // Initialize clouds clouds_ = std::make_unique(); if (!clouds_->initialize()) { LOG_ERROR("Failed to initialize clouds"); return false; } // Initialize lens flare lensFlare_ = std::make_unique(); if (!lensFlare_->initialize()) { LOG_ERROR("Failed to initialize lens flare"); return false; } initialized_ = true; LOG_INFO("Sky system initialized successfully"); return true; } void SkySystem::shutdown() { if (!initialized_) { return; } LOG_INFO("Shutting down sky system"); // Shutdown components that have explicit shutdown methods if (starField_) starField_->shutdown(); if (celestial_) celestial_->shutdown(); if (skybox_) skybox_->shutdown(); // Reset all (destructors handle cleanup for clouds/lensFlare) lensFlare_.reset(); clouds_.reset(); starField_.reset(); celestial_.reset(); skybox_.reset(); initialized_ = false; } void SkySystem::update(float deltaTime) { if (!initialized_) { return; } // Update time-based systems if (skybox_) skybox_->update(deltaTime); if (celestial_) celestial_->update(deltaTime); if (starField_) starField_->update(deltaTime); } void SkySystem::render(const Camera& camera, const SkyParams& params) { if (!initialized_) { return; } // Render skybox first (authoritative, includes baked stars) if (skybox_) { skybox_->render(camera, params.timeOfDay); } // Decide whether to render procedural stars bool renderProceduralStars = false; if (debugSkyMode_) { // Debug mode: always show procedural stars renderProceduralStars = true; } else if (proceduralStarsEnabled_) { // Fallback mode: show only if skybox doesn't have stars renderProceduralStars = !params.skyboxHasStars; } // Render procedural stars (FALLBACK or DEBUG only) if (renderProceduralStars && starField_) { starField_->setEnabled(true); starField_->render(camera, params.timeOfDay, params.cloudDensity, params.fogDensity); } else if (starField_) { starField_->setEnabled(false); } // Render celestial bodies (sun + White Lady + Blue Child) // Pass gameTime for deterministic moon phases if (celestial_) { celestial_->render(camera, params.timeOfDay, ¶ms.directionalDir, ¶ms.sunColor, params.gameTime); } // Render clouds if (clouds_) { clouds_->render(camera, params.timeOfDay); } // Render lens flare (sun glow effect) if (lensFlare_) { glm::vec3 sunPos = getSunPosition(params); lensFlare_->render(camera, sunPos, params.timeOfDay); } } glm::vec3 SkySystem::getSunPosition(const SkyParams& params) const { // Use lighting direction for sun position const float sunDistance = 800.0f; return -params.directionalDir * sunDistance; // Negative because light comes FROM sun } void SkySystem::setMoonPhaseCycling(bool enabled) { if (celestial_) { celestial_->setMoonPhaseCycling(enabled); } } void SkySystem::setWhiteLadyPhase(float phase) { if (celestial_) { celestial_->setMoonPhase(phase); // White Lady is primary moon } } void SkySystem::setBlueChildPhase(float phase) { if (celestial_) { celestial_->setBlueChildPhase(phase); } } float SkySystem::getWhiteLadyPhase() const { return celestial_ ? celestial_->getMoonPhase() : 0.5f; } float SkySystem::getBlueChildPhase() const { // TODO: Second moon support return 0.25f; // Placeholder phase } } // namespace rendering } // namespace wowee