From 6e15590e98ca643d06eacc84adf161bcef705c0b Mon Sep 17 00:00:00 2001 From: Vaxry Date: Thu, 19 Oct 2023 14:04:50 +0100 Subject: [PATCH] shaders: support changing the outer radius of borders independently --- src/render/OpenGL.cpp | 4 +++- src/render/OpenGL.hpp | 2 +- src/render/Shader.hpp | 1 + src/render/shaders/Border.hpp | 22 ++++++++++++++++------ 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 2d8ee92b..29574887 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -349,6 +349,7 @@ void CHyprOpenGLImpl::initShaders() { 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.gradient = glGetUniformLocation(prog, "gradient"); m_RenderData.pCurrentMonData->m_shBORDER1.gradientLength = glGetUniformLocation(prog, "gradientLength"); m_RenderData.pCurrentMonData->m_shBORDER1.angle = glGetUniformLocation(prog, "angle"); @@ -1293,7 +1294,7 @@ void pushVert2D(float x, float y, float* arr, int& counter, wlr_box* box) { counter++; } -void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CGradientValueData& grad, int round, int borderSize, float a) { +void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CGradientValueData& grad, int round, int borderSize, float a, int outerRound) { 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()!"); @@ -1359,6 +1360,7 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CGradientValueData& grad, 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); glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.thick, scaledBorderSize); glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shBORDER1.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index c04e8c65..61e8ffdb 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -109,7 +109,7 @@ class CHyprOpenGLImpl { void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false); void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f); void renderRoundedShadow(wlr_box*, int round, int range, float a = 1.0); - void renderBorder(wlr_box*, const CGradientValueData&, int round, int borderSize, float a = 1.0); + void renderBorder(wlr_box*, const CGradientValueData&, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */); void saveMatrix(); void setMatrixScaleTranslate(const Vector2D& translate, const float& scale); diff --git a/src/render/Shader.hpp b/src/render/Shader.hpp index 5945c157..e972eeb9 100644 --- a/src/render/Shader.hpp +++ b/src/render/Shader.hpp @@ -23,6 +23,7 @@ class CShader { GLint fullSize = -1; GLint fullSizeUntransformed = -1; GLint radius = -1; + GLint radiusOuter = -1; GLint thick = -1; diff --git a/src/render/shaders/Border.hpp b/src/render/shaders/Border.hpp index f7b9d94d..79493da9 100644 --- a/src/render/shaders/Border.hpp +++ b/src/render/shaders/Border.hpp @@ -12,6 +12,7 @@ uniform vec2 topLeft; uniform vec2 fullSize; uniform vec2 fullSizeUntransformed; uniform float radius; +uniform float radiusOuter; uniform float thick; uniform vec4 gradient[10]; @@ -51,6 +52,7 @@ vec4 getColorForCoord(vec2 normalizedCoord) { void main() { highp vec2 pixCoord = vec2(gl_FragCoord); + highp vec2 pixCoordOuter = pixCoord; highp vec2 originalPixCoord = v_texcoord; originalPixCoord *= fullSizeUntransformed; float additionalAlpha = 1.0; @@ -61,25 +63,33 @@ void main() { pixCoord -= topLeft + fullSize * 0.5; pixCoord *= vec2(lessThan(pixCoord, vec2(0.0))) * -2.0 + 1.0; + pixCoordOuter = pixCoord; pixCoord -= fullSize * 0.5 - radius; - pixCoord += vec2(1.0, 1.0) / fullSize; // center the pix dont make it top-left + pixCoordOuter -= fullSize * 0.5 - radiusOuter; + + // center the pixes dont make it top-left + pixCoord += vec2(1.0, 1.0) / fullSize; + pixCoordOuter += vec2(1.0, 1.0) / fullSize; if (min(pixCoord.x, pixCoord.y) > 0.0 && radius > 0.0) { - float dist = length(pixCoord); + float distOuter = length(pixCoordOuter); float h = (thick / 2.0); if (dist < radius - h) { // lower float normalized = smoothstep(0.0, 1.0, dist - radius + thick + 0.5); additionalAlpha *= normalized; - } else { + done = true; + } else if (min(pixCoordOuter.x, pixCoordOuter.y) > 0.0) { // higher - float normalized = 1.0 - smoothstep(0.0, 1.0, dist - radius + 0.5); + float normalized = 1.0 - smoothstep(0.0, 1.0, distOuter - radiusOuter + 0.5); additionalAlpha *= normalized; + done = true; + } else if (distOuter < radiusOuter - h) { + additionalAlpha = 1.0; + done = true; } - - done = true; } // now check for other shit