diff --git a/assets/sky.glsl_fragment b/assets/sky.glsl_fragment index a15a60d..17457b0 100644 --- a/assets/sky.glsl_fragment +++ b/assets/sky.glsl_fragment @@ -1,9 +1,5 @@ #ifdef GL_ES precision highp float; -#else -#define lowp -#define mediump -#define highp #endif IN(0) vec2 tex_coord_0; @@ -17,19 +13,25 @@ UNIFORM_END FRAG_COLOR_OUT(frag_color) +const float PHI = 1.61803398874989484820459; // Golden Ratio + float random(vec2 p) { float sd = sin(dot(p, vec2(54.90898, 18.233))); return fract(sd * 2671.6182); } +float random2(in vec2 xy) { + return fract(tan(distance(xy * PHI, xy)) * (xy.x + 0.1)); +} + float nebula(in vec2 p) { vec2 i = floor(p); vec2 f = fract(p); - float a = random(i); - float b = random(i + vec2(1.0, 0.0)); - float c = random(i + vec2(0.0, 1.0)); - float d = random(i + vec2(1.0, 1.0)); + float a = random2(i); + float b = random2(i + vec2(1.0, 0.0)); + float c = random2(i + vec2(0.0, 1.0)); + float d = random2(i + vec2(1.0, 1.0)); vec2 u = smoothstep(0.0, 1.0, f); @@ -52,7 +54,7 @@ float stars(in vec2 p, float num_cells, float size) { void main() { vec2 layer1_coord = tex_coord_0 + PARAM(sky_offset); vec2 layer2_coord = tex_coord_0 + PARAM(sky_offset) * 0.7; - mediump vec3 result = vec3(0.); + vec3 result = vec3(0.); float c = nebula(layer2_coord * 3.0) * 0.35 - 0.05; result += PARAM(nebula_color) * floor(c * 60.0) / 60.0; diff --git a/assets/sky_without_nebula.glsl_fragment b/assets/sky_without_nebula.glsl_fragment index 46441ba..804c10c 100644 --- a/assets/sky_without_nebula.glsl_fragment +++ b/assets/sky_without_nebula.glsl_fragment @@ -1,9 +1,5 @@ #ifdef GL_ES precision highp float; -#else -#define lowp -#define mediump -#define highp #endif IN(0) vec2 tex_coord_0; @@ -35,7 +31,7 @@ float stars(in vec2 p, float num_cells, float size) { void main() { vec2 layer1_coord = tex_coord_0 + PARAM(sky_offset); vec2 layer2_coord = tex_coord_0 + PARAM(sky_offset) * 0.7; - mediump vec3 result = vec3(0.); + vec3 result = vec3(0.); float c = stars(layer1_coord, 8.0, 0.05); result += vec3(0.97, 0.74, 0.74) * c; diff --git a/src/demo/demo.cc b/src/demo/demo.cc index 8dfaf7c..2d3747f 100644 --- a/src/demo/demo.cc +++ b/src/demo/demo.cc @@ -447,9 +447,9 @@ void Demo::StartNextStage(bool boss) { Vector4f c = {Lerp(0.75f, 0.95f, rnd.Rand()) * weights[0], Lerp(0.75f, 0.95f, rnd.Rand()) * weights[1], Lerp(0.75f, 0.95f, rnd.Rand()) * weights[2], 1}; - c += {Lerp(0.1f, 0.5f, rnd.Rand()) * (1 - weights[0]), - Lerp(0.1f, 0.5f, rnd.Rand()) * (1 - weights[1]), - Lerp(0.1f, 0.5f, rnd.Rand()) * (1 - weights[2]), 1}; + c += {Lerp(0.1f, 0.7f, rnd.Rand()) * (1 - weights[0]), + Lerp(0.1f, 0.7f, rnd.Rand()) * (1 - weights[1]), + Lerp(0.1f, 0.7f, rnd.Rand()) * (1 - weights[2]), 1}; sky_.SwitchColor(c); ++wave_; @@ -457,9 +457,9 @@ void Demo::StartNextStage(bool boss) { hud_.SetProgress(1); if (boss_fight_) - player_.TakeDamage(-3); + player_.TakeDamage(-1); - total_enemies_ = 20.0f + 23.0897f * log((float)wave_); + total_enemies_ = 23.0897f * log((float)wave_ + 1.0f) - 10.0f; last_num_enemies_killed_ = 0; boss_fight_ = false; DLOG << "wave: " << wave_ << " total_enemies_: " << total_enemies_; @@ -489,6 +489,7 @@ void Demo::Dimmer(bool enable) { dimmer_.SetColor(kBgColor * Vector4f(0, 0, 0, 0)); dimmer_animator_.SetBlending(kBgColor, kFadeSpeed); dimmer_animator_.Play(Animator::kBlending, false); + dimmer_animator_.SetEndCallback(Animator::kBlending, nullptr); dimmer_animator_.SetVisible(true); } else if (!enable && dimmer_active_) { dimmer_active_ = false; diff --git a/src/demo/enemy.cc b/src/demo/enemy.cc index a7aea24..5c78220 100644 --- a/src/demo/enemy.cc +++ b/src/demo/enemy.cc @@ -148,7 +148,8 @@ void Enemy::Update(float delta_time) { if (it->chromatic_aberration_active_) { it->sprite.SetCustomUniform( - "aberration_offset", Lerp(0.0f, 0.01f, chromatic_aberration_offset_)); + "aberration_offset", + Lerp(0.0f, 0.015f, chromatic_aberration_offset_)); } #if defined(LOAD_TEST) else if (it->kill_timer <= 0 && @@ -406,6 +407,8 @@ bool Enemy::IsBossAlive() const { } void Enemy::PauseProgress() { + DeselectTarget(kDamageType_Green); + DeselectTarget(kDamageType_Blue); progress_paused_ = true; } @@ -784,8 +787,7 @@ void Enemy::SpawnBoss() { auto& e = enemies_.emplace_front(); e.enemy_type = kEnemyType_Boss; e.damage_type = kDamageType_Any; - e.total_health = e.hit_points = - -15.0845f + 41.1283f * log((float)game->wave()); + e.total_health = e.hit_points = 41.1283f * log((float)game->wave()) - 20.0f; DLOG << " Boss health: " << e.total_health; Vector2f hit_box_pos = @@ -1080,7 +1082,7 @@ void Enemy::UpdateWave(float delta_time) { SpawnUnit(kEnemyType_PowerUp, kDamageType_Any, pos, 6); } seconds_since_last_power_up_ = 0; - seconds_to_next_power_up_ = Lerp(1.3f * 60.0f, 1.8f * 60.0f, rnd.Rand()); + seconds_to_next_power_up_ = Lerp(60.0f, 80.0f, rnd.Rand()); } } @@ -1100,9 +1102,6 @@ void Enemy::UpdateBoss(float delta_time) { if (boss_spawn_factor < 0.1f) boss_spawn_factor = 0.1f; - DLOG << "boss_spawn_time_: " << boss_spawn_time_ - << " boss_spawn_factor: " << boss_spawn_factor; - EnemyType enemy_type = kEnemyType_Invalid; for (int i = 0; i < kEnemyType_Unit_Last + 1; ++i) { diff --git a/src/demo/menu.cc b/src/demo/menu.cc index f90d987..a288d99 100644 --- a/src/demo/menu.cc +++ b/src/demo/menu.cc @@ -81,7 +81,12 @@ bool Menu::Initialize() { items_[i].select_item_cb_ = [&, i]() -> void { items_[i].text_animator.SetEndCallback(Animator::kBlending, nullptr); - selected_option_ = (Option)i; + // Wait until click sound ends before exiting. + if (i == kExit) + click_.SetEndCallback( + [&, i]() -> void { selected_option_ = (Option)i; }); + else + selected_option_ = (Option)i; }; items_[i].text_animator.Attach(&items_[i].text); } diff --git a/src/demo/player.cc b/src/demo/player.cc index d19a162..a78f71e 100644 --- a/src/demo/player.cc +++ b/src/demo/player.cc @@ -288,7 +288,7 @@ void Player::SetupWeapons() { weapon_[i].SetFrame(wepon_warmup_frame[i]); warmup_animator_[i].SetFrames(wepon_warmup_frame_count, wepon_anim_speed); - warmup_animator_[i].SetRotation(M_PI * 2, 8.0f); + warmup_animator_[i].SetRotation(M_PI * 2, 20.0f); warmup_animator_[i].Attach(&weapon_[i]); warmup_animator_[i].Play(Animator::kRotation, true); diff --git a/src/engine/animator.cc b/src/engine/animator.cc index c976297..941cbb6 100644 --- a/src/engine/animator.cc +++ b/src/engine/animator.cc @@ -180,9 +180,13 @@ void Animator::Update(float delta_time) { UpdateAnimTime(delta_time, kFrames, frame_speed_, frame_time_, frame_cb_); if (play_flags_ & kTimer) UpdateAnimTime(delta_time, kTimer, timer_speed_, timer_time_, timer_cb_); + + did_evaluate_ = false; } void Animator::Evaluate(float frame_frac_time) { + did_evaluate_ = true; + Vector2f pos = {0, 0}; if (play_flags_ & kMovement) { float time = movement_time_ + movement_speed_ * frame_frac_time; @@ -248,6 +252,8 @@ void Animator::UpdateAnimTime(float delta_time, if (loop_flags_ & anim) { anim_time = fmod(anim_time, 1.0f); } else { + if (!did_evaluate_) + Evaluate(0); anim_time = 0; play_flags_ &= ~anim; if (cb) { diff --git a/src/engine/animator.h b/src/engine/animator.h index ce02922..05659a1 100644 --- a/src/engine/animator.h +++ b/src/engine/animator.h @@ -120,6 +120,8 @@ class Animator { base::Closure pending_cb_; Flags inside_cb_ = kNone; + bool did_evaluate_ = false; + void UpdateAnimTime(float delta_time, int anim, float anim_speed, diff --git a/src/engine/engine.cc b/src/engine/engine.cc index fb76f8f..60240ab 100644 --- a/src/engine/engine.cc +++ b/src/engine/engine.cc @@ -222,31 +222,27 @@ void Engine::SetImageSource(const std::string& asset_name, void Engine::SetImageSource(const std::string& asset_name, CreateImageCB create_image, bool persistent) { - Texture* texture; - auto it = textures_.find(asset_name); - if (it != textures_.end()) { - texture = it->second.texture.get(); - it->second.create_image = create_image; - it->second.persistent = persistent; - } else { - auto& t = textures_[asset_name] = {CreateRenderResource(), - create_image, persistent, 0}; - texture = t.texture.get(); + if (textures_.contains(asset_name) && textures_[asset_name].use_count > 0) { + DLOG << "Texture in use: " << asset_name; + return; } + auto& t = textures_[asset_name] = {CreateRenderResource(), + create_image, persistent, 0}; + if (persistent) { auto image = create_image(); if (image) - texture->Update(std::move(image)); - else - texture->Destroy(); + t.texture->Update(std::move(image)); } } void Engine::RefreshImage(const std::string& asset_name) { auto it = textures_.find(asset_name); - if (it == textures_.end()) + if (it == textures_.end()) { + DLOG << "Texture not found: " << asset_name; return; + } auto image = it->second.create_image(); if (image) @@ -257,22 +253,23 @@ void Engine::RefreshImage(const std::string& asset_name) { Texture* Engine::AcquireTexture(const std::string& asset_name) { auto it = textures_.find(asset_name); - if (it != textures_.end()) { - if (!it->second.texture->IsValid()) - RefreshImage(it->first); - it->second.use_count++; - return it->second.texture.get(); + if (it == textures_.end()) { + DLOG << "Texture not found: " << asset_name; + return nullptr; } - auto& t = textures_[asset_name] = {CreateRenderResource(), nullptr, - false, 1}; - return t.texture.get(); + if (!it->second.texture->IsValid()) + RefreshImage(it->first); + it->second.use_count++; + return it->second.texture.get(); } void Engine::ReleaseTexture(const std::string& asset_name) { auto it = textures_.find(asset_name); - if (it == textures_.end()) + if (it == textures_.end()) { + DLOG << "Texture not found: " << asset_name; return; + } DCHECK(it->second.use_count > 0); it->second.use_count--; diff --git a/src/engine/image_quad.cc b/src/engine/image_quad.cc index a77d4de..bd6ef9a 100644 --- a/src/engine/image_quad.cc +++ b/src/engine/image_quad.cc @@ -33,8 +33,10 @@ void ImageQuad::Create(const std::string& asset_name, } void ImageQuad::Destory() { - Engine::Get().ReleaseTexture(asset_name_); - texture_ = nullptr; + if (texture_) { + Engine::Get().ReleaseTexture(asset_name_); + texture_ = nullptr; + } } void ImageQuad::AutoScale() { diff --git a/src/engine/renderer/vulkan/renderer_vulkan.cc b/src/engine/renderer/vulkan/renderer_vulkan.cc index d9e8ef8..56d86f2 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan.cc +++ b/src/engine/renderer/vulkan/renderer_vulkan.cc @@ -971,7 +971,7 @@ bool RendererVulkan::InitializeInternal() { // Begin the first command buffer for the first frame. BeginFrame(); - if (context_lost_cb_) { + if (context_lost_ && context_lost_cb_) { LOG << "Context lost."; context_lost_cb_(); } @@ -984,6 +984,7 @@ void RendererVulkan::Shutdown() { LOG << "Shutting down renderer."; DestroyAllResources(); + context_lost_ = true; quit_.store(true, std::memory_order_relaxed); semaphore_.release(); diff --git a/src/engine/renderer/vulkan/renderer_vulkan.h b/src/engine/renderer/vulkan/renderer_vulkan.h index 1796a92..bb333fc 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan.h +++ b/src/engine/renderer/vulkan/renderer_vulkan.h @@ -152,6 +152,8 @@ class RendererVulkan final : public Renderer { std::unordered_map textures_; uint64_t last_resource_id_ = 0; + bool context_lost_ = false; + VulkanContext context_; VmaAllocator allocator_ = nullptr; diff --git a/src/engine/renderer/vulkan/vulkan_context.cc b/src/engine/renderer/vulkan/vulkan_context.cc index 948c9c8..cb246fd 100644 --- a/src/engine/renderer/vulkan/vulkan_context.cc +++ b/src/engine/renderer/vulkan/vulkan_context.cc @@ -58,7 +58,6 @@ void VulkanContext::Shutdown() { vkDestroyDevice(device_, nullptr); device_ = VK_NULL_HANDLE; } - buffers_prepared_ = false; queues_initialized_ = false; separate_present_queue_ = false; swapchain_image_count_ = 0; @@ -788,10 +787,7 @@ void VulkanContext::DestroyWindow() { } VkFramebuffer VulkanContext::GetFramebuffer() { - return buffers_prepared_ - ? window_.swapchain_image_resources[window_.current_buffer] - .frame_buffer - : VK_NULL_HANDLE; + return window_.swapchain_image_resources[window_.current_buffer].frame_buffer; } bool VulkanContext::CleanUpSwapChain(Window* window) { @@ -1421,23 +1417,20 @@ bool VulkanContext::PrepareBuffers() { if (err == VK_ERROR_OUT_OF_DATE_KHR) { // swapchain is out of date (e.g. the window was resized) and must be // recreated: - DLOG << "Swapchain is out of date."; + DLOG << "Swapchain is out of date, recreating."; UpdateSwapChain(&window_); } else if (err == VK_SUBOPTIMAL_KHR) { - DLOG << "Swapchain is suboptimal."; // swapchain is not as optimal as it could be, but the platform's // presentation engine will still present the image correctly. + DLOG << "Swapchain is suboptimal, recreating."; + UpdateSwapChain(&window_); break; - } else { - if (err) { - DLOG << "AcquireNextImageKHR failed. Error: " << err; - return false; - } + } else if (err != VK_SUCCESS) { + DLOG << "AcquireNextImageKHR failed. Error: " << err; + return false; } } while (err != VK_SUCCESS); - buffers_prepared_ = true; - return true; } @@ -1552,7 +1545,6 @@ bool VulkanContext::SwapBuffers() { return false; } - buffers_prepared_ = false; return true; } diff --git a/src/engine/renderer/vulkan/vulkan_context.h b/src/engine/renderer/vulkan/vulkan_context.h index c47a74e..ff5107d 100644 --- a/src/engine/renderer/vulkan/vulkan_context.h +++ b/src/engine/renderer/vulkan/vulkan_context.h @@ -96,8 +96,6 @@ class VulkanContext { uint32_t queue_family_count_ = 0; std::unique_ptr queue_props_ = nullptr; - bool buffers_prepared_ = false; - bool queues_initialized_ = false; bool separate_present_queue_ = false;