From e376b1bc1780141a65669d08ab0943344b83d495 Mon Sep 17 00:00:00 2001 From: Attila Uygun Date: Thu, 1 Jun 2023 20:55:39 +0200 Subject: [PATCH] Add option to switch between renderers --- assets/renderer_logo.png | Bin 0 -> 12850 bytes src/demo/menu.cc | 50 +++++++++++++++---- src/demo/menu.h | 10 +++- src/engine/engine.cc | 26 +++++++--- src/engine/engine.h | 12 +++-- src/engine/renderer/opengl/renderer_opengl.h | 2 + src/engine/renderer/renderer.h | 4 ++ src/engine/renderer/vulkan/renderer_vulkan.h | 2 + 8 files changed, 80 insertions(+), 26 deletions(-) create mode 100644 assets/renderer_logo.png diff --git a/assets/renderer_logo.png b/assets/renderer_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..802488e490ffda25b6d48942473c5b4457b26753 GIT binary patch literal 12850 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 kColorSwitch = {Vector4f{0.003f, 0.91f, 0.99f, 1}, + Vector4f{0.33f, 0.47, 0.51f, 1}}; +const Vector4f kColorFadeIn = {1, 1, 1, 1}; const Vector4f kColorFadeOut = {1, 1, 1, 0}; constexpr float kFadeSpeed = 0.2f; @@ -150,7 +152,8 @@ bool Menu::Initialize() { } game->saved_data().root()["audio"] = toggle_audio_.enabled(); }, - true, game->saved_data().root().get("audio", Json::Value(true)).asBool()); + true, game->saved_data().root().get("audio", Json::Value(true)).asBool(), + kColorFadeOut, kColorSwitch); toggle_audio_.image().SetPosition(Engine::Get().GetScreenSize() * Vector2f(0, -0.25f)); toggle_audio_.image().Scale(0.7f); @@ -162,7 +165,8 @@ bool Menu::Initialize() { game->SetEnableMusic(toggle_music_.enabled()); game->saved_data().root()["music"] = toggle_music_.enabled(); }, - true, game->saved_data().root().get("music", Json::Value(true)).asBool()); + true, game->saved_data().root().get("music", Json::Value(true)).asBool(), + kColorFadeOut, kColorSwitch); toggle_music_.image().SetPosition(Engine::Get().GetScreenSize() * Vector2f(0, -0.25f)); toggle_music_.image().Scale(0.7f); @@ -177,7 +181,8 @@ bool Menu::Initialize() { game->saved_data().root()["vibration"] = toggle_vibration_.enabled(); }, true, - game->saved_data().root().get("vibration", Json::Value(true)).asBool()); + game->saved_data().root().get("vibration", Json::Value(true)).asBool(), + kColorFadeOut, kColorSwitch); toggle_vibration_.image().SetPosition(Engine::Get().GetScreenSize() * Vector2f(0, -0.25f)); toggle_vibration_.image().Scale(0.7f); @@ -188,6 +193,21 @@ bool Menu::Initialize() { toggle_vibration_.image().Translate( {toggle_music_.image().GetSize().x / 2, 0}); + renderer_type_.Create( + "renderer_logo", {2, 1}, 0, 1, + [&] { + Engine::Get().CreateRenderer(renderer_type_.enabled() + ? RendererType::kVulkan + : RendererType::kOpenGL); + renderer_type_.SetEnabled( + (Engine::Get().GetRendererType() == RendererType::kVulkan)); + }, + true, Engine::Get().GetRendererType() == RendererType::kVulkan, + kColorFadeOut, {Vector4f{1, 1, 1, 1}, Vector4f{1, 1, 1, 1}}); + renderer_type_.image().PlaceToBottomOf(toggle_music_.image()); + renderer_type_.image().Translate(toggle_music_.image().GetPosition() * + Vector2f(0, 1.1f)); + high_score_value_ = game->GetHighScore(); high_score_.Create("high_score_tex"); @@ -226,7 +246,7 @@ bool Menu::Initialize() { starting_wave_.image().SetFrame(start_from_wave_ / 3); click_.Play(false); }, - false, true); + false, true, kColorFadeOut, kColorSwitch); wave_up_.image().Scale(1.5f); return true; @@ -236,6 +256,7 @@ void Menu::OnInputEvent(std::unique_ptr event) { if (toggle_audio_.OnInputEvent(event.get()) || toggle_music_.OnInputEvent(event.get()) || toggle_vibration_.OnInputEvent(event.get()) || + renderer_type_.OnInputEvent(event.get()) || (wave_up_.image().IsVisible() && wave_up_.OnInputEvent(event.get()))) return; @@ -350,6 +371,7 @@ void Menu::Show() { toggle_audio_.Show(); toggle_music_.Show(); toggle_vibration_.Show(); + renderer_type_.Show(); Demo* game = static_cast(Engine::Get().GetGame()); @@ -410,6 +432,7 @@ void Menu::Hide(Closure cb) { toggle_audio_.Hide(); toggle_music_.Hide(); toggle_vibration_.Hide(); + renderer_type_.Hide(); if (starting_wave_.image().IsVisible()) { starting_wave_.Hide(); @@ -425,6 +448,7 @@ bool Menu::CreateRenderResources() { Engine::Get().SetImageSource("buttons_tex", "menu_icons.png"); Engine::Get().SetImageSource("high_score_tex", std::bind(&Menu::CreateHighScoreImage, this)); + Engine::Get().SetImageSource("renderer_logo", "renderer_logo.png"); Engine::Get().SetImageSource("wave_up_tex", []() -> std::unique_ptr { const Font& font = static_cast(Engine::Get().GetGame())->GetFont(); @@ -520,16 +544,20 @@ void Menu::Button::Create(const std::string& asset_name, int frame2, Closure pressed_cb, bool switch_control, - bool enabled) { + bool enabled, + const Vector4f& fade_out_color, + const std::array& switch_color) { frame1_ = frame1; frame2_ = frame2; pressed_cb_ = std::move(pressed_cb); switch_control_ = switch_control; enabled_ = enabled; + fade_out_color_ = fade_out_color; + switch_color_ = switch_color; image_.Create(asset_name, num_frames); image_.SetFrame(enabled ? frame1 : frame2); - image_.SetColor(kColorFadeOut); + image_.SetColor(fade_out_color_); image_.SetZOrder(41); image_.SetVisible(false); @@ -562,14 +590,14 @@ bool Menu::Button::OnInputEvent(eng::InputEvent* event) { void Menu::Button::Show() { animator_.SetVisible(true); - animator_.SetBlending(enabled_ ? kColorSwitch[0] : kColorSwitch[1], + animator_.SetBlending(enabled_ ? switch_color_[0] : switch_color_[1], kBlendingSpeed); animator_.Play(Animator::kBlending, false); animator_.SetEndCallback(Animator::kBlending, nullptr); } void Menu::Button::Hide() { - animator_.SetBlending(kColorFadeOut, kBlendingSpeed); + animator_.SetBlending(fade_out_color_, kBlendingSpeed); animator_.Play(Animator::kBlending, false); animator_.SetEndCallback(Animator::kBlending, [&]() -> void { animator_.SetVisible(false); }); @@ -579,7 +607,7 @@ void Menu::Button::SetEnabled(bool enable) { if (switch_control_) { enabled_ = enable; image_.SetFrame(enabled_ ? frame1_ : frame2_); - image_.SetColor(enabled_ ? kColorSwitch[0] : kColorSwitch[1]); + image_.SetColor(enabled_ ? switch_color_[0] : switch_color_[1]); } } diff --git a/src/demo/menu.h b/src/demo/menu.h index 894490c..9a42216 100644 --- a/src/demo/menu.h +++ b/src/demo/menu.h @@ -55,13 +55,17 @@ class Menu { int frame2, base::Closure pressed_cb, bool switch_control, - bool enabled); + bool enabled, + const base::Vector4f& fade_out_color, + const std::array& switch_color); bool OnInputEvent(eng::InputEvent* event); void Show(); void Hide(); + void SetEnabled(bool enable); + eng::ImageQuad& image() { return image_; }; bool enabled() const { return enabled_; } @@ -77,7 +81,8 @@ class Menu { bool enabled_ = false; base::Vector2f tap_pos_[2] = {{0, 0}, {0, 0}}; - void SetEnabled(bool enable); + base::Vector4f fade_out_color_; + std::array switch_color_; }; class Radio { @@ -126,6 +131,7 @@ class Menu { Button toggle_audio_; Button toggle_music_; Button toggle_vibration_; + Button renderer_type_; size_t high_score_value_ = 0; diff --git a/src/engine/engine.cc b/src/engine/engine.cc index fc7e0e8..3622287 100644 --- a/src/engine/engine.cc +++ b/src/engine/engine.cc @@ -106,7 +106,7 @@ void Engine::Initialize() { thread_pool_.Initialize(); - CreateRenderer(true); + CreateRenderer(RendererType::kVulkan); // Normalize viewport. if (GetScreenWidth() > GetScreenHeight()) { @@ -201,23 +201,27 @@ void Engine::RemoveAnimator(Animator* animator) { } } -void Engine::CreateRenderer(bool vulkan) { - if ((dynamic_cast(renderer_.get()) && vulkan) || - (dynamic_cast(renderer_.get()) && !vulkan)) +void Engine::CreateRenderer(RendererType type) { + if ((dynamic_cast(renderer_.get()) && + type == RendererType::kVulkan) || + (dynamic_cast(renderer_.get()) && + type == RendererType::kOpenGL)) return; - if (vulkan) + if (type == RendererType::kVulkan) renderer_ = std::make_unique(std::bind(&Engine::ContextLost, this)); - else + else if (type == RendererType::kOpenGL) renderer_ = std::make_unique(std::bind(&Engine::ContextLost, this)); + else + NOTREACHED; bool result = renderer_->Initialize(platform_); - if (!result && vulkan) { + if (!result && type == RendererType::kVulkan) { LOG << "Failed to initialize " << renderer_->GetDebugName() << " renderer."; LOG << "Fallback to OpenGL renderer."; - CreateRenderer(false); + CreateRenderer(RendererType::kOpenGL); return; } CHECK(result) << "Failed to initialize " << renderer_->GetDebugName() @@ -227,6 +231,12 @@ void Engine::CreateRenderer(bool vulkan) { ContextLost(); } +RendererType Engine::GetRendererType() { + if (renderer_) + return renderer_->GetRendererType(); + return RendererType::kUnknown; +} + void Engine::Exit() { platform_->Exit(); } diff --git a/src/engine/engine.h b/src/engine/engine.h index d694e00..bbbe77f 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -20,17 +20,18 @@ namespace eng { class Animator; class AudioMixer; +class Drawable; class Font; class Game; -class Drawable; -class InputEvent; +class Geometry; class Image; class ImageQuad; +class InputEvent; +class Platform; class Renderer; -class Geometry; class Shader; class Texture; -class Platform; +enum class RendererType; class Engine : public PlatformObserver { public: @@ -49,7 +50,8 @@ class Engine : public PlatformObserver { void AddAnimator(Animator* animator); void RemoveAnimator(Animator* animator); - void CreateRenderer(bool vulkan); + void CreateRenderer(RendererType type); + RendererType GetRendererType(); void Exit(); diff --git a/src/engine/renderer/opengl/renderer_opengl.h b/src/engine/renderer/opengl/renderer_opengl.h index bf7c798..be582be 100644 --- a/src/engine/renderer/opengl/renderer_opengl.h +++ b/src/engine/renderer/opengl/renderer_opengl.h @@ -86,6 +86,8 @@ class RendererOpenGL final : public Renderer { const char* GetDebugName() final { return "OpenGL"; } + RendererType GetRendererType() final { return RendererType::kOpenGL; } + private: struct GeometryOpenGL { struct Element { diff --git a/src/engine/renderer/renderer.h b/src/engine/renderer/renderer.h index 352852f..a539ee0 100644 --- a/src/engine/renderer/renderer.h +++ b/src/engine/renderer/renderer.h @@ -15,6 +15,8 @@ class ShaderSource; class Mesh; class Platform; +enum class RendererType { kUnknown, kVulkan, kOpenGL }; + class Renderer { public: const unsigned kInvalidId = 0; @@ -82,6 +84,8 @@ class Renderer { virtual const char* GetDebugName() = 0; + virtual RendererType GetRendererType() { return RendererType::kUnknown; } + protected: struct TextureCompression { unsigned etc1 : 1; diff --git a/src/engine/renderer/vulkan/renderer_vulkan.h b/src/engine/renderer/vulkan/renderer_vulkan.h index 3412053..6addbef 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan.h +++ b/src/engine/renderer/vulkan/renderer_vulkan.h @@ -69,6 +69,8 @@ class RendererVulkan final : public Renderer { const char* GetDebugName() final { return "Vulkan"; } + RendererType GetRendererType() final { return RendererType::kVulkan; } + private: // VkBuffer or VkImage with allocator. template