mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-07 18:45:59 +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 "Compositor.hpp"
|
||||
#include "render/decorations/CHyprDropShadowDecoration.hpp"
|
||||
|
||||
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_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_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() {
|
||||
|
@ -16,8 +19,9 @@ CWindow::~CWindow() {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
||||
|
|
|
@ -49,6 +49,11 @@ void CConfigManager::setDefaultVars() {
|
|||
configValues["decoration:fullscreen_opacity"].floatValue = 1;
|
||||
configValues["decoration:multisample_edges"].intValue = 0;
|
||||
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:col.group_border"].intValue = 0x66777700;
|
||||
|
|
|
@ -75,6 +75,12 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() {
|
|||
m_shBLUR2.posAttrib = glGetAttribLocation(prog, "pos");
|
||||
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.");
|
||||
|
||||
// End shaders
|
||||
|
@ -858,6 +864,68 @@ void CHyprOpenGLImpl::renderSnapshot(SLayerSurface** pLayer) {
|
|||
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) {
|
||||
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(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 renderRoundedShadow(wlr_box*, int round, int range);
|
||||
|
||||
void makeWindowSnapshot(CWindow*);
|
||||
void makeLayerSnapshot(SLayerSurface*);
|
||||
|
@ -106,6 +107,7 @@ private:
|
|||
CShader m_shEXT;
|
||||
CShader m_shBLUR1;
|
||||
CShader m_shBLUR2;
|
||||
CShader m_shSHADOW;
|
||||
//
|
||||
|
||||
GLuint createProgram(const std::string&, const std::string&);
|
||||
|
|
|
@ -569,7 +569,7 @@ void CHyprRenderer::damageWindow(CWindow* pWindow) {
|
|||
// damage by size & pos
|
||||
// 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) {
|
||||
wlr_box fixedDamageBox = damageBox;
|
||||
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);
|
||||
} else {
|
||||
// damage by real size & pos + border size * 2 (JIC)
|
||||
static auto *const PBORDERSIZE = &g_pConfigManager->getConfigValuePtr("general:border_size")->intValue;
|
||||
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};
|
||||
wlr_box damageBox = pWindow->getFullWindowBoundingBox();
|
||||
for (auto& m : g_pCompositor->m_lMonitors) {
|
||||
wlr_box fixedDamageBox = damageBox;
|
||||
fixedDamageBox.x -= m.vecPosition.x;
|
||||
|
|
|
@ -1,341 +1,4 @@
|
|||
#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;
|
||||
})#";
|
||||
#include "shaders/Textures.hpp"
|
||||
#include "shaders/Shadow.hpp"
|
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 {
|
||||
DECORATION_NONE = -1,
|
||||
DECORATION_GROUPBAR
|
||||
DECORATION_GROUPBAR,
|
||||
DECORATION_SHADOW
|
||||
};
|
||||
|
||||
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