add post-effect-slot resource & add gfx.posteffects library
This commit is contained in:
@@ -1,15 +1,16 @@
|
||||
#include "PostEffect.hpp"
|
||||
|
||||
#include "Shader.hpp"
|
||||
#include "data/dv_util.hpp"
|
||||
|
||||
PostEffect::Param::Param() : type(Type::FLOAT) {}
|
||||
|
||||
PostEffect::Param::Param(Type type, Value defValue)
|
||||
: type(type), defValue(std::move(defValue)) {
|
||||
: type(type), defValue(defValue), value(defValue) {
|
||||
}
|
||||
|
||||
PostEffect::PostEffect(
|
||||
std::unique_ptr<Shader> shader,
|
||||
std::shared_ptr<Shader> shader,
|
||||
std::unordered_map<std::string, Param> params
|
||||
)
|
||||
: shader(std::move(shader)), params(std::move(params)) {
|
||||
@@ -18,9 +19,65 @@ PostEffect::PostEffect(
|
||||
Shader& PostEffect::use() {
|
||||
shader->use();
|
||||
shader->uniform1f("u_intensity", intensity);
|
||||
for (auto& [name, param] : params) {
|
||||
if (!param.dirty) {
|
||||
continue;
|
||||
}
|
||||
switch (param.type) {
|
||||
case Param::Type::FLOAT:
|
||||
shader->uniform1f(name, std::get<float>(param.value));
|
||||
break;
|
||||
case Param::Type::VEC2:
|
||||
shader->uniform2f(name, std::get<glm::vec2>(param.value));
|
||||
break;
|
||||
case Param::Type::VEC3:
|
||||
shader->uniform3f(name, std::get<glm::vec3>(param.value));
|
||||
break;
|
||||
case Param::Type::VEC4:
|
||||
shader->uniform4f(name, std::get<glm::vec4>(param.value));
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
param.dirty = false;
|
||||
}
|
||||
return *shader;
|
||||
}
|
||||
|
||||
float PostEffect::getIntensity() const {
|
||||
return intensity;
|
||||
}
|
||||
|
||||
void PostEffect::setIntensity(float value) {
|
||||
intensity = value;
|
||||
}
|
||||
|
||||
template<int n>
|
||||
static void set_value(PostEffect::Param::Value& dst, const dv::value& value) {
|
||||
glm::vec<n, float> vec;
|
||||
dv::get_vec(value, vec);
|
||||
dst = vec;
|
||||
}
|
||||
|
||||
void PostEffect::setParam(const std::string& name, const dv::value& value) {
|
||||
const auto& found = params.find(name);
|
||||
if (found == params.end()) {
|
||||
return;
|
||||
}
|
||||
auto& param = found->second;
|
||||
switch (param.type) {
|
||||
case Param::Type::FLOAT:
|
||||
param.value = static_cast<float>(value.asNumber());
|
||||
break;
|
||||
case Param::Type::VEC2:
|
||||
set_value<2>(param.value, value);
|
||||
break;
|
||||
case Param::Type::VEC3:
|
||||
set_value<3>(param.value, value);
|
||||
break;
|
||||
case Param::Type::VEC4:
|
||||
set_value<4>(param.value, value);
|
||||
break;
|
||||
}
|
||||
param.dirty = true;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <unordered_map>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "data/dv_fwd.hpp"
|
||||
|
||||
class Shader;
|
||||
|
||||
class PostEffect {
|
||||
@@ -16,25 +18,32 @@ public:
|
||||
|
||||
Type type;
|
||||
Value defValue;
|
||||
Value value;
|
||||
bool dirty = true;
|
||||
|
||||
Param();
|
||||
Param(Type type, Value defValue);
|
||||
};
|
||||
|
||||
PostEffect(
|
||||
std::unique_ptr<Shader> shader,
|
||||
std::shared_ptr<Shader> shader,
|
||||
std::unordered_map<std::string, Param> params
|
||||
);
|
||||
|
||||
explicit PostEffect(const PostEffect&) = default;
|
||||
|
||||
Shader& use();
|
||||
|
||||
float getIntensity() const;
|
||||
void setIntensity(float value);
|
||||
|
||||
void setParam(const std::string& name, const dv::value& value);
|
||||
|
||||
bool isActive() {
|
||||
return intensity > 1e-4f;
|
||||
}
|
||||
private:
|
||||
std::unique_ptr<Shader> shader;
|
||||
std::shared_ptr<Shader> shader;
|
||||
std::unordered_map<std::string, Param> params;
|
||||
float intensity = 0.0f;
|
||||
};
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
PostProcessing::PostProcessing() {
|
||||
PostProcessing::PostProcessing(size_t effectSlotsCount)
|
||||
: effectSlots(effectSlotsCount) {
|
||||
// Fullscreen quad mesh bulding
|
||||
float vertices[] {
|
||||
-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
|
||||
@@ -77,6 +78,14 @@ void PostProcessing::render(
|
||||
}
|
||||
}
|
||||
|
||||
void PostProcessing::setEffect(size_t slot, std::shared_ptr<PostEffect> effect) {
|
||||
effectSlots.at(slot) = std::move(effect);
|
||||
}
|
||||
|
||||
PostEffect* PostProcessing::getEffect(size_t slot) {
|
||||
return effectSlots.at(slot).get();
|
||||
}
|
||||
|
||||
std::unique_ptr<ImageData> PostProcessing::toImage() {
|
||||
return fbo->getTexture()->readData();
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ class PostProcessing {
|
||||
std::unique_ptr<Mesh> quadMesh;
|
||||
std::vector<std::shared_ptr<PostEffect>> effectSlots;
|
||||
public:
|
||||
PostProcessing();
|
||||
PostProcessing(size_t effectSlotsCount);
|
||||
~PostProcessing();
|
||||
|
||||
/// @brief Prepare and bind framebuffer
|
||||
@@ -34,6 +34,10 @@ public:
|
||||
/// @throws std::runtime_error if use(...) wasn't called before
|
||||
void render(const DrawContext& context, const Assets& assets, float timer);
|
||||
|
||||
void setEffect(size_t slot, std::shared_ptr<PostEffect> effect);
|
||||
|
||||
PostEffect* getEffect(size_t slot);
|
||||
|
||||
/// @brief Make an image from the last rendered frame
|
||||
std::unique_ptr<ImageData> toImage();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user