rain_renderer.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include "rain_renderer.h"
  2. #include "../gl/buffer.h"
  3. #include "../scene_renderer.h"
  4. #include "ground_utils.h"
  5. #include <QDebug>
  6. #include <algorithm>
  7. #include <cmath>
  8. #include <cstddef>
  9. namespace {
  10. using std::uint32_t;
  11. using namespace Render::Ground;
  12. } // namespace
  13. namespace Render::GL {
  14. RainRenderer::RainRenderer() = default;
  15. RainRenderer::~RainRenderer() = default;
  16. void RainRenderer::configure(float world_width, float world_height,
  17. std::uint32_t seed, Game::Map::WeatherType type) {
  18. m_world_width = std::max(1.0F, world_width);
  19. m_world_height = std::max(1.0F, world_height);
  20. m_seed = seed;
  21. m_rain_drops.clear();
  22. m_instance_buffer.reset();
  23. m_instance_count = 0;
  24. m_params.weather_type = type;
  25. m_params.time = 0.0F;
  26. m_params.intensity = 0.0F;
  27. m_params.wind_strength = 0.0F;
  28. update_weather_params();
  29. generate_rain_drops();
  30. }
  31. void RainRenderer::set_intensity(float intensity) {
  32. m_target_intensity = std::clamp(intensity, 0.0F, 1.0F);
  33. }
  34. void RainRenderer::set_weather_type(Game::Map::WeatherType type) {
  35. if (m_params.weather_type != type) {
  36. m_params.weather_type = type;
  37. update_weather_params();
  38. }
  39. }
  40. void RainRenderer::update_weather_params() {
  41. if (m_params.weather_type == Game::Map::WeatherType::Snow) {
  42. m_params.drop_speed = RainBatchParams::k_default_snow_drop_speed;
  43. m_params.drop_length = RainBatchParams::k_default_snow_drop_size;
  44. m_params.drop_width = RainBatchParams::k_default_snow_drop_size;
  45. } else {
  46. m_params.drop_speed = RainBatchParams::k_default_rain_drop_speed;
  47. m_params.drop_length = RainBatchParams::k_default_rain_drop_length;
  48. m_params.drop_width = RainBatchParams::k_default_rain_drop_width;
  49. }
  50. }
  51. void RainRenderer::set_wind_strength(float strength) {
  52. m_params.wind_strength = strength;
  53. }
  54. void RainRenderer::set_camera_position(const QVector3D &position) {
  55. m_camera_position = position;
  56. }
  57. void RainRenderer::submit(Renderer &renderer, ResourceManager *resources) {
  58. (void)resources;
  59. if (!m_enabled) {
  60. return;
  61. }
  62. const float delta_time = 0.016F;
  63. if (m_intensity < m_target_intensity) {
  64. m_intensity = std::min(m_target_intensity,
  65. m_intensity + delta_time * k_intensity_lerp_speed);
  66. } else if (m_intensity > m_target_intensity) {
  67. m_intensity = std::max(m_target_intensity,
  68. m_intensity - delta_time * k_intensity_lerp_speed);
  69. }
  70. if (m_intensity < 0.001F) {
  71. return;
  72. }
  73. const float time = renderer.get_animation_time();
  74. const auto visible_count = static_cast<std::size_t>(
  75. static_cast<float>(m_rain_drops.size()) * m_intensity);
  76. if (visible_count == 0) {
  77. return;
  78. }
  79. if (!m_instance_buffer) {
  80. m_instance_buffer = std::make_unique<Buffer>(Buffer::Type::Vertex);
  81. }
  82. m_instance_buffer->set_data(m_rain_drops.data(),
  83. visible_count * sizeof(RainDropInstanceGpu),
  84. Buffer::Usage::Dynamic);
  85. m_params.time = time;
  86. m_params.intensity = m_intensity;
  87. renderer.rain_batch(m_instance_buffer.get(), visible_count, m_params);
  88. }
  89. void RainRenderer::clear() {
  90. m_rain_drops.clear();
  91. m_instance_buffer.reset();
  92. m_instance_count = 0;
  93. m_intensity = 0.0F;
  94. m_target_intensity = 0.0F;
  95. }
  96. void RainRenderer::generate_rain_drops() {
  97. m_rain_drops.clear();
  98. const std::size_t max_drops =
  99. (m_params.weather_type == Game::Map::WeatherType::Snow)
  100. ? k_max_snow_drops
  101. : k_max_rain_drops;
  102. m_rain_drops.reserve(max_drops);
  103. uint32_t state = m_seed;
  104. for (std::size_t i = 0; i < max_drops; ++i) {
  105. state = hash_coords(static_cast<int>(i), static_cast<int>(i * 17),
  106. m_seed ^ 0xDA1A1234U);
  107. const float x = (rand_01(state) - 0.5F) * m_rain_area_radius * 2.0F;
  108. state = hash_coords(static_cast<int>(i * 31), static_cast<int>(i), state);
  109. const float z = (rand_01(state) - 0.5F) * m_rain_area_radius * 2.0F;
  110. state =
  111. hash_coords(static_cast<int>(i * 7), static_cast<int>(i * 13), state);
  112. const float y = rand_01(state) * m_rain_height;
  113. state = hash_coords(static_cast<int>(i), static_cast<int>(i * 23), state);
  114. float speed_variation;
  115. if (m_params.weather_type == Game::Map::WeatherType::Snow) {
  116. speed_variation =
  117. RainBatchParams::k_snow_speed_variation_min +
  118. rand_01(state) * RainBatchParams::k_snow_speed_variation_range;
  119. } else {
  120. speed_variation =
  121. RainBatchParams::k_rain_speed_variation_min +
  122. rand_01(state) * RainBatchParams::k_rain_speed_variation_range;
  123. }
  124. RainDropInstanceGpu drop;
  125. drop.pos_velocity =
  126. QVector4D(x, y, z, m_params.drop_speed * speed_variation);
  127. drop.size_alpha =
  128. QVector4D(m_params.drop_length, m_params.drop_width, 1.0F, 0.0F);
  129. m_rain_drops.push_back(drop);
  130. }
  131. m_instance_count = m_rain_drops.size();
  132. }
  133. } // namespace Render::GL