Move custom shader from ImageQuad to Drawable

This commit is contained in:
Attila Uygun 2023-09-30 23:23:30 +02:00
parent 02418aa42a
commit 261e7f41d6
5 changed files with 49 additions and 34 deletions

View File

@ -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

View File

@ -1,10 +1,16 @@
#ifndef ENGINE_DRAWABLE_H
#define ENGINE_DRAWABLE_H
#include <string>
#include <unordered_map>
#include <variant>
#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 <typename T>
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<base::Vector2f,
base::Vector3f,
base::Vector4f,
base::Matrix4f,
float,
int>;
bool visible_ = false;
int z_order_ = 0;
Shader* custom_shader_ = nullptr;
std::unordered_map<std::string, UniformValue> custom_uniforms_;
};
} // namespace eng

View File

@ -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();

View File

@ -3,15 +3,12 @@
#include <array>
#include <string>
#include <unordered_map>
#include <variant>
#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 <typename T>
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<base::Vector2f,
base::Vector3f,
base::Vector4f,
base::Matrix4f,
float,
int>;
Texture* texture_ = nullptr;
Shader* custom_shader_ = nullptr;
std::unordered_map<std::string, UniformValue> custom_uniforms_;
size_t current_frame_ = 0;
std::array<int, 2> num_frames_ = {1, 1}; // horizontal, vertical
int frame_width_ = 0;

View File

@ -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();