mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-23 00:49:48 +01:00
added drop shadows
This commit is contained in:
parent
b46f45befa
commit
747ff3369d
11 changed files with 603 additions and 344 deletions
|
@ -1,11 +1,14 @@
|
||||||
#include "Window.hpp"
|
#include "Window.hpp"
|
||||||
#include "Compositor.hpp"
|
#include "Compositor.hpp"
|
||||||
|
#include "render/decorations/CHyprDropShadowDecoration.hpp"
|
||||||
|
|
||||||
CWindow::CWindow() {
|
CWindow::CWindow() {
|
||||||
m_vRealPosition.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:windows_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:windows")->intValue, &g_pConfigManager->getConfigValuePtr("animations:windows_curve")->strValue, (void*) this, AVARDAMAGE_ENTIRE);
|
m_vRealPosition.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:windows_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:windows")->intValue, &g_pConfigManager->getConfigValuePtr("animations:windows_curve")->strValue, (void*) this, AVARDAMAGE_ENTIRE);
|
||||||
m_vRealSize.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:windows_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:windows")->intValue, &g_pConfigManager->getConfigValuePtr("animations:windows_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
|
m_vRealSize.create(AVARTYPE_VECTOR, &g_pConfigManager->getConfigValuePtr("animations:windows_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:windows")->intValue, &g_pConfigManager->getConfigValuePtr("animations:windows_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
|
||||||
m_cRealBorderColor.create(AVARTYPE_COLOR, &g_pConfigManager->getConfigValuePtr("animations:borders_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:borders")->intValue, &g_pConfigManager->getConfigValuePtr("animations:borders_curve")->strValue, (void*)this, AVARDAMAGE_BORDER);
|
m_cRealBorderColor.create(AVARTYPE_COLOR, &g_pConfigManager->getConfigValuePtr("animations:borders_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:borders")->intValue, &g_pConfigManager->getConfigValuePtr("animations:borders_curve")->strValue, (void*)this, AVARDAMAGE_BORDER);
|
||||||
m_fAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:fadein_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:fadein")->intValue, &g_pConfigManager->getConfigValuePtr("animations:fadein_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
|
m_fAlpha.create(AVARTYPE_FLOAT, &g_pConfigManager->getConfigValuePtr("animations:fadein_speed")->floatValue, &g_pConfigManager->getConfigValuePtr("animations:fadein")->intValue, &g_pConfigManager->getConfigValuePtr("animations:fadein_curve")->strValue, (void*)this, AVARDAMAGE_ENTIRE);
|
||||||
|
|
||||||
|
m_dWindowDecorations.emplace_back(std::make_unique<CHyprDropShadowDecoration>(this)); // put the shadow so it's the first deco (has to be rendered first)
|
||||||
}
|
}
|
||||||
|
|
||||||
CWindow::~CWindow() {
|
CWindow::~CWindow() {
|
||||||
|
@ -16,8 +19,9 @@ CWindow::~CWindow() {
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_box CWindow::getFullWindowBoundingBox() {
|
wlr_box CWindow::getFullWindowBoundingBox() {
|
||||||
|
static auto* const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||||
|
|
||||||
SWindowDecorationExtents maxExtents;
|
SWindowDecorationExtents maxExtents = {{*PBORDERSIZE + 1, *PBORDERSIZE + 1}, {*PBORDERSIZE + 1, *PBORDERSIZE + 1}};
|
||||||
|
|
||||||
for (auto& wd : m_dWindowDecorations) {
|
for (auto& wd : m_dWindowDecorations) {
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,11 @@ void CConfigManager::setDefaultVars() {
|
||||||
configValues["decoration:fullscreen_opacity"].floatValue = 1;
|
configValues["decoration:fullscreen_opacity"].floatValue = 1;
|
||||||
configValues["decoration:multisample_edges"].intValue = 0;
|
configValues["decoration:multisample_edges"].intValue = 0;
|
||||||
configValues["decoration:no_blur_on_oversized"].intValue = 1;
|
configValues["decoration:no_blur_on_oversized"].intValue = 1;
|
||||||
|
configValues["decoration:drop_shadow"].intValue = 1;
|
||||||
|
configValues["decoration:shadow_range"].intValue = 4;
|
||||||
|
configValues["decoration:shadow_render_power"].intValue = 3;
|
||||||
|
configValues["decoration:shadow_ignore_window"].intValue = 1;
|
||||||
|
configValues["decoration:col.shadow"].intValue = 0xee1a1a1a;
|
||||||
|
|
||||||
configValues["dwindle:pseudotile"].intValue = 0;
|
configValues["dwindle:pseudotile"].intValue = 0;
|
||||||
configValues["dwindle:col.group_border"].intValue = 0x66777700;
|
configValues["dwindle:col.group_border"].intValue = 0x66777700;
|
||||||
|
|
|
@ -75,6 +75,12 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
||||||
m_shBLUR2.posAttrib = glGetAttribLocation(prog, "pos");
|
m_shBLUR2.posAttrib = glGetAttribLocation(prog, "pos");
|
||||||
m_shBLUR2.texAttrib = glGetAttribLocation(prog, "texcoord");
|
m_shBLUR2.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||||
|
|
||||||
|
prog = createProgram(QUADVERTSRC, FRAGSHADOW);
|
||||||
|
m_shSHADOW.program = prog;
|
||||||
|
m_shSHADOW.proj = glGetUniformLocation(prog, "proj");
|
||||||
|
m_shSHADOW.posAttrib = glGetAttribLocation(prog, "pos");
|
||||||
|
m_shSHADOW.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||||
|
|
||||||
Debug::log(LOG, "Shaders initialized successfully.");
|
Debug::log(LOG, "Shaders initialized successfully.");
|
||||||
|
|
||||||
// End shaders
|
// End shaders
|
||||||
|
@ -858,6 +864,68 @@ void CHyprOpenGLImpl::renderSnapshot(SLayerSurface** pLayer) {
|
||||||
pixman_region32_fini(&fakeDamage);
|
pixman_region32_fini(&fakeDamage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range) {
|
||||||
|
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!");
|
||||||
|
|
||||||
|
static auto *const PSHADOWCOL = &g_pConfigManager->getConfigValuePtr("decoration:col.shadow")->intValue;
|
||||||
|
static auto *const PSHADOWPOWER = &g_pConfigManager->getConfigValuePtr("decoration:shadow_render_power")->intValue;
|
||||||
|
static auto *const PSHADOWIGNOREWINDOW = &g_pConfigManager->getConfigValuePtr("decoration:shadow_ignore_window")->intValue;
|
||||||
|
|
||||||
|
const auto SHADOWPOWER = std::clamp((int)*PSHADOWPOWER, 1, 4);
|
||||||
|
|
||||||
|
const auto col = CColor(*PSHADOWCOL);
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
float glMatrix[9];
|
||||||
|
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
|
||||||
|
wlr_matrix_multiply(glMatrix, matrixFlip180, glMatrix);
|
||||||
|
|
||||||
|
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||||
|
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
glUseProgram(m_shSHADOW.program);
|
||||||
|
|
||||||
|
glUniformMatrix3fv(m_shSHADOW.proj, 1, GL_FALSE, glMatrix);
|
||||||
|
glUniform4f(glGetUniformLocation(m_shSHADOW.program, "color"), col.r / 255.f, col.g / 255.f, col.b / 255.f, col.a / 255.f);
|
||||||
|
|
||||||
|
const auto TOPLEFT = Vector2D(range + round, range + round);
|
||||||
|
const auto BOTTOMRIGHT = Vector2D(box->width - (range + round), box->height - (range + round));
|
||||||
|
const auto FULLSIZE = Vector2D(box->width, box->height);
|
||||||
|
|
||||||
|
// Rounded corners
|
||||||
|
glUniform2f(glGetUniformLocation(m_shSHADOW.program, "topLeft"), (float)TOPLEFT.x, (float)TOPLEFT.y);
|
||||||
|
glUniform2f(glGetUniformLocation(m_shSHADOW.program, "bottomRight"), (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y);
|
||||||
|
glUniform2f(glGetUniformLocation(m_shSHADOW.program, "fullSize"), (float)FULLSIZE.x, (float)FULLSIZE.y);
|
||||||
|
glUniform1f(glGetUniformLocation(m_shSHADOW.program, "radius"), range + round);
|
||||||
|
glUniform1f(glGetUniformLocation(m_shSHADOW.program, "range"), range);
|
||||||
|
glUniform1f(glGetUniformLocation(m_shSHADOW.program, "shadowPower"), SHADOWPOWER);
|
||||||
|
glUniform1i(glGetUniformLocation(m_shSHADOW.program, "ignoreWindow"), *PSHADOWIGNOREWINDOW);
|
||||||
|
|
||||||
|
glVertexAttribPointer(m_shSHADOW.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||||
|
glVertexAttribPointer(m_shSHADOW.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(m_shSHADOW.posAttrib);
|
||||||
|
glEnableVertexAttribArray(m_shSHADOW.texAttrib);
|
||||||
|
|
||||||
|
if (pixman_region32_not_empty(m_RenderData.pDamage)) {
|
||||||
|
PIXMAN_DAMAGE_FOREACH(m_RenderData.pDamage) {
|
||||||
|
const auto RECT = RECTSARR[i];
|
||||||
|
scissor(&RECT);
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glDisableVertexAttribArray(m_shSHADOW.posAttrib);
|
||||||
|
glDisableVertexAttribArray(m_shSHADOW.texAttrib);
|
||||||
|
|
||||||
|
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
}
|
||||||
|
|
||||||
void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
|
||||||
RASSERT(m_RenderData.pMonitor, "Tried to createBGTex without begin()!");
|
RASSERT(m_RenderData.pMonitor, "Tried to createBGTex without begin()!");
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@ public:
|
||||||
void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0);
|
void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0);
|
||||||
void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool border = false, bool allowPrimary = false);
|
void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool border = false, bool allowPrimary = false);
|
||||||
void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0, bool border = false);
|
void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0, bool border = false);
|
||||||
|
void renderRoundedShadow(wlr_box*, int round, int range);
|
||||||
|
|
||||||
void makeWindowSnapshot(CWindow*);
|
void makeWindowSnapshot(CWindow*);
|
||||||
void makeLayerSnapshot(SLayerSurface*);
|
void makeLayerSnapshot(SLayerSurface*);
|
||||||
|
@ -106,6 +107,7 @@ private:
|
||||||
CShader m_shEXT;
|
CShader m_shEXT;
|
||||||
CShader m_shBLUR1;
|
CShader m_shBLUR1;
|
||||||
CShader m_shBLUR2;
|
CShader m_shBLUR2;
|
||||||
|
CShader m_shSHADOW;
|
||||||
//
|
//
|
||||||
|
|
||||||
GLuint createProgram(const std::string&, const std::string&);
|
GLuint createProgram(const std::string&, const std::string&);
|
||||||
|
|
|
@ -569,7 +569,7 @@ void CHyprRenderer::damageWindow(CWindow* pWindow) {
|
||||||
// damage by size & pos
|
// damage by size & pos
|
||||||
// TODO TEMP: revise when added shadows/etc
|
// TODO TEMP: revise when added shadows/etc
|
||||||
|
|
||||||
wlr_box damageBox = {pWindow->m_vRealPosition.vec().x, pWindow->m_vRealPosition.vec().y, pWindow->m_vRealSize.vec().x, pWindow->m_vRealSize.vec().y};
|
wlr_box damageBox = pWindow->getFullWindowBoundingBox();
|
||||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||||
wlr_box fixedDamageBox = damageBox;
|
wlr_box fixedDamageBox = damageBox;
|
||||||
fixedDamageBox.x -= m.vecPosition.x;
|
fixedDamageBox.x -= m.vecPosition.x;
|
||||||
|
@ -584,8 +584,7 @@ void CHyprRenderer::damageWindow(CWindow* pWindow) {
|
||||||
Debug::log(LOG, "Damage: Window floated (%s): xy: %d, %d wh: %d, %d", pWindow->m_szTitle.c_str(), damageBox.x, damageBox.y, damageBox.width, damageBox.height);
|
Debug::log(LOG, "Damage: Window floated (%s): xy: %d, %d wh: %d, %d", pWindow->m_szTitle.c_str(), damageBox.x, damageBox.y, damageBox.width, damageBox.height);
|
||||||
} else {
|
} else {
|
||||||
// damage by real size & pos + border size * 2 (JIC)
|
// damage by real size & pos + border size * 2 (JIC)
|
||||||
static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
wlr_box damageBox = pWindow->getFullWindowBoundingBox();
|
||||||
wlr_box damageBox = { pWindow->m_vRealPosition.vec().x - *PBORDERSIZE - 1, pWindow->m_vRealPosition.vec().y - *PBORDERSIZE - 1, pWindow->m_vRealSize.vec().x + 2 * *PBORDERSIZE + 2, pWindow->m_vRealSize.vec().y + 2 * *PBORDERSIZE + 2};
|
|
||||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||||
wlr_box fixedDamageBox = damageBox;
|
wlr_box fixedDamageBox = damageBox;
|
||||||
fixedDamageBox.x -= m.vecPosition.x;
|
fixedDamageBox.x -= m.vecPosition.x;
|
||||||
|
|
|
@ -1,341 +1,4 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include "shaders/Textures.hpp"
|
||||||
|
#include "shaders/Shadow.hpp"
|
||||||
inline static constexpr auto ROUNDED_SHADER_FUNC = [](const std::string colorVarName) -> std::string {
|
|
||||||
return R"#(
|
|
||||||
if (pixCoord[0] < topLeft[0]) {
|
|
||||||
// we're close left
|
|
||||||
if (pixCoord[1] < topLeft[1]) {
|
|
||||||
// top
|
|
||||||
|
|
||||||
if (ignoreCorners == 1) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float topLeftDistance = distance(topLeft, pixCoord);
|
|
||||||
|
|
||||||
if (topLeftDistance > radius - 1.0) {
|
|
||||||
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
} else if (primitiveMultisample == 1) {
|
|
||||||
float distances = 0.0;
|
|
||||||
if (distance(topLeft, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
|
||||||
if (distance(topLeft, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
|
||||||
if (distance(topLeft, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
|
||||||
if (distance(topLeft, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
|
||||||
|
|
||||||
if (distances == 0.0) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
distances = distances / 4.0;
|
|
||||||
|
|
||||||
gl_FragColor = )#" + colorVarName + R"#( * distances;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (pixCoord[1] > bottomRight[1]) {
|
|
||||||
// bottom
|
|
||||||
|
|
||||||
if (ignoreCorners == 1) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float topLeftDistance = distance(vec2(topLeft[0], bottomRight[1]), pixCoord);
|
|
||||||
|
|
||||||
if (topLeftDistance > radius - 1.0) {
|
|
||||||
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
} else if (primitiveMultisample == 1) {
|
|
||||||
float distances = 0.0;
|
|
||||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
|
||||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
|
||||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
|
||||||
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
|
||||||
|
|
||||||
if (distances == 0.0) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
distances = distances / 4.0;
|
|
||||||
|
|
||||||
gl_FragColor = )#" + colorVarName + R"#( * distances;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (pixCoord[0] > bottomRight[0]) {
|
|
||||||
// we're close right
|
|
||||||
if (pixCoord[1] < topLeft[1]) {
|
|
||||||
// top
|
|
||||||
|
|
||||||
if (ignoreCorners == 1) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float topLeftDistance = distance(vec2(bottomRight[0], topLeft[1]), pixCoord);
|
|
||||||
|
|
||||||
if (topLeftDistance > radius - 1.0) {
|
|
||||||
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
} else if (primitiveMultisample == 1) {
|
|
||||||
float distances = 0.0;
|
|
||||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
|
||||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
|
||||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
|
||||||
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
|
||||||
|
|
||||||
if (distances == 0.0) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
distances = distances / 4.0;
|
|
||||||
|
|
||||||
gl_FragColor = )#" + colorVarName + R"#( * distances;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (pixCoord[1] > bottomRight[1]) {
|
|
||||||
// bottom
|
|
||||||
|
|
||||||
if (ignoreCorners == 1) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float topLeftDistance = distance(bottomRight, pixCoord);
|
|
||||||
|
|
||||||
if (topLeftDistance > radius - 1.0) {
|
|
||||||
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
} else if (primitiveMultisample == 1) {
|
|
||||||
float distances = 0.0;
|
|
||||||
if (distance(bottomRight, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
|
||||||
if (distance(bottomRight, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
|
||||||
if (distance(bottomRight, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
|
||||||
if (distance(bottomRight, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
|
||||||
|
|
||||||
if (distances == 0.0) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
distances = distances / 4.0;
|
|
||||||
|
|
||||||
gl_FragColor = )#" + colorVarName + R"#( * distances;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)#";
|
|
||||||
};
|
|
||||||
|
|
||||||
inline const std::string QUADVERTSRC = R"#(
|
|
||||||
uniform mat3 proj;
|
|
||||||
uniform vec4 color;
|
|
||||||
attribute vec2 pos;
|
|
||||||
attribute vec2 texcoord;
|
|
||||||
varying vec4 v_color;
|
|
||||||
varying vec2 v_texcoord;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);
|
|
||||||
v_color = color;
|
|
||||||
v_texcoord = texcoord;
|
|
||||||
})#";
|
|
||||||
|
|
||||||
inline const std::string QUADFRAGSRC = R"#(
|
|
||||||
precision mediump float;
|
|
||||||
varying vec4 v_color;
|
|
||||||
varying vec2 v_texcoord;
|
|
||||||
|
|
||||||
uniform vec2 topLeft;
|
|
||||||
uniform vec2 bottomRight;
|
|
||||||
uniform vec2 fullSize;
|
|
||||||
uniform float radius;
|
|
||||||
|
|
||||||
uniform int primitiveMultisample;
|
|
||||||
uniform int ignoreCorners;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
if (radius == 0.0) {
|
|
||||||
gl_FragColor = v_color;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 pixCoord = fullSize * v_texcoord;
|
|
||||||
|
|
||||||
)#" + ROUNDED_SHADER_FUNC("v_color") + R"#(
|
|
||||||
|
|
||||||
gl_FragColor = v_color;
|
|
||||||
})#";
|
|
||||||
|
|
||||||
inline const std::string TEXVERTSRC = R"#(
|
|
||||||
uniform mat3 proj;
|
|
||||||
attribute vec2 pos;
|
|
||||||
attribute vec2 texcoord;
|
|
||||||
varying vec2 v_texcoord;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);
|
|
||||||
v_texcoord = texcoord;
|
|
||||||
})#";
|
|
||||||
|
|
||||||
inline const std::string TEXFRAGSRCRGBA = R"#(
|
|
||||||
precision mediump float;
|
|
||||||
varying vec2 v_texcoord; // is in 0-1
|
|
||||||
uniform sampler2D tex;
|
|
||||||
uniform float alpha;
|
|
||||||
|
|
||||||
uniform vec2 topLeft;
|
|
||||||
uniform vec2 bottomRight;
|
|
||||||
uniform vec2 fullSize;
|
|
||||||
uniform float radius;
|
|
||||||
|
|
||||||
uniform int discardOpaque;
|
|
||||||
|
|
||||||
uniform int primitiveMultisample;
|
|
||||||
uniform int ignoreCorners;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
|
|
||||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
|
||||||
|
|
||||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 pixCoord = fullSize * v_texcoord;
|
|
||||||
|
|
||||||
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
|
||||||
R"#(
|
|
||||||
|
|
||||||
gl_FragColor = pixColor * alpha;
|
|
||||||
})#";
|
|
||||||
|
|
||||||
inline const std::string TEXFRAGSRCRGBX = R"#(
|
|
||||||
precision mediump float;
|
|
||||||
varying vec2 v_texcoord;
|
|
||||||
uniform sampler2D tex;
|
|
||||||
uniform float alpha;
|
|
||||||
|
|
||||||
uniform vec2 topLeft;
|
|
||||||
uniform vec2 bottomRight;
|
|
||||||
uniform vec2 fullSize;
|
|
||||||
uniform float radius;
|
|
||||||
|
|
||||||
uniform int discardOpaque;
|
|
||||||
|
|
||||||
uniform int primitiveMultisample;
|
|
||||||
uniform int ignoreCorners;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
|
|
||||||
if (discardOpaque == 1 && alpha == 1.0) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec4 pixColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
|
|
||||||
|
|
||||||
vec2 pixCoord = fullSize * v_texcoord;
|
|
||||||
|
|
||||||
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
|
||||||
|
|
||||||
gl_FragColor = pixColor * alpha;
|
|
||||||
})#";
|
|
||||||
|
|
||||||
inline const std::string FRAGBLUR1 = R"#(
|
|
||||||
#version 100
|
|
||||||
precision mediump float;
|
|
||||||
varying mediump vec2 v_texcoord; // is in 0-1
|
|
||||||
uniform sampler2D tex;
|
|
||||||
|
|
||||||
uniform float radius;
|
|
||||||
uniform vec2 halfpixel;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec2 uv = v_texcoord * 2.0;
|
|
||||||
|
|
||||||
vec4 sum = texture2D(tex, uv) * 4.0;
|
|
||||||
sum += texture2D(tex, uv - halfpixel.xy * radius);
|
|
||||||
sum += texture2D(tex, uv + halfpixel.xy * radius);
|
|
||||||
sum += texture2D(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius);
|
|
||||||
sum += texture2D(tex, uv - vec2(halfpixel.x, -halfpixel.y) * radius);
|
|
||||||
gl_FragColor = sum / 8.0;
|
|
||||||
}
|
|
||||||
)#";
|
|
||||||
|
|
||||||
inline const std::string FRAGBLUR2 = R"#(
|
|
||||||
#version 100
|
|
||||||
precision mediump float;
|
|
||||||
varying mediump vec2 v_texcoord; // is in 0-1
|
|
||||||
uniform sampler2D tex;
|
|
||||||
|
|
||||||
uniform float radius;
|
|
||||||
uniform vec2 halfpixel;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec2 uv = v_texcoord / 2.0;
|
|
||||||
|
|
||||||
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;
|
|
||||||
sum += texture2D(tex, uv + vec2(0.0, halfpixel.y * 2.0) * radius);
|
|
||||||
sum += texture2D(tex, uv + vec2(halfpixel.x, halfpixel.y) * radius) * 2.0;
|
|
||||||
sum += texture2D(tex, uv + vec2(halfpixel.x * 2.0, 0.0) * radius);
|
|
||||||
sum += texture2D(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius) * 2.0;
|
|
||||||
sum += texture2D(tex, uv + vec2(0.0, -halfpixel.y * 2.0) * radius);
|
|
||||||
sum += texture2D(tex, uv + vec2(-halfpixel.x, -halfpixel.y) * radius) * 2.0;
|
|
||||||
|
|
||||||
gl_FragColor = sum / 12.0;
|
|
||||||
}
|
|
||||||
)#";
|
|
||||||
|
|
||||||
inline const std::string TEXFRAGSRCEXT = R"#(
|
|
||||||
#extension GL_OES_EGL_image_external : require
|
|
||||||
|
|
||||||
precision mediump float;
|
|
||||||
varying vec2 v_texcoord;
|
|
||||||
uniform samplerExternalOES texture0;
|
|
||||||
uniform float alpha;
|
|
||||||
|
|
||||||
uniform vec2 topLeft;
|
|
||||||
uniform vec2 bottomRight;
|
|
||||||
uniform vec2 fullSize;
|
|
||||||
uniform float radius;
|
|
||||||
|
|
||||||
uniform int discardOpaque;
|
|
||||||
|
|
||||||
uniform int primitiveMultisample;
|
|
||||||
uniform int ignoreCorners;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
|
|
||||||
vec4 pixColor = texture2D(texture0, v_texcoord);
|
|
||||||
|
|
||||||
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0) {
|
|
||||||
discard;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec2 pixCoord = fullSize * v_texcoord;
|
|
||||||
|
|
||||||
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
|
||||||
|
|
||||||
gl_FragColor = pixColor * alpha;
|
|
||||||
})#";
|
|
66
src/render/decorations/CHyprDropShadowDecoration.cpp
Normal file
66
src/render/decorations/CHyprDropShadowDecoration.cpp
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
#include "CHyprDropShadowDecoration.hpp"
|
||||||
|
|
||||||
|
#include "../../Compositor.hpp"
|
||||||
|
|
||||||
|
CHyprDropShadowDecoration::CHyprDropShadowDecoration(CWindow* pWindow) {
|
||||||
|
m_pWindow = pWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHyprDropShadowDecoration::~CHyprDropShadowDecoration() {
|
||||||
|
updateWindow(m_pWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
SWindowDecorationExtents CHyprDropShadowDecoration::getWindowDecorationExtents() {
|
||||||
|
static auto *const PSHADOWS = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue;
|
||||||
|
|
||||||
|
if (*PSHADOWS != 1)
|
||||||
|
return {{}, {}};
|
||||||
|
|
||||||
|
return m_seExtents;
|
||||||
|
}
|
||||||
|
|
||||||
|
eDecorationType CHyprDropShadowDecoration::getDecorationType() {
|
||||||
|
return DECORATION_SHADOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHyprDropShadowDecoration::damageEntire() {
|
||||||
|
static auto *const PSHADOWS = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue;
|
||||||
|
|
||||||
|
if (*PSHADOWS != 1)
|
||||||
|
return; // disabled
|
||||||
|
|
||||||
|
wlr_box dm = {m_vLastWindowPos.x - m_seExtents.topLeft.x, m_vLastWindowPos.y - m_seExtents.topLeft.y, m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x, m_vLastWindowSize.y + m_seExtents.topLeft.y + m_seExtents.bottomRight.y};
|
||||||
|
g_pHyprRenderer->damageBox(&dm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHyprDropShadowDecoration::updateWindow(CWindow* pWindow) {
|
||||||
|
damageEntire();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CHyprDropShadowDecoration::draw(SMonitor* pMonitor) {
|
||||||
|
|
||||||
|
if (!g_pCompositor->windowValidMapped(m_pWindow))
|
||||||
|
return;
|
||||||
|
|
||||||
|
static auto *const PSHADOWS = &g_pConfigManager->getConfigValuePtr("decoration:drop_shadow")->intValue;
|
||||||
|
static auto *const PSHADOWSIZE = &g_pConfigManager->getConfigValuePtr("decoration:shadow_range")->intValue;
|
||||||
|
static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue;
|
||||||
|
|
||||||
|
if (*PSHADOWS != 1)
|
||||||
|
return; // disabled
|
||||||
|
|
||||||
|
// update the extents if needed
|
||||||
|
if (*PSHADOWSIZE != m_seExtents.topLeft.x)
|
||||||
|
m_seExtents = {{*PSHADOWSIZE + 2, *PSHADOWSIZE + 2}, {*PSHADOWSIZE + 2, *PSHADOWSIZE + 2}};
|
||||||
|
|
||||||
|
m_vLastWindowPos = m_pWindow->m_vRealPosition.vec();
|
||||||
|
m_vLastWindowSize = m_pWindow->m_vRealSize.vec();
|
||||||
|
|
||||||
|
// draw the shadow
|
||||||
|
wlr_box fullBox = {m_vLastWindowPos.x - m_seExtents.topLeft.x + 2, m_vLastWindowPos.y - m_seExtents.topLeft.y + 2, m_vLastWindowSize.x + m_seExtents.topLeft.x + m_seExtents.bottomRight.x - 4, m_vLastWindowSize.y + m_seExtents.topLeft.y + m_seExtents.bottomRight.y - 4};
|
||||||
|
|
||||||
|
fullBox.x -= pMonitor->vecPosition.x;
|
||||||
|
fullBox.y -= pMonitor->vecPosition.y;
|
||||||
|
|
||||||
|
g_pHyprOpenGL->renderRoundedShadow(&fullBox, *PROUNDING, *PSHADOWSIZE);
|
||||||
|
}
|
27
src/render/decorations/CHyprDropShadowDecoration.hpp
Normal file
27
src/render/decorations/CHyprDropShadowDecoration.hpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IHyprWindowDecoration.hpp"
|
||||||
|
|
||||||
|
class CHyprDropShadowDecoration : public IHyprWindowDecoration {
|
||||||
|
public:
|
||||||
|
CHyprDropShadowDecoration(CWindow*);
|
||||||
|
virtual ~CHyprDropShadowDecoration();
|
||||||
|
|
||||||
|
virtual SWindowDecorationExtents getWindowDecorationExtents();
|
||||||
|
|
||||||
|
virtual void draw(SMonitor*);
|
||||||
|
|
||||||
|
virtual eDecorationType getDecorationType();
|
||||||
|
|
||||||
|
virtual void updateWindow(CWindow*);
|
||||||
|
|
||||||
|
virtual void damageEntire();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SWindowDecorationExtents m_seExtents;
|
||||||
|
|
||||||
|
CWindow* m_pWindow = nullptr;
|
||||||
|
|
||||||
|
Vector2D m_vLastWindowPos;
|
||||||
|
Vector2D m_vLastWindowSize;
|
||||||
|
};
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
enum eDecorationType {
|
enum eDecorationType {
|
||||||
DECORATION_NONE = -1,
|
DECORATION_NONE = -1,
|
||||||
DECORATION_GROUPBAR
|
DECORATION_GROUPBAR,
|
||||||
|
DECORATION_SHADOW
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SWindowDecorationExtents {
|
struct SWindowDecorationExtents {
|
||||||
|
|
83
src/render/shaders/Shadow.hpp
Normal file
83
src/render/shaders/Shadow.hpp
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
inline const std::string FRAGSHADOW = R"#(
|
||||||
|
precision mediump float;
|
||||||
|
varying vec4 v_color;
|
||||||
|
varying vec2 v_texcoord;
|
||||||
|
|
||||||
|
uniform vec2 topLeft;
|
||||||
|
uniform vec2 bottomRight;
|
||||||
|
uniform vec2 fullSize;
|
||||||
|
uniform float radius;
|
||||||
|
uniform float range;
|
||||||
|
uniform float shadowPower;
|
||||||
|
uniform int ignoreWindow;
|
||||||
|
|
||||||
|
float pixAlphaRoundedDistance(float distanceToCorner) {
|
||||||
|
if (distanceToCorner > radius) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (distanceToCorner > radius - range) {
|
||||||
|
return pow((range - (distanceToCorner - radius + range)) / range, shadowPower); // i think?
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
vec4 pixColor = v_color;
|
||||||
|
float originalAlpha = pixColor[3];
|
||||||
|
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
|
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 (!done) {
|
||||||
|
// distance to all straight bb borders
|
||||||
|
float distanceT = pixCoord[1];
|
||||||
|
float distanceB = fullSize[1] - pixCoord[1];
|
||||||
|
float distanceL = pixCoord[0];
|
||||||
|
float distanceR = fullSize[0] - pixCoord[0];
|
||||||
|
|
||||||
|
// get the smallest
|
||||||
|
float smallest = min(min(distanceT, distanceB), min(distanceL, distanceR));
|
||||||
|
|
||||||
|
if (smallest < range) {
|
||||||
|
pixColor[3] = pixColor[3] * pow((smallest / range), shadowPower);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pixColor[3] == 0.0 || (ignoreWindow == 1 && pixColor[3] == originalAlpha)) {
|
||||||
|
discard; return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor = pixColor;
|
||||||
|
})#";
|
341
src/render/shaders/Textures.hpp
Normal file
341
src/render/shaders/Textures.hpp
Normal file
|
@ -0,0 +1,341 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
inline static constexpr auto ROUNDED_SHADER_FUNC = [](const std::string colorVarName) -> std::string {
|
||||||
|
return R"#(
|
||||||
|
if (pixCoord[0] < topLeft[0]) {
|
||||||
|
// we're close left
|
||||||
|
if (pixCoord[1] < topLeft[1]) {
|
||||||
|
// top
|
||||||
|
|
||||||
|
if (ignoreCorners == 1) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float topLeftDistance = distance(topLeft, pixCoord);
|
||||||
|
|
||||||
|
if (topLeftDistance > radius - 1.0) {
|
||||||
|
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
} else if (primitiveMultisample == 1) {
|
||||||
|
float distances = 0.0;
|
||||||
|
if (distance(topLeft, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(topLeft, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(topLeft, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(topLeft, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
|
||||||
|
if (distances == 0.0) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
distances = distances / 4.0;
|
||||||
|
|
||||||
|
gl_FragColor = )#" + colorVarName + R"#( * distances;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (pixCoord[1] > bottomRight[1]) {
|
||||||
|
// bottom
|
||||||
|
|
||||||
|
if (ignoreCorners == 1) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float topLeftDistance = distance(vec2(topLeft[0], bottomRight[1]), pixCoord);
|
||||||
|
|
||||||
|
if (topLeftDistance > radius - 1.0) {
|
||||||
|
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
} else if (primitiveMultisample == 1) {
|
||||||
|
float distances = 0.0;
|
||||||
|
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(vec2(topLeft[0], bottomRight[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
|
||||||
|
if (distances == 0.0) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
distances = distances / 4.0;
|
||||||
|
|
||||||
|
gl_FragColor = )#" + colorVarName + R"#( * distances;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pixCoord[0] > bottomRight[0]) {
|
||||||
|
// we're close right
|
||||||
|
if (pixCoord[1] < topLeft[1]) {
|
||||||
|
// top
|
||||||
|
|
||||||
|
if (ignoreCorners == 1) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float topLeftDistance = distance(vec2(bottomRight[0], topLeft[1]), pixCoord);
|
||||||
|
|
||||||
|
if (topLeftDistance > radius - 1.0) {
|
||||||
|
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
} else if (primitiveMultisample == 1) {
|
||||||
|
float distances = 0.0;
|
||||||
|
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(vec2(bottomRight[0], topLeft[1]), pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
|
||||||
|
if (distances == 0.0) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
distances = distances / 4.0;
|
||||||
|
|
||||||
|
gl_FragColor = )#" + colorVarName + R"#( * distances;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (pixCoord[1] > bottomRight[1]) {
|
||||||
|
// bottom
|
||||||
|
|
||||||
|
if (ignoreCorners == 1) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float topLeftDistance = distance(bottomRight, pixCoord);
|
||||||
|
|
||||||
|
if (topLeftDistance > radius - 1.0) {
|
||||||
|
if (primitiveMultisample == 0 && topLeftDistance > radius) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
} else if (primitiveMultisample == 1) {
|
||||||
|
float distances = 0.0;
|
||||||
|
if (distance(bottomRight, pixCoord + vec2(0.25, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(bottomRight, pixCoord + vec2(0.75, 0.25)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(bottomRight, pixCoord + vec2(0.25, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
if (distance(bottomRight, pixCoord + vec2(0.75, 0.75)) < radius) { distances = distances + 1.0; }
|
||||||
|
|
||||||
|
if (distances == 0.0) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
distances = distances / 4.0;
|
||||||
|
|
||||||
|
gl_FragColor = )#" + colorVarName + R"#( * distances;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)#";
|
||||||
|
};
|
||||||
|
|
||||||
|
inline const std::string QUADVERTSRC = R"#(
|
||||||
|
uniform mat3 proj;
|
||||||
|
uniform vec4 color;
|
||||||
|
attribute vec2 pos;
|
||||||
|
attribute vec2 texcoord;
|
||||||
|
varying vec4 v_color;
|
||||||
|
varying vec2 v_texcoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);
|
||||||
|
v_color = color;
|
||||||
|
v_texcoord = texcoord;
|
||||||
|
})#";
|
||||||
|
|
||||||
|
inline const std::string QUADFRAGSRC = R"#(
|
||||||
|
precision mediump float;
|
||||||
|
varying vec4 v_color;
|
||||||
|
varying vec2 v_texcoord;
|
||||||
|
|
||||||
|
uniform vec2 topLeft;
|
||||||
|
uniform vec2 bottomRight;
|
||||||
|
uniform vec2 fullSize;
|
||||||
|
uniform float radius;
|
||||||
|
|
||||||
|
uniform int primitiveMultisample;
|
||||||
|
uniform int ignoreCorners;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
if (radius == 0.0) {
|
||||||
|
gl_FragColor = v_color;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 pixCoord = fullSize * v_texcoord;
|
||||||
|
|
||||||
|
)#" + ROUNDED_SHADER_FUNC("v_color") + R"#(
|
||||||
|
|
||||||
|
gl_FragColor = v_color;
|
||||||
|
})#";
|
||||||
|
|
||||||
|
inline const std::string TEXVERTSRC = R"#(
|
||||||
|
uniform mat3 proj;
|
||||||
|
attribute vec2 pos;
|
||||||
|
attribute vec2 texcoord;
|
||||||
|
varying vec2 v_texcoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);
|
||||||
|
v_texcoord = texcoord;
|
||||||
|
})#";
|
||||||
|
|
||||||
|
inline const std::string TEXFRAGSRCRGBA = R"#(
|
||||||
|
precision mediump float;
|
||||||
|
varying vec2 v_texcoord; // is in 0-1
|
||||||
|
uniform sampler2D tex;
|
||||||
|
uniform float alpha;
|
||||||
|
|
||||||
|
uniform vec2 topLeft;
|
||||||
|
uniform vec2 bottomRight;
|
||||||
|
uniform vec2 fullSize;
|
||||||
|
uniform float radius;
|
||||||
|
|
||||||
|
uniform int discardOpaque;
|
||||||
|
|
||||||
|
uniform int primitiveMultisample;
|
||||||
|
uniform int ignoreCorners;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||||
|
|
||||||
|
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 pixCoord = fullSize * v_texcoord;
|
||||||
|
|
||||||
|
)#" + ROUNDED_SHADER_FUNC("pixColor") +
|
||||||
|
R"#(
|
||||||
|
|
||||||
|
gl_FragColor = pixColor * alpha;
|
||||||
|
})#";
|
||||||
|
|
||||||
|
inline const std::string TEXFRAGSRCRGBX = R"#(
|
||||||
|
precision mediump float;
|
||||||
|
varying vec2 v_texcoord;
|
||||||
|
uniform sampler2D tex;
|
||||||
|
uniform float alpha;
|
||||||
|
|
||||||
|
uniform vec2 topLeft;
|
||||||
|
uniform vec2 bottomRight;
|
||||||
|
uniform vec2 fullSize;
|
||||||
|
uniform float radius;
|
||||||
|
|
||||||
|
uniform int discardOpaque;
|
||||||
|
|
||||||
|
uniform int primitiveMultisample;
|
||||||
|
uniform int ignoreCorners;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
if (discardOpaque == 1 && alpha == 1.0) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 pixColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
|
||||||
|
|
||||||
|
vec2 pixCoord = fullSize * v_texcoord;
|
||||||
|
|
||||||
|
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||||
|
|
||||||
|
gl_FragColor = pixColor * alpha;
|
||||||
|
})#";
|
||||||
|
|
||||||
|
inline const std::string FRAGBLUR1 = R"#(
|
||||||
|
#version 100
|
||||||
|
precision mediump float;
|
||||||
|
varying mediump vec2 v_texcoord; // is in 0-1
|
||||||
|
uniform sampler2D tex;
|
||||||
|
|
||||||
|
uniform float radius;
|
||||||
|
uniform vec2 halfpixel;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 uv = v_texcoord * 2.0;
|
||||||
|
|
||||||
|
vec4 sum = texture2D(tex, uv) * 4.0;
|
||||||
|
sum += texture2D(tex, uv - halfpixel.xy * radius);
|
||||||
|
sum += texture2D(tex, uv + halfpixel.xy * radius);
|
||||||
|
sum += texture2D(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius);
|
||||||
|
sum += texture2D(tex, uv - vec2(halfpixel.x, -halfpixel.y) * radius);
|
||||||
|
gl_FragColor = sum / 8.0;
|
||||||
|
}
|
||||||
|
)#";
|
||||||
|
|
||||||
|
inline const std::string FRAGBLUR2 = R"#(
|
||||||
|
#version 100
|
||||||
|
precision mediump float;
|
||||||
|
varying mediump vec2 v_texcoord; // is in 0-1
|
||||||
|
uniform sampler2D tex;
|
||||||
|
|
||||||
|
uniform float radius;
|
||||||
|
uniform vec2 halfpixel;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 uv = v_texcoord / 2.0;
|
||||||
|
|
||||||
|
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;
|
||||||
|
sum += texture2D(tex, uv + vec2(0.0, halfpixel.y * 2.0) * radius);
|
||||||
|
sum += texture2D(tex, uv + vec2(halfpixel.x, halfpixel.y) * radius) * 2.0;
|
||||||
|
sum += texture2D(tex, uv + vec2(halfpixel.x * 2.0, 0.0) * radius);
|
||||||
|
sum += texture2D(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius) * 2.0;
|
||||||
|
sum += texture2D(tex, uv + vec2(0.0, -halfpixel.y * 2.0) * radius);
|
||||||
|
sum += texture2D(tex, uv + vec2(-halfpixel.x, -halfpixel.y) * radius) * 2.0;
|
||||||
|
|
||||||
|
gl_FragColor = sum / 12.0;
|
||||||
|
}
|
||||||
|
)#";
|
||||||
|
|
||||||
|
inline const std::string TEXFRAGSRCEXT = R"#(
|
||||||
|
#extension GL_OES_EGL_image_external : require
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
varying vec2 v_texcoord;
|
||||||
|
uniform samplerExternalOES texture0;
|
||||||
|
uniform float alpha;
|
||||||
|
|
||||||
|
uniform vec2 topLeft;
|
||||||
|
uniform vec2 bottomRight;
|
||||||
|
uniform vec2 fullSize;
|
||||||
|
uniform float radius;
|
||||||
|
|
||||||
|
uniform int discardOpaque;
|
||||||
|
|
||||||
|
uniform int primitiveMultisample;
|
||||||
|
uniform int ignoreCorners;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
vec4 pixColor = texture2D(texture0, v_texcoord);
|
||||||
|
|
||||||
|
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 pixCoord = fullSize * v_texcoord;
|
||||||
|
|
||||||
|
)#" + ROUNDED_SHADER_FUNC("pixColor") + R"#(
|
||||||
|
|
||||||
|
gl_FragColor = pixColor * alpha;
|
||||||
|
})#";
|
Loading…
Reference in a new issue