mirror of
https://github.com/hyprwm/hyprlock.git
synced 2024-12-21 21:09:49 +01:00
widgets: Reload backgrounds and not just images (#583)
* widgets: Reload background and fade * clang-format also clang-format * undo possibly unwanted format on Renderer.hpp * rename stuff + style * codestyle + initialize reloadTime * remove trailing eols
This commit is contained in:
parent
381a284b3b
commit
058830668e
7 changed files with 365 additions and 30 deletions
|
@ -191,6 +191,9 @@ void CConfigManager::init() {
|
|||
m_config.addSpecialConfigValue("background", "vibrancy", Hyprlang::FLOAT{0.1686});
|
||||
m_config.addSpecialConfigValue("background", "vibrancy_darkness", Hyprlang::FLOAT{0.05});
|
||||
m_config.addSpecialConfigValue("background", "zindex", Hyprlang::INT{-1});
|
||||
m_config.addSpecialConfigValue("background", "reload_time", Hyprlang::INT{-1});
|
||||
m_config.addSpecialConfigValue("background", "reload_cmd", Hyprlang::STRING{""});
|
||||
m_config.addSpecialConfigValue("background", "crossfade_time", Hyprlang::FLOAT{-1.0});
|
||||
|
||||
m_config.addSpecialCategory("shape", Hyprlang::SSpecialCategoryOptions{.key = nullptr, .anonymousKeyBased = true});
|
||||
m_config.addSpecialConfigValue("shape", "monitor", Hyprlang::STRING{""});
|
||||
|
@ -318,6 +321,9 @@ std::vector<CConfigManager::SWidgetConfig> CConfigManager::getWidgetConfigs() {
|
|||
{"brightness", m_config.getSpecialConfigValue("background", "brightness", k.c_str())},
|
||||
{"vibrancy_darkness", m_config.getSpecialConfigValue("background", "vibrancy_darkness", k.c_str())},
|
||||
{"zindex", m_config.getSpecialConfigValue("background", "zindex", k.c_str())},
|
||||
{"reload_time", m_config.getSpecialConfigValue("background", "reload_time", k.c_str())},
|
||||
{"reload_cmd", m_config.getSpecialConfigValue("background", "reload_cmd", k.c_str())},
|
||||
{"crossfade_time", m_config.getSpecialConfigValue("background", "crossfade_time", k.c_str())},
|
||||
}
|
||||
});
|
||||
// clang-format on
|
||||
|
|
|
@ -106,6 +106,27 @@ CRenderer::CRenderer() {
|
|||
texShader.tint = glGetUniformLocation(prog, "tint");
|
||||
texShader.useAlphaMatte = glGetUniformLocation(prog, "useAlphaMatte");
|
||||
|
||||
prog = createProgram(TEXVERTSRC, TEXMIXFRAGSRCRGBA);
|
||||
texMixShader.program = prog;
|
||||
texMixShader.proj = glGetUniformLocation(prog, "proj");
|
||||
texMixShader.tex = glGetUniformLocation(prog, "tex1");
|
||||
texMixShader.tex2 = glGetUniformLocation(prog, "tex2");
|
||||
texMixShader.alphaMatte = glGetUniformLocation(prog, "texMatte");
|
||||
texMixShader.alpha = glGetUniformLocation(prog, "alpha");
|
||||
texMixShader.mixFactor = glGetUniformLocation(prog, "mixFactor");
|
||||
texMixShader.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
texMixShader.matteTexAttrib = glGetAttribLocation(prog, "texcoordMatte");
|
||||
texMixShader.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
texMixShader.discardOpaque = glGetUniformLocation(prog, "discardOpaque");
|
||||
texMixShader.discardAlpha = glGetUniformLocation(prog, "discardAlpha");
|
||||
texMixShader.discardAlphaValue = glGetUniformLocation(prog, "discardAlphaValue");
|
||||
texMixShader.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
texMixShader.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
texMixShader.radius = glGetUniformLocation(prog, "radius");
|
||||
texMixShader.applyTint = glGetUniformLocation(prog, "applyTint");
|
||||
texMixShader.tint = glGetUniformLocation(prog, "tint");
|
||||
texMixShader.useAlphaMatte = glGetUniformLocation(prog, "useAlphaMatte");
|
||||
|
||||
prog = createProgram(TEXVERTSRC, FRAGBLUR1);
|
||||
blurShader1.program = prog;
|
||||
blurShader1.tex = glGetUniformLocation(prog, "tex");
|
||||
|
@ -347,6 +368,52 @@ void CRenderer::renderTexture(const CBox& box, const CTexture& tex, float a, int
|
|||
glBindTexture(tex.m_iTarget, 0);
|
||||
}
|
||||
|
||||
void CRenderer::renderTextureMix(const CBox& box, const CTexture& tex, const CTexture& tex2, float a, float mixFactor, int rounding, std::optional<eTransform> tr) {
|
||||
const auto ROUNDEDBOX = box.copy().round();
|
||||
Mat3x3 matrix = projMatrix.projectBox(ROUNDEDBOX, tr.value_or(HYPRUTILS_TRANSFORM_FLIPPED_180), box.rot);
|
||||
Mat3x3 glMatrix = projection.copy().multiply(matrix);
|
||||
|
||||
CShader* shader = &texMixShader;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(tex.m_iTarget, tex.m_iTexID);
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(tex2.m_iTarget, tex2.m_iTexID);
|
||||
|
||||
glUseProgram(shader->program);
|
||||
|
||||
glUniformMatrix3fv(shader->proj, 1, GL_TRUE, glMatrix.getMatrix().data());
|
||||
glUniform1i(shader->tex, 0);
|
||||
glUniform1i(shader->tex2, 1);
|
||||
glUniform1f(shader->alpha, a);
|
||||
glUniform1f(shader->mixFactor, mixFactor);
|
||||
const auto TOPLEFT = Vector2D(ROUNDEDBOX.x, ROUNDEDBOX.y);
|
||||
const auto FULLSIZE = Vector2D(ROUNDEDBOX.width, ROUNDEDBOX.height);
|
||||
|
||||
// Rounded corners
|
||||
glUniform2f(shader->topLeft, TOPLEFT.x, TOPLEFT.y);
|
||||
glUniform2f(shader->fullSize, FULLSIZE.x, FULLSIZE.y);
|
||||
glUniform1f(shader->radius, rounding);
|
||||
|
||||
glUniform1i(shader->discardOpaque, 0);
|
||||
glUniform1i(shader->discardAlpha, 0);
|
||||
glUniform1i(shader->applyTint, 0);
|
||||
|
||||
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
glEnableVertexAttribArray(shader->posAttrib);
|
||||
glEnableVertexAttribArray(shader->texAttrib);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
glDisableVertexAttribArray(shader->posAttrib);
|
||||
glDisableVertexAttribArray(shader->texAttrib);
|
||||
|
||||
glBindTexture(tex.m_iTarget, 0);
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<IWidget>>* CRenderer::getOrCreateWidgetsFor(const CSessionLockSurface* surf) {
|
||||
if (!widgets.contains(surf)) {
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ class CRenderer {
|
|||
void renderRect(const CBox& box, const CColor& col, int rounding = 0);
|
||||
void renderBorder(const CBox& box, const CGradientValueData& gradient, int thickness, int rounding = 0, float alpha = 1.0);
|
||||
void renderTexture(const CBox& box, const CTexture& tex, float a = 1.0, int rounding = 0, std::optional<eTransform> tr = {});
|
||||
void renderTextureMix(const CBox& box, const CTexture& tex, const CTexture& tex2, float a = 1.0, float mixFactor = 0.0, int rounding = 0, std::optional<eTransform> tr = {});
|
||||
void blurFB(const CFramebuffer& outfb, SBlurParams params);
|
||||
|
||||
std::unique_ptr<CAsyncResourceGatherer> asyncResourceGatherer;
|
||||
|
@ -50,6 +51,7 @@ class CRenderer {
|
|||
|
||||
CShader rectShader;
|
||||
CShader texShader;
|
||||
CShader texMixShader;
|
||||
CShader blurShader1;
|
||||
CShader blurShader2;
|
||||
CShader blurPrepareShader;
|
||||
|
|
|
@ -13,7 +13,9 @@ class CShader {
|
|||
GLint color = -1;
|
||||
GLint alphaMatte = -1;
|
||||
GLint tex = -1;
|
||||
GLint tex2 = -1;
|
||||
GLint alpha = -1;
|
||||
GLfloat mixFactor = -1;
|
||||
GLint posAttrib = -1;
|
||||
GLint texAttrib = -1;
|
||||
GLint matteTexAttrib = -1;
|
||||
|
|
|
@ -129,6 +129,49 @@ void main() {
|
|||
gl_FragColor = pixColor * alpha;
|
||||
})#";
|
||||
|
||||
inline const std::string TEXMIXFRAGSRCRGBA = R"#(
|
||||
precision highp float;
|
||||
varying vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex1;
|
||||
uniform sampler2D tex2;
|
||||
uniform float mixFactor;
|
||||
uniform float alpha;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
|
||||
uniform int discardOpaque;
|
||||
uniform int discardAlpha;
|
||||
uniform float discardAlphaValue;
|
||||
|
||||
uniform int applyTint;
|
||||
uniform vec3 tint;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = mix(texture2D(tex1, v_texcoord), texture2D(tex2, v_texcoord), smoothstep(0.0, 1.0, mixFactor));
|
||||
|
||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0)
|
||||
discard;
|
||||
|
||||
if (discardAlpha == 1 && pixColor[3] <= discardAlphaValue)
|
||||
discard;
|
||||
|
||||
if (applyTint == 1) {
|
||||
pixColor[0] = pixColor[0] * tint[0];
|
||||
pixColor[1] = pixColor[1] * tint[1];
|
||||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
if (radius > 0.0) {
|
||||
)#" +
|
||||
ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
}
|
||||
|
||||
gl_FragColor = pixColor * alpha;
|
||||
})#";
|
||||
|
||||
inline const std::string FRAGBLUR1 = R"#(
|
||||
#version 100
|
||||
precision highp float;
|
||||
|
|
|
@ -1,18 +1,58 @@
|
|||
#include "Background.hpp"
|
||||
#include "../Renderer.hpp"
|
||||
#include "../../core/hyprlock.hpp"
|
||||
#include "src/helpers/Log.hpp"
|
||||
#include <chrono>
|
||||
#include <hyprlang.hpp>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <GLES3/gl32.h>
|
||||
|
||||
CBackground::~CBackground() {
|
||||
|
||||
if (reloadTimer) {
|
||||
reloadTimer->cancel();
|
||||
reloadTimer.reset();
|
||||
}
|
||||
|
||||
if (fade) {
|
||||
if (fade->crossFadeTimer) {
|
||||
fade->crossFadeTimer->cancel();
|
||||
fade->crossFadeTimer.reset();
|
||||
}
|
||||
fade.reset();
|
||||
}
|
||||
}
|
||||
|
||||
CBackground::CBackground(const Vector2D& viewport_, COutput* output_, const std::string& resourceID_, const std::unordered_map<std::string, std::any>& props, bool ss) :
|
||||
viewport(viewport_), resourceID(resourceID_), output(output_), isScreenshot(ss) {
|
||||
|
||||
color = std::any_cast<Hyprlang::INT>(props.at("color"));
|
||||
blurPasses = std::any_cast<Hyprlang::INT>(props.at("blur_passes"));
|
||||
blurSize = std::any_cast<Hyprlang::INT>(props.at("blur_size"));
|
||||
vibrancy = std::any_cast<Hyprlang::FLOAT>(props.at("vibrancy"));
|
||||
vibrancy_darkness = std::any_cast<Hyprlang::FLOAT>(props.at("vibrancy_darkness"));
|
||||
noise = std::any_cast<Hyprlang::FLOAT>(props.at("noise"));
|
||||
brightness = std::any_cast<Hyprlang::FLOAT>(props.at("brightness"));
|
||||
contrast = std::any_cast<Hyprlang::FLOAT>(props.at("contrast"));
|
||||
try {
|
||||
color = std::any_cast<Hyprlang::INT>(props.at("color"));
|
||||
blurPasses = std::any_cast<Hyprlang::INT>(props.at("blur_passes"));
|
||||
blurSize = std::any_cast<Hyprlang::INT>(props.at("blur_size"));
|
||||
vibrancy = std::any_cast<Hyprlang::FLOAT>(props.at("vibrancy"));
|
||||
vibrancy_darkness = std::any_cast<Hyprlang::FLOAT>(props.at("vibrancy_darkness"));
|
||||
noise = std::any_cast<Hyprlang::FLOAT>(props.at("noise"));
|
||||
brightness = std::any_cast<Hyprlang::FLOAT>(props.at("brightness"));
|
||||
contrast = std::any_cast<Hyprlang::FLOAT>(props.at("contrast"));
|
||||
path = std::any_cast<Hyprlang::STRING>(props.at("path"));
|
||||
reloadCommand = std::any_cast<Hyprlang::STRING>(props.at("reload_cmd"));
|
||||
reloadTime = std::any_cast<Hyprlang::INT>(props.at("reload_time"));
|
||||
crossFadeTime = std::any_cast<Hyprlang::FLOAT>(props.at("crossfade_time"));
|
||||
|
||||
} catch (const std::bad_any_cast& e) {
|
||||
RASSERT(false, "Failed to construct CBackground: {}", e.what()); //
|
||||
} catch (const std::out_of_range& e) {
|
||||
RASSERT(false, "Missing propperty for CBackground: {}", e.what()); //
|
||||
}
|
||||
|
||||
try {
|
||||
modificationTime = std::filesystem::last_write_time(path);
|
||||
} catch (std::exception& e) { Debug::log(ERR, "{}", e.what()); }
|
||||
|
||||
if (!isScreenshot)
|
||||
plantReloadTimer(); // No reloads for screenshots.
|
||||
}
|
||||
|
||||
void CBackground::renderRect(CColor color) {
|
||||
|
@ -20,6 +60,27 @@ void CBackground::renderRect(CColor color) {
|
|||
g_pRenderer->renderRect(monbox, color, 0);
|
||||
}
|
||||
|
||||
static void onReloadTimer(std::shared_ptr<CTimer> self, void* data) {
|
||||
const auto PBG = (CBackground*)data;
|
||||
|
||||
PBG->onReloadTimerUpdate();
|
||||
PBG->plantReloadTimer();
|
||||
}
|
||||
|
||||
static void onCrossFadeTimer(std::shared_ptr<CTimer> self, void* data) {
|
||||
const auto PBG = (CBackground*)data;
|
||||
PBG->onCrossFadeTimerUpdate();
|
||||
}
|
||||
|
||||
static void onAssetCallback(void* data) {
|
||||
const auto PBG = (CBackground*)data;
|
||||
PBG->startCrossFadeOrUpdateRender();
|
||||
}
|
||||
|
||||
static void onAssetCallbackTimer(std::shared_ptr<CTimer> self, void* data) {
|
||||
onAssetCallback(data);
|
||||
}
|
||||
|
||||
bool CBackground::draw(const SRenderData& data) {
|
||||
|
||||
if (resourceID.empty()) {
|
||||
|
@ -45,10 +106,13 @@ bool CBackground::draw(const SRenderData& data) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if ((blurPasses > 0 || isScreenshot) && !blurredFB.isAllocated()) {
|
||||
if (fade || ((blurPasses > 0 || isScreenshot) && (!blurredFB.isAllocated() || firstRender))) {
|
||||
|
||||
if (firstRender)
|
||||
firstRender = false;
|
||||
|
||||
// make it brah
|
||||
Vector2D size = asset->texture.m_vSize;
|
||||
|
||||
if (output->transform % 2 == 1 && isScreenshot) {
|
||||
size.x = asset->texture.m_vSize.y;
|
||||
size.y = asset->texture.m_vSize.x;
|
||||
|
@ -67,13 +131,23 @@ bool CBackground::draw(const SRenderData& data) {
|
|||
else
|
||||
texbox.x = -(texbox.w - viewport.x) / 2.f;
|
||||
texbox.round();
|
||||
blurredFB.alloc(viewport.x, viewport.y); // TODO 10 bit
|
||||
|
||||
if (!blurredFB.isAllocated())
|
||||
blurredFB.alloc(viewport.x, viewport.y); // TODO 10 bit
|
||||
|
||||
blurredFB.bind();
|
||||
|
||||
g_pRenderer->renderTexture(texbox, asset->texture, 1.0, 0,
|
||||
isScreenshot ?
|
||||
wlTransformToHyprutils(invertTransform(output->transform)) :
|
||||
HYPRUTILS_TRANSFORM_NORMAL); // this could be omitted but whatever it's only once and makes code cleaner plus less blurring on large texs
|
||||
if (fade)
|
||||
g_pRenderer->renderTextureMix(texbox, asset->texture, pendingAsset->texture, 1.0,
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - fade->start).count() / (1000 * crossFadeTime),
|
||||
0, HYPRUTILS_TRANSFORM_NORMAL);
|
||||
else
|
||||
g_pRenderer->renderTexture(texbox, asset->texture, 1.0, 0,
|
||||
isScreenshot ?
|
||||
wlTransformToHyprutils(invertTransform(output->transform)) :
|
||||
HYPRUTILS_TRANSFORM_NORMAL); // this could be omitted but whatever it's only once and makes code cleaner plus less blurring on large texs
|
||||
|
||||
|
||||
if (blurPasses > 0)
|
||||
g_pRenderer->blurFB(blurredFB, CRenderer::SBlurParams{blurSize, blurPasses, noise, contrast, brightness, vibrancy, vibrancy_darkness});
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
|
@ -97,5 +171,114 @@ bool CBackground::draw(const SRenderData& data) {
|
|||
texbox.round();
|
||||
g_pRenderer->renderTexture(texbox, *tex, data.opacity, 0, HYPRUTILS_TRANSFORM_FLIPPED_180);
|
||||
|
||||
return data.opacity < 1.0;
|
||||
return fade || data.opacity < 1.0; // actively render during fading
|
||||
}
|
||||
|
||||
void CBackground::plantReloadTimer() {
|
||||
|
||||
if (reloadTime == 0)
|
||||
reloadTimer = g_pHyprlock->addTimer(std::chrono::hours(1), onReloadTimer, this, true);
|
||||
else if (reloadTime > 0)
|
||||
reloadTimer = g_pHyprlock->addTimer(std::chrono::seconds(reloadTime), onReloadTimer, this, false);
|
||||
}
|
||||
|
||||
void CBackground::onCrossFadeTimerUpdate() {
|
||||
|
||||
// Animation done: Unload previous asset, deinitialize the fade and pass the asset
|
||||
|
||||
if (fade) {
|
||||
fade->crossFadeTimer.reset();
|
||||
fade.reset(nullptr);
|
||||
}
|
||||
|
||||
if (!(blurPasses > 0 || isScreenshot))
|
||||
blurredFB.release();
|
||||
|
||||
asset = pendingAsset;
|
||||
resourceID = pendingResourceID;
|
||||
pendingResourceID = "";
|
||||
pendingAsset = nullptr;
|
||||
firstRender = true;
|
||||
|
||||
g_pHyprlock->renderOutput(output->stringPort);
|
||||
}
|
||||
|
||||
void CBackground::onReloadTimerUpdate() {
|
||||
const std::string OLDPATH = path;
|
||||
|
||||
// Path parsing and early returns
|
||||
|
||||
if (!reloadCommand.empty()) {
|
||||
path = g_pHyprlock->spawnSync(reloadCommand);
|
||||
|
||||
if (path.ends_with('\n'))
|
||||
path.pop_back();
|
||||
|
||||
if (path.starts_with("file://"))
|
||||
path = path.substr(7);
|
||||
|
||||
if (path.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const auto MTIME = std::filesystem::last_write_time(path);
|
||||
if (OLDPATH == path && MTIME == modificationTime)
|
||||
return;
|
||||
|
||||
modificationTime = MTIME;
|
||||
} catch (std::exception& e) {
|
||||
path = OLDPATH;
|
||||
Debug::log(ERR, "{}", e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pendingResourceID.empty())
|
||||
return;
|
||||
|
||||
// Issue the next request
|
||||
|
||||
request.id = std::string{"background:"} + path + ",time:" + std::to_string((uint64_t)modificationTime.time_since_epoch().count());
|
||||
pendingResourceID = request.id;
|
||||
request.asset = path;
|
||||
request.type = CAsyncResourceGatherer::eTargetType::TARGET_IMAGE;
|
||||
|
||||
request.callback = onAssetCallback;
|
||||
request.callbackData = this;
|
||||
|
||||
g_pRenderer->asyncResourceGatherer->requestAsyncAssetPreload(request);
|
||||
}
|
||||
|
||||
void CBackground::startCrossFadeOrUpdateRender() {
|
||||
auto newAsset = g_pRenderer->asyncResourceGatherer->getAssetByID(pendingResourceID);
|
||||
if (newAsset) {
|
||||
if (newAsset->texture.m_iType == TEXTURE_INVALID) {
|
||||
g_pRenderer->asyncResourceGatherer->unloadAsset(newAsset);
|
||||
Debug::log(ERR, "New asset had an invalid texture!");
|
||||
} else if (resourceID != pendingResourceID) {
|
||||
pendingAsset = newAsset;
|
||||
if (crossFadeTime > 0) {
|
||||
// Start a fade
|
||||
if (!fade)
|
||||
fade = std::make_unique<SFade>(std::chrono::system_clock::now(), 0, nullptr);
|
||||
else {
|
||||
// Maybe we where already fading so reset it just in case, but should'nt be happening.
|
||||
if (fade->crossFadeTimer) {
|
||||
fade->crossFadeTimer->cancel();
|
||||
fade->crossFadeTimer.reset();
|
||||
}
|
||||
}
|
||||
fade->start = std::chrono::system_clock::now();
|
||||
fade->a = 0;
|
||||
fade->crossFadeTimer = g_pHyprlock->addTimer(std::chrono::milliseconds((int)(1000.0 * crossFadeTime)), onCrossFadeTimer, this);
|
||||
} else {
|
||||
onCrossFadeTimerUpdate();
|
||||
}
|
||||
}
|
||||
} else if (!pendingResourceID.empty()) {
|
||||
Debug::log(WARN, "Asset {} not available after the asyncResourceGatherer's callback!", pendingResourceID);
|
||||
g_pHyprlock->addTimer(std::chrono::milliseconds(100), onAssetCallbackTimer, this);
|
||||
}
|
||||
|
||||
g_pHyprlock->renderOutput(output->stringPort);
|
||||
}
|
|
@ -3,36 +3,68 @@
|
|||
#include "IWidget.hpp"
|
||||
#include "../../helpers/Color.hpp"
|
||||
#include "../../helpers/Math.hpp"
|
||||
#include "../../core/Timer.hpp"
|
||||
#include "../Framebuffer.hpp"
|
||||
#include "../AsyncResourceGatherer.hpp"
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <any>
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
|
||||
struct SPreloadedAsset;
|
||||
class COutput;
|
||||
|
||||
struct SFade {
|
||||
std::chrono::system_clock::time_point start;
|
||||
float a = 0;
|
||||
std::shared_ptr<CTimer> crossFadeTimer = nullptr;
|
||||
};
|
||||
|
||||
class CBackground : public IWidget {
|
||||
public:
|
||||
CBackground(const Vector2D& viewport, COutput* output_, const std::string& resourceID, const std::unordered_map<std::string, std::any>& props, bool ss_);
|
||||
~CBackground();
|
||||
|
||||
virtual bool draw(const SRenderData& data);
|
||||
void renderRect(CColor color);
|
||||
|
||||
void onReloadTimerUpdate();
|
||||
void onCrossFadeTimerUpdate();
|
||||
void plantReloadTimer();
|
||||
void startCrossFadeOrUpdateRender();
|
||||
|
||||
private:
|
||||
// if needed
|
||||
CFramebuffer blurredFB;
|
||||
CFramebuffer blurredFB;
|
||||
|
||||
int blurSize = 10;
|
||||
int blurPasses = 3;
|
||||
float noise = 0.0117;
|
||||
float contrast = 0.8916;
|
||||
float brightness = 0.8172;
|
||||
float vibrancy = 0.1696;
|
||||
float vibrancy_darkness = 0.0;
|
||||
Vector2D viewport;
|
||||
std::string resourceID;
|
||||
CColor color;
|
||||
SPreloadedAsset* asset = nullptr;
|
||||
COutput* output = nullptr;
|
||||
bool isScreenshot = false;
|
||||
int blurSize = 10;
|
||||
int blurPasses = 3;
|
||||
float noise = 0.0117;
|
||||
float contrast = 0.8916;
|
||||
float brightness = 0.8172;
|
||||
float vibrancy = 0.1696;
|
||||
float vibrancy_darkness = 0.0;
|
||||
Vector2D viewport;
|
||||
std::string path = "";
|
||||
|
||||
std::string resourceID;
|
||||
std::string pendingResourceID;
|
||||
|
||||
float crossFadeTime = -1.0;
|
||||
|
||||
CColor color;
|
||||
SPreloadedAsset* asset = nullptr;
|
||||
COutput* output = nullptr;
|
||||
bool isScreenshot = false;
|
||||
SPreloadedAsset* pendingAsset = nullptr;
|
||||
bool firstRender = true;
|
||||
|
||||
std::unique_ptr<SFade> fade;
|
||||
|
||||
int reloadTime = -1;
|
||||
std::string reloadCommand;
|
||||
CAsyncResourceGatherer::SPreloadRequest request;
|
||||
std::shared_ptr<CTimer> reloadTimer;
|
||||
std::filesystem::file_time_type modificationTime;
|
||||
};
|
Loading…
Reference in a new issue