mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-23 07:40:14 +00:00
- Skybox now uses DBC sky colors (skyTop/skyMiddle/skyBand1/skyBand2) instead of hardcoded C++ color curves, with 3-band gradient and Rayleigh/Mie scattering - Clouds receive sun direction for lit edges, self-shadowing, and silver lining - Fixed sun quad box artifact with proper edge fade in celestial shader - Lens flare attenuated by fog, cloud density, and weather intensity - Replaced garish green/purple lens flare ghosts with warm natural palette - Added zone-based weather system for single-player mode with per-zone rain/snow configuration, probability-based activation, and smooth intensity transitions - Server SMSG_WEATHER remains authoritative when connected to a server
165 lines
4.8 KiB
C++
165 lines
4.8 KiB
C++
#pragma once
|
|
|
|
#include <vulkan/vulkan.h>
|
|
#include <vk_mem_alloc.h>
|
|
#include <glm/glm.hpp>
|
|
#include <vector>
|
|
#include <unordered_map>
|
|
|
|
namespace wowee {
|
|
namespace rendering {
|
|
|
|
class Camera;
|
|
class VkContext;
|
|
|
|
/**
|
|
* @brief Weather particle system for rain and snow
|
|
*
|
|
* Features:
|
|
* - Rain particles (fast vertical drops)
|
|
* - Snow particles (slow floating flakes)
|
|
* - Particle recycling for efficiency
|
|
* - Camera-relative positioning (follows player)
|
|
* - Adjustable intensity (light, medium, heavy)
|
|
* - Vulkan point-sprite rendering
|
|
*/
|
|
class Weather {
|
|
public:
|
|
enum class Type {
|
|
NONE,
|
|
RAIN,
|
|
SNOW
|
|
};
|
|
|
|
Weather();
|
|
~Weather();
|
|
|
|
/**
|
|
* @brief Initialize weather system
|
|
* @param ctx Vulkan context
|
|
* @param perFrameLayout Descriptor set layout for the per-frame UBO (set 0)
|
|
* @return true if initialization succeeded
|
|
*/
|
|
bool initialize(VkContext* ctx, VkDescriptorSetLayout perFrameLayout);
|
|
void recreatePipelines();
|
|
|
|
/**
|
|
* @brief Update weather particles
|
|
* @param camera Camera for particle positioning
|
|
* @param deltaTime Time since last frame
|
|
*/
|
|
void update(const Camera& camera, float deltaTime);
|
|
|
|
/**
|
|
* @brief Render weather particles
|
|
* @param cmd Command buffer to record into
|
|
* @param perFrameSet Per-frame descriptor set (set 0, contains camera UBO)
|
|
*/
|
|
void render(VkCommandBuffer cmd, VkDescriptorSet perFrameSet);
|
|
|
|
/**
|
|
* @brief Set weather type
|
|
*/
|
|
void setWeatherType(Type type) { weatherType = type; }
|
|
Type getWeatherType() const { return weatherType; }
|
|
|
|
/**
|
|
* @brief Set weather intensity (0.0 = none, 1.0 = heavy)
|
|
*/
|
|
void setIntensity(float intensity);
|
|
float getIntensity() const { return intensity; }
|
|
|
|
/**
|
|
* @brief Enable or disable weather
|
|
*/
|
|
void setEnabled(bool enabled) { this->enabled = enabled; }
|
|
bool isEnabled() const { return enabled; }
|
|
|
|
/**
|
|
* @brief Get active particle count
|
|
*/
|
|
int getParticleCount() const;
|
|
|
|
/**
|
|
* @brief Zone weather configuration
|
|
* Provides default weather per zone for single-player mode.
|
|
* When connected to a server, SMSG_WEATHER overrides these.
|
|
*/
|
|
struct ZoneWeather {
|
|
Type type = Type::NONE;
|
|
float minIntensity = 0.0f; // Min intensity (varies over time)
|
|
float maxIntensity = 0.0f; // Max intensity
|
|
float probability = 0.0f; // Chance of weather being active (0-1)
|
|
};
|
|
|
|
/**
|
|
* @brief Set weather for a zone (used for zone-based weather configuration)
|
|
*/
|
|
void setZoneWeather(uint32_t zoneId, Type type, float minIntensity, float maxIntensity, float probability);
|
|
|
|
/**
|
|
* @brief Update weather based on current zone (single-player mode)
|
|
* @param zoneId Current zone ID
|
|
* @param deltaTime Time since last frame
|
|
*/
|
|
void updateZoneWeather(uint32_t zoneId, float deltaTime);
|
|
|
|
/**
|
|
* @brief Initialize default zone weather table
|
|
*/
|
|
void initializeZoneWeatherDefaults();
|
|
|
|
/**
|
|
* @brief Clean up Vulkan resources
|
|
*/
|
|
void shutdown();
|
|
|
|
private:
|
|
struct Particle {
|
|
glm::vec3 position;
|
|
glm::vec3 velocity;
|
|
float lifetime;
|
|
float maxLifetime;
|
|
};
|
|
|
|
void resetParticles(const Camera& camera);
|
|
void updateParticle(Particle& particle, const Camera& camera, float deltaTime);
|
|
glm::vec3 getRandomPosition(const glm::vec3& center) const;
|
|
|
|
// Vulkan objects
|
|
VkContext* vkCtx = nullptr;
|
|
VkPipeline pipeline = VK_NULL_HANDLE;
|
|
VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
|
|
|
|
// Dynamic mapped buffer for particle positions (updated every frame)
|
|
::VkBuffer dynamicVB = VK_NULL_HANDLE;
|
|
VmaAllocation dynamicVBAlloc = VK_NULL_HANDLE;
|
|
VmaAllocationInfo dynamicVBAllocInfo{};
|
|
VkDeviceSize dynamicVBSize = 0;
|
|
|
|
// Particles
|
|
std::vector<Particle> particles;
|
|
std::vector<glm::vec3> particlePositions; // For rendering
|
|
|
|
// Weather parameters
|
|
bool enabled = false;
|
|
Type weatherType = Type::NONE;
|
|
float intensity = 0.5f;
|
|
|
|
// Particle system parameters
|
|
static constexpr int MAX_PARTICLES = 2000;
|
|
static constexpr float SPAWN_VOLUME_SIZE = 100.0f; // Size of spawn area around camera
|
|
static constexpr float SPAWN_HEIGHT = 80.0f; // Height above camera to spawn
|
|
|
|
// Zone-based weather
|
|
std::unordered_map<uint32_t, ZoneWeather> zoneWeatherTable_;
|
|
uint32_t currentWeatherZone_ = 0;
|
|
float zoneWeatherTimer_ = 0.0f; // Time accumulator for weather cycling
|
|
float zoneWeatherCycleDuration_ = 0.0f; // Current cycle length
|
|
bool zoneWeatherActive_ = false; // Is zone weather currently active?
|
|
float targetIntensity_ = 0.0f; // Target intensity for smooth transitions
|
|
bool zoneWeatherInitialized_ = false;
|
|
};
|
|
|
|
} // namespace rendering
|
|
} // namespace wowee
|