summaryrefslogtreecommitdiff
path: root/src/render
diff options
context:
space:
mode:
authorvaxerski <43317083+vaxerski@users.noreply.github.com>2022-11-26 17:56:43 +0000
committervaxerski <43317083+vaxerski@users.noreply.github.com>2022-11-26 17:57:02 +0000
commit0948b078e1789605c42746a024df6039bb566b45 (patch)
treee3e1a0dfe0cf748343b290f30ef85824993145c8 /src/render
parent52c03569007f3df1a3fc740450db9b4b81d06ca7 (diff)
added border gradients
Diffstat (limited to 'src/render')
-rw-r--r--src/render/OpenGL.cpp44
-rw-r--r--src/render/OpenGL.hpp4
-rw-r--r--src/render/Renderer.cpp12
-rw-r--r--src/render/Shader.hpp4
-rw-r--r--src/render/shaders/Border.hpp20
5 files changed, 60 insertions, 24 deletions
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp
index 8010f9ca..676a49a9 100644
--- a/src/render/OpenGL.cpp
+++ b/src/render/OpenGL.cpp
@@ -239,7 +239,9 @@ void CHyprOpenGLImpl::initShaders() {
m_RenderData.pCurrentMonData->m_shBORDER1.fullSize = glGetUniformLocation(prog, "fullSize");
m_RenderData.pCurrentMonData->m_shBORDER1.radius = glGetUniformLocation(prog, "radius");
m_RenderData.pCurrentMonData->m_shBORDER1.primitiveMultisample = glGetUniformLocation(prog, "primitiveMultisample");
- m_RenderData.pCurrentMonData->m_shBORDER1.color = glGetUniformLocation(prog, "color");
+ 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");
m_RenderData.pCurrentMonData->m_bShadersInitialized = true;
@@ -804,7 +806,7 @@ void pushVert2D(float x, float y, float* arr, int& counter, wlr_box* box) {
counter++;
}
-void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int round) {
+void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CGradientValueData& grad, int round, float a) {
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()!");
@@ -819,27 +821,13 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int round) {
int scaledBorderSize = *PBORDERSIZE * m_RenderData.pMonitor->scale;
- if (round < 1) {
- // zero rounding, just lines
- wlr_box borderbox = {box->x - scaledBorderSize, box->y - scaledBorderSize, scaledBorderSize, box->height + 2 * scaledBorderSize};
- renderRect(&borderbox, col, 0); // left
- borderbox = {box->x, box->y - (int)scaledBorderSize, box->width + (int)scaledBorderSize, (int)scaledBorderSize};
- renderRect(&borderbox, col, 0); // top
- borderbox = {box->x + box->width, box->y, (int)scaledBorderSize, box->height + (int)scaledBorderSize};
- renderRect(&borderbox, col, 0); // right
- borderbox = {box->x, box->y + box->height, box->width, (int)scaledBorderSize};
- renderRect(&borderbox, col, 0); // bottom
-
- return;
- }
-
// adjust box
box->x -= scaledBorderSize;
box->y -= scaledBorderSize;
box->width += 2 * scaledBorderSize;
box->height += 2 * scaledBorderSize;
- round += scaledBorderSize;
+ round += round == 0 ? 0 : scaledBorderSize;
float matrix[9];
wlr_matrix_project_box(matrix, box, wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0, m_RenderData.pMonitor->output->transform_matrix); // TODO: write own, don't use WLR here
@@ -858,7 +846,19 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int round) {
wlr_matrix_transpose(glMatrix, glMatrix);
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBORDER1.proj, 1, GL_FALSE, glMatrix);
#endif
- glUniform4f(m_RenderData.pCurrentMonData->m_shBORDER1.color, col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f);
+
+ // TODO: make gradients already in 0 ... 1 and just pass vec.data(), alpha in shader
+ float* gradientValues = (float*)malloc(sizeof(float) * grad.m_vColors.size() * 4);
+ for (size_t i = 0; i < grad.m_vColors.size(); ++i) {
+ gradientValues[i * 4] = grad.m_vColors[i].r / 255.f;
+ gradientValues[i * 4 + 1] = grad.m_vColors[i].g / 255.f;
+ gradientValues[i * 4 + 2] = grad.m_vColors[i].b / 255.f;
+ gradientValues[i * 4 + 3] = grad.m_vColors[i].a / 255.f * a;
+ }
+
+ glUniform4fv(m_RenderData.pCurrentMonData->m_shBORDER1.gradient, grad.m_vColors.size(), gradientValues);
+ glUniform1i(m_RenderData.pCurrentMonData->m_shBORDER1.gradientLength, grad.m_vColors.size());
+ glUniform1f(m_RenderData.pCurrentMonData->m_shBORDER1.angle, grad.m_fAngle);
wlr_box transformedBox;
wlr_box_transform(&transformedBox, box, wlr_output_transform_invert(m_RenderData.pMonitor->transform),
@@ -906,6 +906,14 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CColor& col, int round) {
glDisableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBORDER1.texAttrib);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ free(gradientValues);
+
+ // fix back box
+ box->x += scaledBorderSize;
+ box->y += scaledBorderSize;
+ box->width -= 2 * scaledBorderSize;
+ box->height -= 2 * scaledBorderSize;
}
void CHyprOpenGLImpl::makeRawWindowSnapshot(CWindow* pWindow, CFramebuffer* pFramebuffer) {
diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp
index 70e6b258..e54b76aa 100644
--- a/src/render/OpenGL.hpp
+++ b/src/render/OpenGL.hpp
@@ -68,6 +68,8 @@ struct SCurrentRenderData {
wlr_box clipBox = {};
};
+class CGradientValueData;
+
class CHyprOpenGLImpl {
public:
@@ -82,7 +84,7 @@ public:
void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool allowCustomUV = false);
void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0);
void renderRoundedShadow(wlr_box*, int round, int range, float a = 1.0);
- void renderBorder(wlr_box*, const CColor&, int round);
+ void renderBorder(wlr_box*, const CGradientValueData&, int round, float a = 1.0);
void makeWindowSnapshot(CWindow*);
void makeRawWindowSnapshot(CWindow*, CFramebuffer*);
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index eabd03e0..a85ba118 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -300,14 +300,20 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
float rounding = renderdata.dontRound ? 0 : renderdata.rounding == -1 ? *PROUNDING : renderdata.rounding;
rounding *= pMonitor->scale;
- auto col = g_pHyprOpenGL->m_pCurrentWindow->m_cRealBorderColor.col();
- col.a *= renderdata.fadeAlpha * renderdata.alpha / 255.f;
+ auto grad = g_pHyprOpenGL->m_pCurrentWindow->m_cRealBorderColor;
+ const bool ANIMATED = g_pHyprOpenGL->m_pCurrentWindow->m_fBorderAnimationProgress.isBeingAnimated();
+ float a1 = renderdata.fadeAlpha * renderdata.alpha / 255.f * (ANIMATED ? g_pHyprOpenGL->m_pCurrentWindow->m_fBorderAnimationProgress.fl() : 1.f);
wlr_box windowBox = {renderdata.x - pMonitor->vecPosition.x, renderdata.y - pMonitor->vecPosition.y, renderdata.w, renderdata.h};
scaleBox(&windowBox, pMonitor->scale);
- g_pHyprOpenGL->renderBorder(&windowBox, col, rounding);
+ g_pHyprOpenGL->renderBorder(&windowBox, grad, rounding, a1);
+
+ if (ANIMATED) {
+ float a2 = 1.f - a1;
+ g_pHyprOpenGL->renderBorder(&windowBox, g_pHyprOpenGL->m_pCurrentWindow->m_cRealBorderColorPrevious, rounding, a2);
+ }
}
}
diff --git a/src/render/Shader.hpp b/src/render/Shader.hpp
index cf31ed9c..db98b1f2 100644
--- a/src/render/Shader.hpp
+++ b/src/render/Shader.hpp
@@ -32,6 +32,10 @@ public:
GLint applyTint;
GLint tint;
+ GLint gradient;
+ GLint gradientLength;
+ GLint angle;
+
GLint getUniformLocation(const std::string&);
private:
diff --git a/src/render/shaders/Border.hpp b/src/render/shaders/Border.hpp
index 70ed8baa..a2d61066 100644
--- a/src/render/shaders/Border.hpp
+++ b/src/render/shaders/Border.hpp
@@ -14,12 +14,28 @@ uniform float radius;
uniform float thick;
uniform int primitiveMultisample;
+uniform vec4 gradient[10];
+uniform int gradientLength;
+uniform float angle;
+
+vec4 getColorForCoord(vec2 normalizedCoord) {
+ if (gradientLength < 2)
+ return gradient[0];
+
+ float sine = sin(angle);
+ float progress = (normalizedCoord[1] * sine + normalizedCoord[0] * (1.0 - sine)) * float(gradientLength - 1);
+ int bottom = int(floor(progress));
+ int top = bottom + 1;
+
+ return gradient[top] * (progress - float(bottom)) + gradient[bottom] * (float(top) - progress);
+}
+
void main() {
highp vec2 pixCoord = vec2(gl_FragCoord);
vec2 originalPixCoord = fullSize * v_texcoord;
- vec4 pixColor = v_color;
+ vec4 pixColor = getColorForCoord(v_texcoord);
bool done = false;
@@ -27,7 +43,7 @@ void main() {
pixCoord *= vec2(lessThan(pixCoord, vec2(0.0))) * -2.0 + 1.0;
pixCoord -= fullSize * 0.5 - radius;
- if (min(pixCoord.x, pixCoord.y) > 0.0) {
+ if (min(pixCoord.x, pixCoord.y) > 0.0 && radius > 0.0) {
float dist = length(pixCoord);