diff --git a/src/engine/drawable.cc b/src/engine/drawable.cc index 7643606..1288e1e 100644 --- a/src/engine/drawable.cc +++ b/src/engine/drawable.cc @@ -1,6 +1,7 @@ #include "engine/drawable.h" #include "engine/engine.h" +#include "engine/renderer/shader.h" namespace eng { @@ -12,4 +13,17 @@ Drawable::~Drawable() { Engine::Get().RemoveDrawable(this); } +void Drawable::SetCustomShader(const std::string& asset_name) { + custom_shader_ = Engine::Get().GetShader(asset_name); + custom_uniforms_.clear(); +} + +void Drawable::DoSetCustomUniforms() { + if (custom_shader_) { + for (auto& cu : custom_uniforms_) + std::visit([&](auto&& arg) { custom_shader_->SetUniform(cu.first, arg); }, + cu.second); + } +} + } // namespace eng diff --git a/src/engine/drawable.h b/src/engine/drawable.h index 6739f0a..22244d1 100644 --- a/src/engine/drawable.h +++ b/src/engine/drawable.h @@ -1,10 +1,16 @@ #ifndef ENGINE_DRAWABLE_H #define ENGINE_DRAWABLE_H +#include +#include +#include + #include "base/vecmath.h" namespace eng { +class Shader; + class Drawable { public: Drawable(); @@ -21,9 +27,30 @@ class Drawable { int GetZOrder() const { return z_order_; } bool IsVisible() const { return visible_; } + void SetCustomShader(const std::string& asset_name); + + template + void SetCustomUniform(const std::string& name, T value) { + custom_uniforms_[name] = UniformValue(value); + } + + protected: + Shader* GetCustomShader() { return custom_shader_; } + void DoSetCustomUniforms(); + private: + using UniformValue = std::variant; + bool visible_ = false; int z_order_ = 0; + + Shader* custom_shader_ = nullptr; + std::unordered_map custom_uniforms_; }; } // namespace eng diff --git a/src/engine/image_quad.cc b/src/engine/image_quad.cc index ed1b55b..2b597d0 100644 --- a/src/engine/image_quad.cc +++ b/src/engine/image_quad.cc @@ -40,11 +40,6 @@ void ImageQuad::Destroy() { } } -void ImageQuad::SetCustomShader(const std::string& asset_name) { - custom_shader_ = Engine::Get().GetShader(asset_name); - custom_uniforms_.clear(); -} - void ImageQuad::SetFrame(size_t frame) { DCHECK(frame < GetNumFrames()) << "asset: " << asset_name_ << " frame: " << frame; @@ -66,8 +61,9 @@ void ImageQuad::Draw(float frame_frac) { Vector2f tex_scale = {GetFrameWidth() / texture_->GetWidth(), GetFrameHeight() / texture_->GetHeight()}; - Shader* shader = - custom_shader_ ? custom_shader_ : Engine::Get().GetPassThroughShader(); + Shader* shader = GetCustomShader(); + if (!shader) + shader = Engine::Get().GetPassThroughShader(); shader->Activate(); shader->SetUniform("offset", position_); @@ -78,12 +74,7 @@ void ImageQuad::Draw(float frame_frac) { shader->SetUniform("projection", Engine::Get().GetProjectionMatrix()); shader->SetUniform("color", color_); shader->SetUniform("texture_0", 0); - if (custom_shader_) { - for (auto& cu : custom_uniforms_) - std::visit( - [shader, &cu](auto&& arg) { shader->SetUniform(cu.first, arg); }, - cu.second); - } + DoSetCustomUniforms(); shader->UploadUniforms(); Engine::Get().GetQuad()->Draw(); diff --git a/src/engine/image_quad.h b/src/engine/image_quad.h index 660dc95..694affd 100644 --- a/src/engine/image_quad.h +++ b/src/engine/image_quad.h @@ -3,15 +3,12 @@ #include #include -#include -#include #include "base/vecmath.h" #include "engine/animatable.h" namespace eng { -class Shader; class Texture; class ImageQuad final : public Animatable { @@ -26,13 +23,6 @@ class ImageQuad final : public Animatable { void Destroy(); - void SetCustomShader(const std::string& asset_name); - - template - void SetCustomUniform(const std::string& name, T value) { - custom_uniforms_[name] = UniformValue(value); - } - // Animatable interface. void SetFrame(size_t frame) final; size_t GetFrame() const final { return current_frame_; } @@ -44,18 +34,8 @@ class ImageQuad final : public Animatable { void Draw(float frame_frac) final; private: - using UniformValue = std::variant; - Texture* texture_ = nullptr; - Shader* custom_shader_ = nullptr; - std::unordered_map custom_uniforms_; - size_t current_frame_ = 0; std::array num_frames_ = {1, 1}; // horizontal, vertical int frame_width_ = 0; diff --git a/src/engine/solid_quad.cc b/src/engine/solid_quad.cc index d71573e..60984b7 100644 --- a/src/engine/solid_quad.cc +++ b/src/engine/solid_quad.cc @@ -12,7 +12,9 @@ namespace eng { void SolidQuad::Draw(float frame_frac) { DCHECK(IsVisible()); - Shader* shader = Engine::Get().GetSolidShader(); + Shader* shader = GetCustomShader(); + if (!shader) + shader = Engine::Get().GetSolidShader(); shader->Activate(); shader->SetUniform("offset", position_); @@ -20,6 +22,7 @@ void SolidQuad::Draw(float frame_frac) { shader->SetUniform("rotation", rotation_); shader->SetUniform("projection", Engine::Get().GetProjectionMatrix()); shader->SetUniform("color", color_); + DoSetCustomUniforms(); shader->UploadUniforms(); Engine::Get().GetQuad()->Draw();