mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-24 23:45:58 +01:00
corner radii
This commit is contained in:
parent
880996b053
commit
2cf2a0d986
17 changed files with 332 additions and 182 deletions
|
@ -563,7 +563,7 @@ void CWindow::applyDynamicRule(const SWindowRule& r) {
|
|||
m_sAdditionalConfigData.nearestNeighbor = true;
|
||||
} else if (r.szRule.starts_with("rounding")) {
|
||||
try {
|
||||
m_sAdditionalConfigData.rounding = std::stoi(r.szRule.substr(r.szRule.find_first_of(' ') + 1));
|
||||
m_sAdditionalConfigData.cornerRadii = configStringToRadii(r.szRule);
|
||||
} catch (std::exception& e) { Debug::log(ERR, "Rounding rule \"{}\" failed with: {}", r.szRule, e.what()); }
|
||||
} else if (r.szRule.starts_with("bordersize")) {
|
||||
try {
|
||||
|
@ -656,7 +656,7 @@ void CWindow::updateDynamicRules() {
|
|||
m_sAdditionalConfigData.forceOpaque = false;
|
||||
m_sAdditionalConfigData.forceNoAnims = false;
|
||||
m_sAdditionalConfigData.animationStyle = std::string("");
|
||||
m_sAdditionalConfigData.rounding = -1;
|
||||
m_sAdditionalConfigData.cornerRadii = -1;
|
||||
m_sAdditionalConfigData.dimAround = false;
|
||||
m_sAdditionalConfigData.forceRGBX = false;
|
||||
m_sAdditionalConfigData.borderSize = -1;
|
||||
|
@ -678,27 +678,29 @@ void CWindow::updateDynamicRules() {
|
|||
// it is assumed that the point is within the real window box (m_vRealPosition, m_vRealSize)
|
||||
// otherwise behaviour is undefined
|
||||
bool CWindow::isInCurvedCorner(double x, double y) {
|
||||
const int ROUNDING = rounding();
|
||||
if (getRealBorderSize() >= ROUNDING)
|
||||
const CCornerRadiiData ROUNDING = getCornerRadii();
|
||||
const int BORDER = getRealBorderSize();
|
||||
|
||||
if (BORDER >= ROUNDING.topLeft && BORDER >= ROUNDING.topRight && BORDER >= ROUNDING.bottomLeft && BORDER >= ROUNDING.bottomRight)
|
||||
return false;
|
||||
|
||||
// (x0, y0), (x0, y1), ... are the center point of rounding at each corner
|
||||
double x0 = m_vRealPosition.vec().x + ROUNDING;
|
||||
double y0 = m_vRealPosition.vec().y + ROUNDING;
|
||||
double x1 = m_vRealPosition.vec().x + m_vRealSize.vec().x - ROUNDING;
|
||||
double y1 = m_vRealPosition.vec().y + m_vRealSize.vec().y - ROUNDING;
|
||||
// topLeft, topRight, bottomLeft, bottomRight, ... are the center point of rounding at each corner
|
||||
Vector2D topLeft = {m_vRealPosition.vec().x + ROUNDING.topLeft, m_vRealPosition.vec().y + ROUNDING.topLeft};
|
||||
Vector2D topRight = {m_vRealPosition.vec().x + m_vRealSize.vec().x + ROUNDING.topRight, m_vRealPosition.vec().y + ROUNDING.topRight};
|
||||
Vector2D bottomLeft = {m_vRealPosition.vec().x + ROUNDING.bottomLeft, m_vRealPosition.vec().y + m_vRealSize.vec().y + ROUNDING.bottomLeft};
|
||||
Vector2D bottomRight = {m_vRealPosition.vec().x + m_vRealSize.vec().x + ROUNDING.bottomRight, m_vRealPosition.vec().y + m_vRealSize.vec().y + ROUNDING.bottomRight};
|
||||
|
||||
if (x < x0 && y < y0) {
|
||||
return Vector2D{x0, y0}.distance(Vector2D{x, y}) > (double)ROUNDING;
|
||||
if (x < topLeft.x && y < topLeft.y) {
|
||||
return topLeft.distance(Vector2D{x, y}) > (double)ROUNDING.topLeft;
|
||||
}
|
||||
if (x > x1 && y < y0) {
|
||||
return Vector2D{x1, y0}.distance(Vector2D{x, y}) > (double)ROUNDING;
|
||||
if (x > topRight.x && y < topRight.y) {
|
||||
return topRight.distance(Vector2D{x, y}) > (double)ROUNDING.topRight;
|
||||
}
|
||||
if (x < x0 && y > y1) {
|
||||
return Vector2D{x0, y1}.distance(Vector2D{x, y}) > (double)ROUNDING;
|
||||
if (x < bottomLeft.x && y > bottomLeft.y) {
|
||||
return bottomLeft.distance(Vector2D{x, y}) > (double)ROUNDING.bottomLeft;
|
||||
}
|
||||
if (x > x1 && y > y1) {
|
||||
return Vector2D{x1, y1}.distance(Vector2D{x, y}) > (double)ROUNDING;
|
||||
if (x > bottomRight.x && y > bottomRight.y) {
|
||||
return bottomRight.distance(Vector2D{x, y}) > (double)ROUNDING.bottomRight;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -989,12 +991,12 @@ bool CWindow::opaque() {
|
|||
return false;
|
||||
}
|
||||
|
||||
float CWindow::rounding() {
|
||||
static auto* const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||
CCornerRadiiData CWindow::getCornerRadii() {
|
||||
static auto* const PRADII = (CCornerRadiiData*)g_pConfigManager->getConfigValuePtr("decoration:rounding")->data.get();
|
||||
|
||||
float rounding = m_sAdditionalConfigData.rounding.toUnderlying() == -1 ? *PROUNDING : m_sAdditionalConfigData.rounding.toUnderlying();
|
||||
CCornerRadiiData radii = m_sAdditionalConfigData.cornerRadii.toUnderlying() == -1 ? *PRADII : m_sAdditionalConfigData.cornerRadii.toUnderlying();
|
||||
|
||||
return m_sSpecialRenderData.rounding ? rounding : 0;
|
||||
return m_sSpecialRenderData.rounding ? radii : 0;
|
||||
}
|
||||
|
||||
void CWindow::updateSpecialRenderData() {
|
||||
|
|
|
@ -35,8 +35,8 @@ class IWindowTransformer;
|
|||
template <typename T>
|
||||
class CWindowOverridableVar {
|
||||
public:
|
||||
CWindowOverridableVar(T val) {
|
||||
value = val;
|
||||
CWindowOverridableVar(T val)
|
||||
: value(val) {
|
||||
}
|
||||
|
||||
~CWindowOverridableVar() = default;
|
||||
|
@ -51,7 +51,7 @@ class CWindowOverridableVar {
|
|||
return *this;
|
||||
}
|
||||
|
||||
T operator=(T& other) {
|
||||
T operator=(const T& other) {
|
||||
if (locked)
|
||||
return value;
|
||||
value = other;
|
||||
|
@ -123,25 +123,25 @@ struct SWindowSpecialRenderData {
|
|||
};
|
||||
|
||||
struct SWindowAdditionalConfigData {
|
||||
std::string animationStyle = std::string("");
|
||||
CWindowOverridableVar<int> rounding = -1; // -1 means no
|
||||
CWindowOverridableVar<bool> forceNoBlur = false;
|
||||
CWindowOverridableVar<bool> forceOpaque = false;
|
||||
CWindowOverridableVar<bool> forceOpaqueOverridden = false; // if true, a rule will not change the forceOpaque state. This is for the force opaque dispatcher.
|
||||
CWindowOverridableVar<bool> forceAllowsInput = false;
|
||||
CWindowOverridableVar<bool> forceNoAnims = false;
|
||||
CWindowOverridableVar<bool> forceNoBorder = false;
|
||||
CWindowOverridableVar<bool> forceNoShadow = false;
|
||||
CWindowOverridableVar<bool> forceNoDim = false;
|
||||
CWindowOverridableVar<bool> windowDanceCompat = false;
|
||||
CWindowOverridableVar<bool> noMaxSize = false;
|
||||
CWindowOverridableVar<bool> dimAround = false;
|
||||
CWindowOverridableVar<bool> forceRGBX = false;
|
||||
CWindowOverridableVar<bool> keepAspectRatio = false;
|
||||
CWindowOverridableVar<int> xray = -1; // -1 means unset, takes precedence over the renderdata one
|
||||
CWindowOverridableVar<int> borderSize = -1; // -1 means unset, takes precedence over the renderdata one
|
||||
CWindowOverridableVar<bool> forceTearing = false;
|
||||
CWindowOverridableVar<bool> nearestNeighbor = false;
|
||||
std::string animationStyle = std::string("");
|
||||
CWindowOverridableVar<CCornerRadiiData> cornerRadii = CCornerRadiiData(-1); // -1 means no
|
||||
CWindowOverridableVar<bool> forceNoBlur = false;
|
||||
CWindowOverridableVar<bool> forceOpaque = false;
|
||||
CWindowOverridableVar<bool> forceOpaqueOverridden = false; // if true, a rule will not change the forceOpaque state. This is for the force opaque dispatcher.
|
||||
CWindowOverridableVar<bool> forceAllowsInput = false;
|
||||
CWindowOverridableVar<bool> forceNoAnims = false;
|
||||
CWindowOverridableVar<bool> forceNoBorder = false;
|
||||
CWindowOverridableVar<bool> forceNoShadow = false;
|
||||
CWindowOverridableVar<bool> forceNoDim = false;
|
||||
CWindowOverridableVar<bool> windowDanceCompat = false;
|
||||
CWindowOverridableVar<bool> noMaxSize = false;
|
||||
CWindowOverridableVar<bool> dimAround = false;
|
||||
CWindowOverridableVar<bool> forceRGBX = false;
|
||||
CWindowOverridableVar<bool> keepAspectRatio = false;
|
||||
CWindowOverridableVar<int> xray = -1; // -1 means unset, takes precedence over the renderdata one
|
||||
CWindowOverridableVar<int> borderSize = -1; // -1 means unset, takes precedence over the renderdata one
|
||||
CWindowOverridableVar<bool> forceTearing = false;
|
||||
CWindowOverridableVar<bool> nearestNeighbor = false;
|
||||
};
|
||||
|
||||
struct SWindowRule {
|
||||
|
@ -368,7 +368,7 @@ class CWindow {
|
|||
SWindowDecorationExtents getFullWindowReservedArea();
|
||||
Vector2D middle();
|
||||
bool opaque();
|
||||
float rounding();
|
||||
CCornerRadiiData getCornerRadii();
|
||||
bool canBeTorn();
|
||||
bool shouldSendFullscreenState();
|
||||
void setSuspended(bool suspend);
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
enum eConfigValueDataTypes {
|
||||
CVD_TYPE_INVALID = -1,
|
||||
CVD_TYPE_GRADIENT = 0
|
||||
CVD_TYPE_GRADIENT = 0,
|
||||
CVD_TYPE_CORNER_RADII = 1
|
||||
};
|
||||
|
||||
class ICustomConfigValueData {
|
||||
|
@ -49,3 +50,74 @@ class CGradientValueData : public ICustomConfigValueData {
|
|||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// This class is probably going to be refactored once hyprlang is used
|
||||
class CCornerRadiiData : public ICustomConfigValueData {
|
||||
public:
|
||||
CCornerRadiiData()
|
||||
: CCornerRadiiData(0) {
|
||||
}
|
||||
|
||||
CCornerRadiiData(int radius)
|
||||
: CCornerRadiiData(radius, radius, radius, radius) {
|
||||
}
|
||||
|
||||
CCornerRadiiData(int topL, int topR, int bottomR, int bottomL)
|
||||
: topLeft(topL), topRight(topR), bottomRight(bottomR), bottomLeft(bottomL) {
|
||||
}
|
||||
|
||||
virtual ~CCornerRadiiData(){}
|
||||
|
||||
virtual eConfigValueDataTypes getDataType() {
|
||||
return CVD_TYPE_CORNER_RADII;
|
||||
}
|
||||
|
||||
void reset(int radius) {
|
||||
topLeft = topRight = bottomRight = bottomLeft = radius;
|
||||
}
|
||||
|
||||
CCornerRadiiData operator+(int a) const {
|
||||
return CCornerRadiiData(topLeft + a, topRight + a, bottomRight + a, bottomLeft + a);
|
||||
}
|
||||
|
||||
CCornerRadiiData operator-(int a) const {
|
||||
return CCornerRadiiData(topLeft - a, topRight - a, bottomRight - a, bottomLeft - a);
|
||||
}
|
||||
|
||||
CCornerRadiiData operator*(int a) const {
|
||||
return CCornerRadiiData(topLeft * a, topRight * a, bottomRight * a, bottomLeft * a);
|
||||
}
|
||||
|
||||
CCornerRadiiData operator/(int a) const {
|
||||
return CCornerRadiiData(topLeft / a, topRight / a, bottomRight / a, bottomLeft / a);
|
||||
}
|
||||
|
||||
bool operator==(int a) const {
|
||||
return topLeft == a && topRight == a && bottomRight == a && bottomLeft == a;
|
||||
}
|
||||
|
||||
bool operator!=(int a) const {
|
||||
return topLeft != a && topRight != a && bottomRight != a && bottomLeft != a;
|
||||
}
|
||||
|
||||
CCornerRadiiData& operator+=(int a) {
|
||||
topLeft += a;
|
||||
topRight += a;
|
||||
bottomRight += a;
|
||||
bottomLeft += a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CCornerRadiiData& operator-=(int a) {
|
||||
topLeft -= a;
|
||||
topRight -= a;
|
||||
bottomRight -= a;
|
||||
bottomLeft -= a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int topLeft;
|
||||
int topRight;
|
||||
int bottomRight;
|
||||
int bottomLeft;
|
||||
};
|
||||
|
|
|
@ -33,6 +33,8 @@ CConfigManager::CConfigManager() {
|
|||
configValues["group:groupbar:col.locked_active"].data = std::make_shared<CGradientValueData>(0x66ff5500);
|
||||
configValues["group:groupbar:col.locked_inactive"].data = std::make_shared<CGradientValueData>(0x66775500);
|
||||
|
||||
configValues["decoration:rounding"].data = std::make_shared<CCornerRadiiData>(0);
|
||||
|
||||
Debug::log(LOG, "NOTE: further logs to stdout / logfile are disabled by default. Use debug:disable_logs and debug:enable_stdout_logs to override this.");
|
||||
|
||||
setDefaultVars();
|
||||
|
@ -161,7 +163,7 @@ void CConfigManager::setDefaultVars() {
|
|||
configValues["debug:watchdog_timeout"].intValue = 5;
|
||||
configValues["debug:disable_scale_checks"].intValue = 0;
|
||||
|
||||
configValues["decoration:rounding"].intValue = 0;
|
||||
((CCornerRadiiData*)configValues["decoration:rounding"].data.get())->reset(0xffffffff);
|
||||
configValues["decoration:blur:enabled"].intValue = 1;
|
||||
configValues["decoration:blur:size"].intValue = 8;
|
||||
configValues["decoration:blur:passes"].intValue = 1;
|
||||
|
@ -543,6 +545,18 @@ void CConfigManager::configSetValueSafe(const std::string& COMMAND, const std::s
|
|||
|
||||
break;
|
||||
}
|
||||
case CVD_TYPE_CORNER_RADII: {
|
||||
CCornerRadiiData* data = static_cast<CCornerRadiiData*>(CONFIGENTRY->data.get());
|
||||
|
||||
try {
|
||||
*data = configStringToRadii(VALUE);
|
||||
} catch (std::exception& e) {
|
||||
Debug::log(WARN, "Error reading value of {}", COMMAND);
|
||||
parseError = "Error setting value <" + VALUE + "> for field <" + COMMAND + ">. " + e.what();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
|
|
@ -1106,7 +1106,7 @@ std::string dispatchSetProp(std::string request) {
|
|||
if (PROP == "animationstyle") {
|
||||
PWINDOW->m_sAdditionalConfigData.animationStyle = VAL;
|
||||
} else if (PROP == "rounding") {
|
||||
PWINDOW->m_sAdditionalConfigData.rounding.forceSetIgnoreLocked(configStringToInt(VAL), lock);
|
||||
PWINDOW->m_sAdditionalConfigData.cornerRadii.forceSetIgnoreLocked(configStringToRadii(VAL), lock);
|
||||
} else if (PROP == "forcenoblur") {
|
||||
PWINDOW->m_sAdditionalConfigData.forceNoBlur.forceSetIgnoreLocked(configStringToInt(VAL), lock);
|
||||
} else if (PROP == "forceopaque") {
|
||||
|
|
|
@ -715,6 +715,24 @@ int64_t configStringToInt(const std::string& VALUE) {
|
|||
return std::stoll(VALUE);
|
||||
}
|
||||
|
||||
CCornerRadiiData configStringToRadii(const std::string& VALUE) {
|
||||
CVarList vars(VALUE);
|
||||
|
||||
CCornerRadiiData radii;
|
||||
if (vars.size() == 1) {
|
||||
radii.reset(std::stoi(vars[0]));
|
||||
} else if (vars.size() == 4) {
|
||||
radii.topLeft = std::stoi(vars[0]);
|
||||
radii.topRight = std::stoi(vars[1]);
|
||||
radii.bottomRight = std::stoi(vars[2]);
|
||||
radii.bottomLeft = std::stoi(vars[3]);
|
||||
} else {
|
||||
throw std::invalid_argument("not enough or too many values (1 or 4 separated by comma)");
|
||||
}
|
||||
|
||||
return radii;
|
||||
}
|
||||
|
||||
double normalizeAngleRad(double ang) {
|
||||
if (ang > M_PI * 2) {
|
||||
while (ang > M_PI * 2)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <wayland-server.h>
|
||||
#include <wlr/util/box.h>
|
||||
#include "Vector2D.hpp"
|
||||
#include "../config/ConfigDataValues.hpp"
|
||||
#include <vector>
|
||||
#include <format>
|
||||
|
||||
|
@ -27,6 +28,7 @@ void logSystemInfo();
|
|||
std::string execAndGet(const char*);
|
||||
int64_t getPPIDof(int64_t pid);
|
||||
int64_t configStringToInt(const std::string&);
|
||||
CCornerRadiiData configStringToRadii(const std::string&);
|
||||
std::optional<float> getPlusMinusKeywordResult(std::string in, float relative);
|
||||
void matrixProjection(float mat[9], int w, int h, wl_output_transform tr);
|
||||
double normalizeAngleRad(double ang);
|
||||
|
|
|
@ -86,7 +86,7 @@ struct SRenderData {
|
|||
bool decorate = false;
|
||||
|
||||
// for custom round values
|
||||
int rounding = -1; // -1 means not set
|
||||
CCornerRadiiData cornerRadii = -1; // -1 means not set
|
||||
|
||||
// for blurring
|
||||
bool blur = false;
|
||||
|
|
|
@ -313,14 +313,14 @@ void CHyprOpenGLImpl::end() {
|
|||
}
|
||||
|
||||
void CHyprOpenGLImpl::initShaders() {
|
||||
GLuint prog = createProgram(QUADVERTSRC, QUADFRAGSRC);
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.program = prog;
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.proj = glGetUniformLocation(prog, "proj");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.color = glGetUniformLocation(prog, "color");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.radius = glGetUniformLocation(prog, "radius");
|
||||
GLuint prog = createProgram(QUADVERTSRC, QUADFRAGSRC);
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.program = prog;
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.proj = glGetUniformLocation(prog, "proj");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.color = glGetUniformLocation(prog, "color");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shQUAD.cornerRadii = glGetUniformLocation(prog, "cornerRadii");
|
||||
|
||||
prog = createProgram(TEXVERTSRC, TEXFRAGSRCRGBA);
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.program = prog;
|
||||
|
@ -336,7 +336,7 @@ void CHyprOpenGLImpl::initShaders() {
|
|||
m_RenderData.pCurrentMonData->m_shRGBA.discardAlphaValue = glGetUniformLocation(prog, "discardAlphaValue");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.cornerRadii = glGetUniformLocation(prog, "cornerRadii");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.applyTint = glGetUniformLocation(prog, "applyTint");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.tint = glGetUniformLocation(prog, "tint");
|
||||
m_RenderData.pCurrentMonData->m_shRGBA.useAlphaMatte = glGetUniformLocation(prog, "useAlphaMatte");
|
||||
|
@ -378,7 +378,7 @@ void CHyprOpenGLImpl::initShaders() {
|
|||
m_RenderData.pCurrentMonData->m_shRGBX.discardAlphaValue = glGetUniformLocation(prog, "discardAlphaValue");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.cornerRadii = glGetUniformLocation(prog, "cornerRadii");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.applyTint = glGetUniformLocation(prog, "applyTint");
|
||||
m_RenderData.pCurrentMonData->m_shRGBX.tint = glGetUniformLocation(prog, "tint");
|
||||
|
||||
|
@ -394,7 +394,7 @@ void CHyprOpenGLImpl::initShaders() {
|
|||
m_RenderData.pCurrentMonData->m_shEXT.discardAlphaValue = glGetUniformLocation(prog, "discardAlphaValue");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.cornerRadii = glGetUniformLocation(prog, "cornerRadii");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.applyTint = glGetUniformLocation(prog, "applyTint");
|
||||
m_RenderData.pCurrentMonData->m_shEXT.tint = glGetUniformLocation(prog, "tint");
|
||||
|
||||
|
@ -405,21 +405,21 @@ void CHyprOpenGLImpl::initShaders() {
|
|||
m_RenderData.pCurrentMonData->m_shBLUR1.proj = glGetUniformLocation(prog, "proj");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR1.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR1.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR1.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR1.cornerRadii = glGetUniformLocation(prog, "cornerRadii");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR1.halfpixel = glGetUniformLocation(prog, "halfpixel");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR1.passes = glGetUniformLocation(prog, "passes");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR1.vibrancy = glGetUniformLocation(prog, "vibrancy");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR1.vibrancy_darkness = glGetUniformLocation(prog, "vibrancy_darkness");
|
||||
|
||||
prog = createProgram(TEXVERTSRC, FRAGBLUR2);
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.program = prog;
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.tex = glGetUniformLocation(prog, "tex");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.alpha = glGetUniformLocation(prog, "alpha");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.proj = glGetUniformLocation(prog, "proj");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.halfpixel = glGetUniformLocation(prog, "halfpixel");
|
||||
prog = createProgram(TEXVERTSRC, FRAGBLUR2);
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.program = prog;
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.tex = glGetUniformLocation(prog, "tex");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.alpha = glGetUniformLocation(prog, "alpha");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.proj = glGetUniformLocation(prog, "proj");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.cornerRadii = glGetUniformLocation(prog, "cornerRadii");
|
||||
m_RenderData.pCurrentMonData->m_shBLUR2.halfpixel = glGetUniformLocation(prog, "halfpixel");
|
||||
|
||||
prog = createProgram(TEXVERTSRC, FRAGBLURPREPARE);
|
||||
m_RenderData.pCurrentMonData->m_shBLURPREPARE.program = prog;
|
||||
|
@ -445,9 +445,11 @@ void CHyprOpenGLImpl::initShaders() {
|
|||
m_RenderData.pCurrentMonData->m_shSHADOW.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
m_RenderData.pCurrentMonData->m_shSHADOW.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||
m_RenderData.pCurrentMonData->m_shSHADOW.topLeft = glGetUniformLocation(prog, "topLeft");
|
||||
m_RenderData.pCurrentMonData->m_shSHADOW.topRight = glGetUniformLocation(prog, "topRight");
|
||||
m_RenderData.pCurrentMonData->m_shSHADOW.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_RenderData.pCurrentMonData->m_shSHADOW.bottomLeft = glGetUniformLocation(prog, "bottomLeft");
|
||||
m_RenderData.pCurrentMonData->m_shSHADOW.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shSHADOW.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shSHADOW.cornerRadii = glGetUniformLocation(prog, "cornerRadii");
|
||||
m_RenderData.pCurrentMonData->m_shSHADOW.range = glGetUniformLocation(prog, "range");
|
||||
m_RenderData.pCurrentMonData->m_shSHADOW.shadowPower = glGetUniformLocation(prog, "shadowPower");
|
||||
m_RenderData.pCurrentMonData->m_shSHADOW.color = glGetUniformLocation(prog, "color");
|
||||
|
@ -462,8 +464,8 @@ void CHyprOpenGLImpl::initShaders() {
|
|||
m_RenderData.pCurrentMonData->m_shBORDER1.bottomRight = glGetUniformLocation(prog, "bottomRight");
|
||||
m_RenderData.pCurrentMonData->m_shBORDER1.fullSize = glGetUniformLocation(prog, "fullSize");
|
||||
m_RenderData.pCurrentMonData->m_shBORDER1.fullSizeUntransformed = glGetUniformLocation(prog, "fullSizeUntransformed");
|
||||
m_RenderData.pCurrentMonData->m_shBORDER1.radius = glGetUniformLocation(prog, "radius");
|
||||
m_RenderData.pCurrentMonData->m_shBORDER1.radiusOuter = glGetUniformLocation(prog, "radiusOuter");
|
||||
m_RenderData.pCurrentMonData->m_shBORDER1.cornerRadii = glGetUniformLocation(prog, "cornerRadii");
|
||||
m_RenderData.pCurrentMonData->m_shBORDER1.cornerRadiiOuter = glGetUniformLocation(prog, "cornerRadiiOuter");
|
||||
m_RenderData.pCurrentMonData->m_shBORDER1.gradient = glGetUniformLocation(prog, "gradient");
|
||||
m_RenderData.pCurrentMonData->m_shBORDER1.gradientLength = glGetUniformLocation(prog, "gradientLength");
|
||||
m_RenderData.pCurrentMonData->m_shBORDER1.angle = glGetUniformLocation(prog, "angle");
|
||||
|
@ -578,12 +580,12 @@ void CHyprOpenGLImpl::scissor(const int x, const int y, const int w, const int h
|
|||
scissor(&box, transform);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderRect(CBox* box, const CColor& col, int round) {
|
||||
void CHyprOpenGLImpl::renderRect(CBox* box, const CColor& col, CCornerRadiiData radii) {
|
||||
if (!m_RenderData.damage.empty())
|
||||
renderRectWithDamage(box, col, &m_RenderData.damage, round);
|
||||
renderRectWithDamage(box, col, &m_RenderData.damage, radii);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CColor& col, int round, float blurA, bool xray) {
|
||||
void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CColor& col, CCornerRadiiData radii, float blurA, bool xray) {
|
||||
if (m_RenderData.damage.empty())
|
||||
return;
|
||||
|
||||
|
@ -605,7 +607,7 @@ void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CColor& col, int round
|
|||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
renderRect(box, CColor(0, 0, 0, 0), round);
|
||||
renderRect(box, CColor(0, 0, 0, 0), radii);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
glStencilFunc(GL_EQUAL, 1, -1);
|
||||
|
@ -627,10 +629,10 @@ void CHyprOpenGLImpl::renderRectWithBlur(CBox* box, const CColor& col, int round
|
|||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
scissor((CBox*)nullptr);
|
||||
|
||||
renderRectWithDamage(box, col, &m_RenderData.damage, round);
|
||||
renderRectWithDamage(box, col, &m_RenderData.damage, radii);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CColor& col, CRegion* damage, int round) {
|
||||
void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CColor& col, CRegion* damage, CCornerRadiiData radii) {
|
||||
RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!");
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!");
|
||||
|
||||
|
@ -670,7 +672,7 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CColor& col, CRegion
|
|||
// Rounded corners
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shQUAD.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shQUAD.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(m_RenderData.pCurrentMonData->m_shQUAD.radius, round);
|
||||
glUniform4f(m_RenderData.pCurrentMonData->m_shQUAD.cornerRadii, radii.topLeft, radii.topRight, radii.bottomRight, radii.bottomLeft);
|
||||
|
||||
glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shQUAD.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
||||
|
@ -696,21 +698,21 @@ void CHyprOpenGLImpl::renderRectWithDamage(CBox* box, const CColor& col, CRegion
|
|||
glDisableVertexAttribArray(m_RenderData.pCurrentMonData->m_shQUAD.posAttrib);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, CBox* pBox, float alpha, int round, bool allowCustomUV) {
|
||||
void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, CBox* pBox, float alpha, CCornerRadiiData radii, bool allowCustomUV) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||
|
||||
renderTexture(CTexture(tex), pBox, alpha, round, false, allowCustomUV);
|
||||
renderTexture(CTexture(tex), pBox, alpha, radii, false, allowCustomUV);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTexture(const CTexture& tex, CBox* pBox, float alpha, int round, bool discardActive, bool allowCustomUV) {
|
||||
void CHyprOpenGLImpl::renderTexture(const CTexture& tex, CBox* pBox, float alpha, CCornerRadiiData radii, bool discardActive, bool allowCustomUV) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||
|
||||
renderTextureInternalWithDamage(tex, pBox, alpha, &m_RenderData.damage, round, discardActive, false, allowCustomUV, true);
|
||||
renderTextureInternalWithDamage(tex, pBox, alpha, &m_RenderData.damage, radii, discardActive, false, allowCustomUV, true);
|
||||
|
||||
scissor((CBox*)nullptr);
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, CBox* pBox, float alpha, CRegion* damage, int round, bool discardActive, bool noAA, bool allowCustomUV,
|
||||
void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, CBox* pBox, float alpha, CRegion* damage, CCornerRadiiData radii, bool discardActive, bool noAA, bool allowCustomUV,
|
||||
bool allowDim) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
|
||||
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
|
||||
|
@ -824,7 +826,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, CBox*
|
|||
// Rounded corners
|
||||
glUniform2f(shader->topLeft, TOPLEFT.x, TOPLEFT.y);
|
||||
glUniform2f(shader->fullSize, FULLSIZE.x, FULLSIZE.y);
|
||||
glUniform1f(shader->radius, round);
|
||||
glUniform4f(shader->cornerRadii, radii.topLeft, radii.topRight, radii.bottomRight, radii.bottomLeft);
|
||||
|
||||
if (allowDim && m_pCurrentWindow && *PDIMINACTIVE) {
|
||||
glUniform1i(shader->applyTint, 1);
|
||||
|
@ -1094,7 +1096,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
|||
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||
glUniformMatrix3fv(pShader->proj, 1, GL_FALSE, glMatrix);
|
||||
#endif
|
||||
glUniform1f(pShader->radius, *PBLURSIZE * a); // this makes the blursize change with a
|
||||
glUniform4f(pShader->cornerRadii, *PBLURSIZE * a, *PBLURSIZE * a, *PBLURSIZE * a, *PBLURSIZE * a); // this makes the blursize change with a
|
||||
if (pShader == &m_RenderData.pCurrentMonData->m_shBLUR1) {
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shBLUR1.halfpixel, 0.5f / (m_RenderData.pMonitor->vecPixelSize.x / 2.f),
|
||||
0.5f / (m_RenderData.pMonitor->vecPixelSize.y / 2.f));
|
||||
|
@ -1361,7 +1363,7 @@ bool CHyprOpenGLImpl::shouldUseNewBlurOptimizations(SLayerSurface* pLayer, CWind
|
|||
return false;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, float a, wlr_surface* pSurface, int round, bool blockBlurOptimization, float blurA) {
|
||||
void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, float a, wlr_surface* pSurface, CCornerRadiiData radii, bool blockBlurOptimization, float blurA) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!");
|
||||
|
||||
static auto* const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur:enabled")->intValue;
|
||||
|
@ -1378,7 +1380,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, flo
|
|||
|
||||
if (*PBLURENABLED == 0 || (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) ||
|
||||
(m_pCurrentWindow && (m_pCurrentWindow->m_sAdditionalConfigData.forceNoBlur || m_pCurrentWindow->m_sAdditionalConfigData.forceRGBX))) {
|
||||
renderTexture(tex, pBox, a, round, false, true);
|
||||
renderTexture(tex, pBox, a, radii, false, true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1391,7 +1393,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, flo
|
|||
inverseOpaque.invert(&surfbox).intersect(0, 0, pSurface->current.width * pSurface->current.scale, pSurface->current.height * pSurface->current.scale);
|
||||
|
||||
if (inverseOpaque.empty()) {
|
||||
renderTexture(tex, pBox, a, round, false, true);
|
||||
renderTexture(tex, pBox, a, radii, false, true);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@ -1426,9 +1428,9 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, flo
|
|||
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
if (USENEWOPTIMIZE && !(m_RenderData.discardMode & DISCARD_ALPHA))
|
||||
renderRect(pBox, CColor(0, 0, 0, 0), round);
|
||||
renderRect(pBox, CColor(0, 0, 0, 0), radii);
|
||||
else
|
||||
renderTexture(tex, pBox, a, round, true, true); // discard opaque
|
||||
renderTexture(tex, pBox, a, radii, true, true); // discard opaque
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
glStencilFunc(GL_EQUAL, 1, -1);
|
||||
|
@ -1451,7 +1453,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, CBox* pBox, flo
|
|||
|
||||
// draw window
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
renderTextureInternalWithDamage(tex, pBox, a, &texDamage, round, false, false, true, true);
|
||||
renderTextureInternalWithDamage(tex, pBox, a, &texDamage, radii, false, false, true, true);
|
||||
|
||||
glStencilMask(-1);
|
||||
glStencilFunc(GL_ALWAYS, 1, 0xFF);
|
||||
|
@ -1465,7 +1467,7 @@ void pushVert2D(float x, float y, float* arr, int& counter, CBox* box) {
|
|||
counter++;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, int round, int borderSize, float a, int outerRound) {
|
||||
void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, CCornerRadiiData radii, int borderSize, float a, CCornerRadiiData outerRadii) {
|
||||
RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!");
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!");
|
||||
|
||||
|
@ -1490,7 +1492,7 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in
|
|||
box->width += 2 * scaledBorderSize;
|
||||
box->height += 2 * scaledBorderSize;
|
||||
|
||||
round += round == 0 ? 0 : scaledBorderSize;
|
||||
radii += radii == 0 ? 0 : scaledBorderSize;
|
||||
|
||||
float matrix[9];
|
||||
wlr_matrix_project_box(matrix, box->pWlr(), wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0,
|
||||
|
@ -1528,8 +1530,10 @@ void CHyprOpenGLImpl::renderBorder(CBox* box, const CGradientValueData& grad, in
|
|||
glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shBORDER1.fullSizeUntransformed, (float)box->width, (float)box->height);
|
||||
glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radius, round);
|
||||
glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.radiusOuter, outerRound == -1 ? round : outerRound);
|
||||
glUniform4f(m_RenderData.pCurrentMonData->m_shBORDER1.cornerRadii, radii.topLeft, radii.topRight, radii.bottomRight, radii.bottomLeft);
|
||||
|
||||
CCornerRadiiData actualOuterRadii = outerRadii == -1 ? radii : outerRadii;
|
||||
glUniform4f(m_RenderData.pCurrentMonData->m_shBORDER1.cornerRadiiOuter, actualOuterRadii.topLeft, actualOuterRadii.topRight, actualOuterRadii.bottomRight, actualOuterRadii.bottomLeft);
|
||||
glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.thick, scaledBorderSize);
|
||||
|
||||
glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shBORDER1.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||
|
@ -1768,7 +1772,7 @@ void CHyprOpenGLImpl::renderSnapshot(SLayerSurface** pLayer) {
|
|||
m_bEndFrame = false;
|
||||
}
|
||||
|
||||
void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, const CColor& color, float a) {
|
||||
void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, CCornerRadiiData radii, int range, const CColor& color, float a) {
|
||||
RASSERT(m_RenderData.pMonitor, "Tried to render shadow without begin()!");
|
||||
RASSERT((box->width > 0 && box->height > 0), "Tried to render shadow with width/height < 0!");
|
||||
RASSERT(m_pCurrentWindow, "Tried to render shadow without a window!");
|
||||
|
@ -1808,15 +1812,19 @@ void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, const
|
|||
#endif
|
||||
glUniform4f(m_RenderData.pCurrentMonData->m_shSHADOW.color, col.r, col.g, col.b, col.a * a);
|
||||
|
||||
const auto TOPLEFT = Vector2D(range + round, range + round);
|
||||
const auto BOTTOMRIGHT = Vector2D(box->width - (range + round), box->height - (range + round));
|
||||
const auto TOPLEFT = Vector2D(range + radii.topLeft, range + radii.topLeft);
|
||||
const auto TOPRIGHT = Vector2D(box->width - range - radii.topRight, range + radii.topRight);
|
||||
const auto BOTTOMRIGHT = Vector2D(box->width - (range + radii.bottomRight), box->height - (range + radii.bottomRight));
|
||||
const auto BOTTOMLEFT = Vector2D(range + radii.bottomLeft, box->height - (range + radii.bottomLeft));
|
||||
const auto FULLSIZE = Vector2D(box->width, box->height);
|
||||
|
||||
// Rounded corners
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shSHADOW.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shSHADOW.topRight, (float)TOPRIGHT.x, (float)TOPRIGHT.y);
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shSHADOW.bottomRight, (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shSHADOW.bottomLeft, (float)BOTTOMLEFT.x, (float)BOTTOMLEFT.y);
|
||||
glUniform2f(m_RenderData.pCurrentMonData->m_shSHADOW.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||
glUniform1f(m_RenderData.pCurrentMonData->m_shSHADOW.radius, range + round);
|
||||
glUniform4f(m_RenderData.pCurrentMonData->m_shSHADOW.cornerRadii, range + radii.topLeft, range + radii.topRight, range + radii.bottomRight, range + radii.bottomLeft);
|
||||
glUniform1f(m_RenderData.pCurrentMonData->m_shSHADOW.range, range);
|
||||
glUniform1f(m_RenderData.pCurrentMonData->m_shSHADOW.shadowPower, SHADOWPOWER);
|
||||
|
||||
|
|
|
@ -118,14 +118,14 @@ class CHyprOpenGLImpl {
|
|||
void begin(CMonitor*, CRegion*, CFramebuffer* fb = nullptr /* if provided, it's not a real frame */);
|
||||
void end();
|
||||
|
||||
void renderRect(CBox*, const CColor&, int round = 0);
|
||||
void renderRectWithBlur(CBox*, const CColor&, int round = 0, float blurA = 1.f, bool xray = false);
|
||||
void renderRectWithDamage(CBox*, const CColor&, CRegion* damage, int round = 0);
|
||||
void renderTexture(wlr_texture*, CBox*, float a, int round = 0, bool allowCustomUV = false);
|
||||
void renderTexture(const CTexture&, CBox*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false);
|
||||
void renderTextureWithBlur(const CTexture&, CBox*, float a, wlr_surface* pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f);
|
||||
void renderRoundedShadow(CBox*, int round, int range, const CColor& color, float a = 1.0);
|
||||
void renderBorder(CBox*, const CGradientValueData&, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */);
|
||||
void renderRect(CBox*, const CColor&, CCornerRadiiData radii = 0);
|
||||
void renderRectWithBlur(CBox*, const CColor&, CCornerRadiiData radii = 0, float blurA = 1.f, bool xray = false);
|
||||
void renderRectWithDamage(CBox*, const CColor&, CRegion* damage, CCornerRadiiData radii = 0);
|
||||
void renderTexture(wlr_texture*, CBox*, float a, CCornerRadiiData radii = 0, bool allowCustomUV = false);
|
||||
void renderTexture(const CTexture&, CBox*, float a, CCornerRadiiData radii = 0, bool discardActive = false, bool allowCustomUV = false);
|
||||
void renderTextureWithBlur(const CTexture&, CBox*, float a, wlr_surface* pSurface, CCornerRadiiData radii = 0, bool blockBlurOptimization = false, float blurA = 1.f);
|
||||
void renderRoundedShadow(CBox*, CCornerRadiiData radii, int range, const CColor& color, float a = 1.0);
|
||||
void renderBorder(CBox*, const CGradientValueData&, CCornerRadiiData radii, int borderSize, float a = 1.0, CCornerRadiiData outerRadii = -1 /* use round */);
|
||||
void renderTextureMatte(const CTexture& tex, CBox* pBox, CFramebuffer& matte);
|
||||
|
||||
void setMonitorTransformEnabled(bool enabled);
|
||||
|
@ -216,7 +216,7 @@ class CHyprOpenGLImpl {
|
|||
// returns the out FB, can be either Mirror or MirrorSwap
|
||||
CFramebuffer* blurMainFramebufferWithDamage(float a, CRegion* damage);
|
||||
|
||||
void renderTextureInternalWithDamage(const CTexture&, CBox* pBox, float a, CRegion* damage, int round = 0, bool discardOpaque = false, bool noAA = false,
|
||||
void renderTextureInternalWithDamage(const CTexture&, CBox* pBox, float a, CRegion* damage, CCornerRadiiData radii = 0, bool discardOpaque = false, bool noAA = false,
|
||||
bool allowCustomUV = false, bool allowDim = false);
|
||||
void renderTexturePrimitive(const CTexture& tex, CBox* pBox);
|
||||
void renderSplash(cairo_t* const, cairo_surface_t* const, double);
|
||||
|
|
|
@ -122,15 +122,15 @@ static void renderSurface(struct wlr_surface* surface, int x, int y, void* data)
|
|||
(!RDATA->pWindow || (!RDATA->pWindow->m_vRealSize.isBeingAnimated() && !INTERACTIVERESIZEINPROGRESS)) /* not window or not animated/resizing */)
|
||||
g_pHyprOpenGL->m_RenderData.useNearestNeighbor = true;
|
||||
|
||||
float rounding = RDATA->rounding;
|
||||
CCornerRadiiData radii = RDATA->cornerRadii;
|
||||
|
||||
rounding -= 1; // to fix a border issue
|
||||
radii -= 1; // to fix a border issue
|
||||
|
||||
if (RDATA->dontRound)
|
||||
rounding = 0;
|
||||
radii = 0;
|
||||
|
||||
const bool WINDOWOPAQUE = RDATA->pWindow && RDATA->pWindow->m_pWLSurface.wlr() == surface ? RDATA->pWindow->opaque() : false;
|
||||
const bool CANDISABLEBLEND = RDATA->alpha * RDATA->fadeAlpha >= 1.f && rounding == 0 && (WINDOWOPAQUE || surface->opaque);
|
||||
const bool CANDISABLEBLEND = RDATA->alpha * RDATA->fadeAlpha >= 1.f && radii == 0 && (WINDOWOPAQUE || surface->opaque);
|
||||
|
||||
if (CANDISABLEBLEND)
|
||||
g_pHyprOpenGL->blend(false);
|
||||
|
@ -139,12 +139,12 @@ static void renderSurface(struct wlr_surface* surface, int x, int y, void* data)
|
|||
|
||||
if (RDATA->surface && surface == RDATA->surface) {
|
||||
if (wlr_xwayland_surface_try_from_wlr_surface(surface) && !wlr_xwayland_surface_try_from_wlr_surface(surface)->has_alpha && RDATA->fadeAlpha * RDATA->alpha == 1.f) {
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, true);
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, radii, true);
|
||||
} else {
|
||||
if (RDATA->blur)
|
||||
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding, RDATA->blockBlurOptimization, RDATA->fadeAlpha);
|
||||
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, radii, RDATA->blockBlurOptimization, RDATA->fadeAlpha);
|
||||
else
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, true);
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, radii, true);
|
||||
}
|
||||
} else {
|
||||
if (RDATA->blur && RDATA->popup && *PBLURPOPUPS) {
|
||||
|
@ -154,10 +154,10 @@ static void renderSurface(struct wlr_surface* surface, int x, int y, void* data)
|
|||
g_pHyprOpenGL->m_RenderData.discardOpacity = *PBLURPOPUPSIGNOREALPHA;
|
||||
}
|
||||
|
||||
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding, true);
|
||||
g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, radii, true);
|
||||
g_pHyprOpenGL->m_RenderData.discardMode &= ~DISCARD_ALPHA;
|
||||
} else
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, true);
|
||||
g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, radii, true);
|
||||
}
|
||||
|
||||
if (!g_pHyprRenderer->m_bBlockSurfaceFeedback) {
|
||||
|
@ -424,14 +424,14 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
|||
if (ignoreAllGeometry)
|
||||
decorate = false;
|
||||
|
||||
renderdata.surface = pWindow->m_pWLSurface.wlr();
|
||||
renderdata.dontRound = (pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) || (!pWindow->m_sSpecialRenderData.rounding);
|
||||
renderdata.fadeAlpha = pWindow->m_fAlpha.fl() * (pWindow->m_bPinned ? 1.f : PWORKSPACE->m_fAlpha.fl());
|
||||
renderdata.alpha = pWindow->m_fActiveInactiveAlpha.fl();
|
||||
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL);
|
||||
renderdata.rounding = ignoreAllGeometry || renderdata.dontRound ? 0 : pWindow->rounding() * pMonitor->scale;
|
||||
renderdata.blur = !ignoreAllGeometry; // if it shouldn't, it will be ignored later
|
||||
renderdata.pWindow = pWindow;
|
||||
renderdata.surface = pWindow->m_pWLSurface.wlr();
|
||||
renderdata.dontRound = (pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL) || (!pWindow->m_sSpecialRenderData.rounding);
|
||||
renderdata.fadeAlpha = pWindow->m_fAlpha.fl() * (pWindow->m_bPinned ? 1.f : PWORKSPACE->m_fAlpha.fl());
|
||||
renderdata.alpha = pWindow->m_fActiveInactiveAlpha.fl();
|
||||
renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL);
|
||||
renderdata.cornerRadii = ignoreAllGeometry || renderdata.dontRound ? 0 : pWindow->getCornerRadii() * pMonitor->scale;
|
||||
renderdata.blur = !ignoreAllGeometry; // if it shouldn't, it will be ignored later
|
||||
renderdata.pWindow = pWindow;
|
||||
|
||||
if (ignoreAllGeometry) {
|
||||
renderdata.alpha = 1.f;
|
||||
|
@ -524,7 +524,7 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
|
|||
if (pWindow->m_pWLSurface.small() && !pWindow->m_pWLSurface.m_bFillIgnoreSmall && renderdata.blur && *PBLUR) {
|
||||
CBox wb = {renderdata.x - pMonitor->vecPosition.x, renderdata.y - pMonitor->vecPosition.y, renderdata.w, renderdata.h};
|
||||
wb.scale(pMonitor->scale).round();
|
||||
g_pHyprOpenGL->renderRectWithBlur(&wb, CColor(0, 0, 0, 0), renderdata.dontRound ? 0 : renderdata.rounding - 1, renderdata.fadeAlpha,
|
||||
g_pHyprOpenGL->renderRectWithBlur(&wb, CColor(0, 0, 0, 0), renderdata.dontRound ? 0 : renderdata.cornerRadii - 1, renderdata.fadeAlpha,
|
||||
g_pHyprOpenGL->shouldUseNewBlurOptimizations(nullptr, pWindow));
|
||||
renderdata.blur = false;
|
||||
}
|
||||
|
@ -2250,9 +2250,10 @@ void CHyprRenderer::setOccludedForMainWorkspace(CRegion& region, CWorkspace* pWo
|
|||
if (!w->opaque())
|
||||
continue;
|
||||
|
||||
const auto ROUNDING = w->rounding() * PMONITOR->scale;
|
||||
const Vector2D POS = w->m_vRealPosition.vec() + Vector2D{ROUNDING, ROUNDING} - PMONITOR->vecPosition + (w->m_bPinned ? Vector2D{} : pWorkspace->m_vRenderOffset.vec());
|
||||
const Vector2D SIZE = w->m_vRealSize.vec() - Vector2D{ROUNDING * 2, ROUNDING * 2};
|
||||
const auto RADII = w->getCornerRadii() * PMONITOR->scale;
|
||||
const int MINRADIUS = std::min(std::min(RADII.topLeft, RADII.topRight), std::min(RADII.bottomLeft, RADII.bottomRight));
|
||||
const Vector2D POS = w->m_vRealPosition.vec() + Vector2D{MINRADIUS, MINRADIUS} - PMONITOR->vecPosition + (w->m_bPinned ? Vector2D{} : pWorkspace->m_vRenderOffset.vec());
|
||||
const Vector2D SIZE = w->m_vRealSize.vec() - Vector2D{MINRADIUS * 2, MINRADIUS * 2};
|
||||
|
||||
CBox box = {POS.x, POS.y, SIZE.x, SIZE.y};
|
||||
|
||||
|
@ -2276,9 +2277,10 @@ void CHyprRenderer::setOccludedForBackLayers(CRegion& region, CWorkspace* pWorks
|
|||
if (!w->opaque())
|
||||
continue;
|
||||
|
||||
const auto ROUNDING = w->rounding() * PMONITOR->scale;
|
||||
const Vector2D POS = w->m_vRealPosition.vec() + Vector2D{ROUNDING, ROUNDING} - PMONITOR->vecPosition + (w->m_bPinned ? Vector2D{} : pWorkspace->m_vRenderOffset.vec());
|
||||
const Vector2D SIZE = w->m_vRealSize.vec() - Vector2D{ROUNDING * 2, ROUNDING * 2};
|
||||
const auto RADII = w->getCornerRadii() * PMONITOR->scale;
|
||||
const int MINRADIUS = std::min(std::min(RADII.topLeft, RADII.topRight), std::min(RADII.bottomLeft, RADII.bottomRight));
|
||||
const Vector2D POS = w->m_vRealPosition.vec() + Vector2D{MINRADIUS, MINRADIUS} - PMONITOR->vecPosition + (w->m_bPinned ? Vector2D{} : pWorkspace->m_vRenderOffset.vec());
|
||||
const Vector2D SIZE = w->m_vRealSize.vec() - Vector2D{MINRADIUS * 2, MINRADIUS * 2};
|
||||
|
||||
CBox box = {POS.x, POS.y, SIZE.x, SIZE.y};
|
||||
|
||||
|
|
|
@ -21,11 +21,13 @@ class CShader {
|
|||
GLfloat discardAlphaValue = -1;
|
||||
|
||||
GLint topLeft = -1;
|
||||
GLint topRight = -1;
|
||||
GLint bottomRight = -1;
|
||||
GLint bottomLeft = -1;
|
||||
GLint fullSize = -1;
|
||||
GLint fullSizeUntransformed = -1;
|
||||
GLint radius = -1;
|
||||
GLint radiusOuter = -1;
|
||||
GLint cornerRadii = -1;
|
||||
GLint cornerRadiiOuter = -1;
|
||||
|
||||
GLint thick = -1;
|
||||
|
||||
|
|
|
@ -66,13 +66,13 @@ void CHyprBorderDecoration::draw(CMonitor* pMonitor, float a, const Vector2D& of
|
|||
}
|
||||
|
||||
int borderSize = m_pWindow->getRealBorderSize();
|
||||
const auto ROUNDING = m_pWindow->rounding() * pMonitor->scale;
|
||||
const auto RADII = m_pWindow->getCornerRadii() * pMonitor->scale;
|
||||
|
||||
g_pHyprOpenGL->renderBorder(&windowBox, grad, ROUNDING, borderSize, a1);
|
||||
g_pHyprOpenGL->renderBorder(&windowBox, grad, RADII, borderSize, a1);
|
||||
|
||||
if (ANIMATED) {
|
||||
float a2 = a * (1.f - m_pWindow->m_fBorderFadeAnimationProgress.fl());
|
||||
g_pHyprOpenGL->renderBorder(&windowBox, m_pWindow->m_cRealBorderColorPrevious, ROUNDING, borderSize, a2);
|
||||
g_pHyprOpenGL->renderBorder(&windowBox, m_pWindow->m_cRealBorderColorPrevious, RADII, borderSize, a2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -79,8 +79,8 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D
|
|||
if (*PSHADOWS != 1)
|
||||
return; // disabled
|
||||
|
||||
const auto ROUNDINGBASE = m_pWindow->rounding();
|
||||
const auto ROUNDING = ROUNDINGBASE > 0 ? ROUNDINGBASE + m_pWindow->getRealBorderSize() : 0;
|
||||
const auto RADIIBASE = m_pWindow->getCornerRadii();
|
||||
const auto RADII = RADIIBASE.topLeft > 0|| RADIIBASE.topRight > 0 || RADIIBASE.bottomRight > 0 || RADIIBASE.bottomLeft > 0 ? RADIIBASE + m_pWindow->getRealBorderSize() : 0;
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(m_pWindow->m_iWorkspaceID);
|
||||
const auto WORKSPACEOFFSET = PWORKSPACE && !m_pWindow->m_bPinned ? PWORKSPACE->m_vRenderOffset.vec() : Vector2D();
|
||||
|
||||
|
@ -137,7 +137,15 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D
|
|||
CRegion saveDamage = g_pHyprOpenGL->m_RenderData.damage;
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.damage = fullBox;
|
||||
g_pHyprOpenGL->m_RenderData.damage.subtract(windowBox.copy().expand(-ROUNDING * pMonitor->scale)).intersect(saveDamage);
|
||||
|
||||
// TODO: check if CBox has the right params
|
||||
CBox substract = windowBox.copy();
|
||||
substract.x -= -std::min(RADII.topLeft, RADII.bottomLeft) * pMonitor->scale;
|
||||
substract.y -= -std::min(RADII.topRight, RADII.bottomRight) * pMonitor->scale;
|
||||
substract.w += -(std::min(RADII.topLeft, RADII.bottomLeft) + std::min(RADII.topRight, RADII.bottomRight)) * pMonitor->scale;
|
||||
substract.h += -(std::min(RADII.topLeft, RADII.topRight) + std::min(RADII.bottomLeft, RADII.bottomRight)) * pMonitor->scale;
|
||||
|
||||
g_pHyprOpenGL->m_RenderData.damage.subtract(substract).intersect(saveDamage);
|
||||
|
||||
alphaFB.bind();
|
||||
|
||||
|
@ -147,10 +155,10 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D
|
|||
g_pHyprOpenGL->renderRect(&fullBox, CColor(0, 0, 0, 1), 0);
|
||||
|
||||
// render white shadow with the alpha of the shadow color (otherwise we clear with alpha later and shit it to 2 bit)
|
||||
g_pHyprOpenGL->renderRoundedShadow(&fullBox, ROUNDING * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, CColor(1, 1, 1, m_pWindow->m_cRealShadowColor.col().a), a);
|
||||
g_pHyprOpenGL->renderRoundedShadow(&fullBox, RADII * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, CColor(1, 1, 1, m_pWindow->m_cRealShadowColor.col().a), a);
|
||||
|
||||
// render black window box ("clip")
|
||||
g_pHyprOpenGL->renderRect(&windowBox, CColor(0, 0, 0, 1.0), ROUNDING * pMonitor->scale);
|
||||
g_pHyprOpenGL->renderRect(&windowBox, CColor(0, 0, 0, 1.0), RADII * pMonitor->scale);
|
||||
|
||||
alphaSwapFB.bind();
|
||||
|
||||
|
@ -166,7 +174,7 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D
|
|||
|
||||
g_pHyprOpenGL->m_RenderData.damage = saveDamage;
|
||||
} else {
|
||||
g_pHyprOpenGL->renderRoundedShadow(&fullBox, ROUNDING * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, m_pWindow->m_cRealShadowColor.col(), a);
|
||||
g_pHyprOpenGL->renderRoundedShadow(&fullBox, RADII * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, m_pWindow->m_cRealShadowColor.col(), a);
|
||||
}
|
||||
|
||||
if (m_seExtents != m_seReportedExtents)
|
||||
|
|
|
@ -11,8 +11,8 @@ varying vec2 v_texcoord;
|
|||
uniform vec2 topLeft;
|
||||
uniform vec2 fullSize;
|
||||
uniform vec2 fullSizeUntransformed;
|
||||
uniform float radius;
|
||||
uniform float radiusOuter;
|
||||
uniform vec4 cornerRadii;
|
||||
uniform vec4 cornerRadiiOuter;
|
||||
uniform float thick;
|
||||
|
||||
uniform vec4 gradient[10];
|
||||
|
@ -62,8 +62,24 @@ void main() {
|
|||
bool done = false;
|
||||
|
||||
pixCoord -= topLeft + fullSize * 0.5;
|
||||
|
||||
bvec2 positive = lessThan(vec2(0.0), pixCoord);
|
||||
|
||||
vec4 pick = vec4(
|
||||
!positive.x && !positive.y,
|
||||
positive.x && !positive.y,
|
||||
positive.x && positive.y,
|
||||
!positive.x && positive.y);
|
||||
|
||||
vec4 result = pick * cornerRadii;
|
||||
vec4 resultOuter = pick * cornerRadiiOuter;
|
||||
|
||||
float radius = result.x + result.y + result.z + result.w;
|
||||
float radiusOuter = resultOuter.x + resultOuter.y + resultOuter.z + resultOuter.w;
|
||||
|
||||
pixCoord *= vec2(lessThan(pixCoord, vec2(0.0))) * -2.0 + 1.0;
|
||||
pixCoordOuter = pixCoord;
|
||||
|
||||
pixCoord -= fullSize * 0.5 - radius;
|
||||
pixCoordOuter -= fullSize * 0.5 - radiusOuter;
|
||||
|
||||
|
|
|
@ -8,14 +8,16 @@ varying vec4 v_color;
|
|||
varying vec2 v_texcoord;
|
||||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 topRight;
|
||||
uniform vec2 bottomRight;
|
||||
uniform vec2 bottomLeft;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
uniform vec4 cornerRadii;
|
||||
uniform float range;
|
||||
uniform float shadowPower;
|
||||
|
||||
float pixAlphaRoundedDistance(float distanceToCorner) {
|
||||
if (distanceToCorner > radius) {
|
||||
float pixAlphaRoundedDistance(float distanceToCorner, float radius) {
|
||||
if (distanceToCorner > radius) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
@ -36,27 +38,18 @@ void main() {
|
|||
vec2 pixCoord = fullSize * v_texcoord;
|
||||
|
||||
// ok, now we check the distance to a border.
|
||||
|
||||
if (pixCoord[0] < topLeft[0]) {
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top left
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(distance(pixCoord, topLeft));
|
||||
done = true;
|
||||
} else if (pixCoord[1] > bottomRight[1]) {
|
||||
// bottom left
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(distance(pixCoord, vec2(topLeft[0], bottomRight[1])));
|
||||
done = true;
|
||||
}
|
||||
} else if (pixCoord[0] > bottomRight[0]) {
|
||||
if (pixCoord[1] < topLeft[1]) {
|
||||
// top right
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(distance(pixCoord, vec2(bottomRight[0], topLeft[1])));
|
||||
done = true;
|
||||
} else if (pixCoord[1] > bottomRight[1]) {
|
||||
// bottom right
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(distance(pixCoord, bottomRight));
|
||||
done = true;
|
||||
}
|
||||
if (pixCoord[0] < topLeft[0] && pixCoord[1] < topLeft[1]) {
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(distance(pixCoord, topLeft), cornerRadii.x);
|
||||
done = true;
|
||||
} else if (pixCoord[0] > topRight[0] && pixCoord[1] < topRight[1]) {
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(distance(pixCoord, topRight), cornerRadii.y);
|
||||
done = true;
|
||||
} else if (pixCoord[0] > bottomRight[0] && pixCoord[1] > bottomRight[1]) {
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(distance(pixCoord, bottomRight), cornerRadii.z);
|
||||
done = true;
|
||||
} else if (pixCoord[0] < bottomLeft[0] && pixCoord[1] > bottomLeft[1]) {
|
||||
pixColor[3] = pixColor[3] * pixAlphaRoundedDistance(distance(pixCoord, bottomLeft), cornerRadii.w);
|
||||
done = true;
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
|
|
|
@ -8,6 +8,19 @@ inline static constexpr auto ROUNDED_SHADER_FUNC = [](const std::string colorVar
|
|||
// branchless baby!
|
||||
highp vec2 pixCoord = vec2(gl_FragCoord);
|
||||
pixCoord -= topLeft + fullSize * 0.5;
|
||||
|
||||
bvec2 positive = lessThan(vec2(0.0), pixCoord);
|
||||
|
||||
vec4 pick = vec4(
|
||||
!positive.x && !positive.y,
|
||||
positive.x && !positive.y,
|
||||
positive.x && positive.y,
|
||||
!positive.x && positive.y);
|
||||
|
||||
vec4 result = pick * cornerRadii;
|
||||
|
||||
float radius = result.x + result.y + result.z + result.w;
|
||||
|
||||
pixCoord *= vec2(lessThan(pixCoord, vec2(0.0))) * -2.0 + 1.0;
|
||||
pixCoord -= fullSize * 0.5 - radius;
|
||||
pixCoord += vec2(1.0, 1.0) / fullSize; // center the pix dont make it top-left
|
||||
|
@ -20,8 +33,6 @@ inline static constexpr auto ROUNDED_SHADER_FUNC = [](const std::string colorVar
|
|||
discard;
|
||||
|
||||
if (dist > radius - 1.0) {
|
||||
float dist = length(pixCoord);
|
||||
|
||||
float normalized = 1.0 - smoothstep(0.0, 1.0, dist - radius + 0.5);
|
||||
|
||||
)#" +
|
||||
|
@ -55,13 +66,13 @@ varying vec4 v_color;
|
|||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
uniform vec4 cornerRadii;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 pixColor = v_color;
|
||||
|
||||
if (radius > 0.0) {
|
||||
if (cornerRadii != vec4(0, 0, 0, 0)) {
|
||||
)#" +
|
||||
ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
}
|
||||
|
@ -88,7 +99,7 @@ uniform float alpha;
|
|||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
uniform vec4 cornerRadii;
|
||||
|
||||
uniform int discardOpaque;
|
||||
uniform int discardAlpha;
|
||||
|
@ -113,7 +124,7 @@ void main() {
|
|||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
if (radius > 0.0) {
|
||||
if (cornerRadii != vec4(0, 0, 0, 0)) {
|
||||
)#" +
|
||||
ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
}
|
||||
|
@ -148,7 +159,7 @@ uniform float alpha;
|
|||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
uniform vec4 cornerRadii;
|
||||
|
||||
uniform int discardOpaque;
|
||||
uniform int discardAlpha;
|
||||
|
@ -170,7 +181,7 @@ void main() {
|
|||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
if (radius > 0.0) {
|
||||
if (cornerRadii != vec4(0, 0, 0, 0)) {
|
||||
)#" +
|
||||
ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
}
|
||||
|
@ -184,7 +195,7 @@ precision mediump float;
|
|||
varying mediump vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float radius;
|
||||
uniform vec4 cornerRadii;
|
||||
uniform vec2 halfpixel;
|
||||
uniform int passes;
|
||||
uniform float vibrancy;
|
||||
|
@ -292,6 +303,7 @@ void main() {
|
|||
vec2 uv = v_texcoord * 2.0;
|
||||
|
||||
vec4 sum = texture2D(tex, uv) * 4.0;
|
||||
float radius = cornerRadii.x;
|
||||
sum += texture2D(tex, uv - halfpixel.xy * radius);
|
||||
sum += texture2D(tex, uv + halfpixel.xy * radius);
|
||||
sum += texture2D(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius);
|
||||
|
@ -328,12 +340,13 @@ precision mediump float;
|
|||
varying mediump vec2 v_texcoord; // is in 0-1
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform float radius;
|
||||
uniform vec4 cornerRadii;
|
||||
uniform vec2 halfpixel;
|
||||
|
||||
void main() {
|
||||
vec2 uv = v_texcoord / 2.0;
|
||||
|
||||
float radius = cornerRadii.x;
|
||||
vec4 sum = texture2D(tex, uv + vec2(-halfpixel.x * 2.0, 0.0) * radius);
|
||||
|
||||
sum += texture2D(tex, uv + vec2(-halfpixel.x, halfpixel.y) * radius) * 2.0;
|
||||
|
@ -419,7 +432,7 @@ uniform float alpha;
|
|||
|
||||
uniform vec2 topLeft;
|
||||
uniform vec2 fullSize;
|
||||
uniform float radius;
|
||||
uniform vec4 cornerRadii;
|
||||
|
||||
uniform int discardOpaque;
|
||||
uniform int discardAlpha;
|
||||
|
@ -441,7 +454,7 @@ void main() {
|
|||
pixColor[2] = pixColor[2] * tint[2];
|
||||
}
|
||||
|
||||
if (radius > 0.0) {
|
||||
if (cornerRadii != vec4(0, 0, 0, 0)) {
|
||||
)#" +
|
||||
ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue