opengl: switch to black-and-white for alpha mattes

also fixes shadows on 10b
This commit is contained in:
Vaxry 2023-11-09 22:11:42 +00:00
parent 11432f69b9
commit 14195835ef
4 changed files with 17 additions and 10 deletions

View file

@ -1718,7 +1718,7 @@ void CHyprOpenGLImpl::renderSnapshot(SLayerSurface** pLayer) {
m_bEndFrame = false; m_bEndFrame = false;
} }
void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, float a) { void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, const CColor& color, float a) {
RASSERT(m_RenderData.pMonitor, "Tried to render shadow without begin()!"); RASSERT(m_RenderData.pMonitor, "Tried to render shadow without begin()!");
RASSERT((box->width > 0 && box->height > 0), "Tried to render shadow with width/height < 0!"); RASSERT((box->width > 0 && box->height > 0), "Tried to render shadow with width/height < 0!");
RASSERT(m_pCurrentWindow, "Tried to render shadow without a window!"); RASSERT(m_pCurrentWindow, "Tried to render shadow without a window!");
@ -1737,7 +1737,7 @@ void CHyprOpenGLImpl::renderRoundedShadow(CBox* box, int round, int range, float
const auto SHADOWPOWER = std::clamp((int)*PSHADOWPOWER, 1, 4); const auto SHADOWPOWER = std::clamp((int)*PSHADOWPOWER, 1, 4);
const auto col = m_pCurrentWindow->m_cRealShadowColor.col(); const auto col = color;
float matrix[9]; float matrix[9];
wlr_matrix_project_box(matrix, box->pWlr(), wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0, wlr_matrix_project_box(matrix, box->pWlr(), wlr_output_transform_invert(!m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : m_RenderData.pMonitor->transform), 0,

View file

@ -113,7 +113,7 @@ class CHyprOpenGLImpl {
void renderTexture(wlr_texture*, CBox*, float a, int round = 0, bool allowCustomUV = false); void renderTexture(wlr_texture*, CBox*, float a, int round = 0, bool allowCustomUV = false);
void renderTexture(const CTexture&, CBox*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false); void renderTexture(const CTexture&, CBox*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false);
void renderTextureWithBlur(const CTexture&, CBox*, float a, wlr_surface* pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f); void renderTextureWithBlur(const CTexture&, CBox*, float a, wlr_surface* pSurface, int round = 0, bool blockBlurOptimization = false, float blurA = 1.f);
void renderRoundedShadow(CBox*, int round, int range, float a = 1.0); void renderRoundedShadow(CBox*, int round, int range, const CColor& color, float a = 1.0);
void renderBorder(CBox*, const CGradientValueData&, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */); void renderBorder(CBox*, const CGradientValueData&, int round, int borderSize, float a = 1.0, int outerRound = -1 /* use round */);
void renderTextureMatte(const CTexture& tex, CBox* pBox, CFramebuffer& matte); void renderTextureMatte(const CTexture& tex, CBox* pBox, CFramebuffer& matte);

View file

@ -140,19 +140,26 @@ void CHyprDropShadowDecoration::draw(CMonitor* pMonitor, float a, const Vector2D
windowBox.addExtents(SWindowDecorationExtents{m_eLastExtents * pMonitor->scale}.floor()).round(); windowBox.addExtents(SWindowDecorationExtents{m_eLastExtents * pMonitor->scale}.floor()).round();
if (windowBox.width < 1 || windowBox.height < 1) { if (windowBox.width < 1 || windowBox.height < 1)
return; // prevent assert failed return; // prevent assert failed
}
alphaFB.bind(); alphaFB.bind();
g_pHyprOpenGL->clear(CColor(0, 0, 0, 0));
g_pHyprOpenGL->renderRect(&windowBox, CColor(1.0, 1.0, 1.0, 1.0), ROUNDING * pMonitor->scale); // build the matte
// 10-bit formats have dogshit alpha channels, so we have to use the matte to its fullest.
// first, clear with black (fully transparent)
g_pHyprOpenGL->clear(CColor(0, 0, 0, 1));
// render white shadow
g_pHyprOpenGL->renderRoundedShadow(&fullBox, ROUNDING * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, CColor(1, 1, 1, 1), a);
// render black window box ("clip")
g_pHyprOpenGL->renderRect(&windowBox, CColor(0, 0, 0, 1.0), ROUNDING * pMonitor->scale);
alphaSwapFB.bind(); alphaSwapFB.bind();
g_pHyprOpenGL->clear(CColor(0, 0, 0, 0));
g_pHyprOpenGL->renderRoundedShadow(&fullBox, ROUNDING * pMonitor->scale, *PSHADOWSIZE * pMonitor->scale, a); // alpha swap just has the shadow color. It will be the "texture" to render.
g_pHyprOpenGL->clear(m_pWindow->m_cRealShadowColor.col());
LASTFB->bind(); LASTFB->bind();

View file

@ -137,7 +137,7 @@ uniform sampler2D tex;
uniform sampler2D texMatte; uniform sampler2D texMatte;
void main() { void main() {
gl_FragColor = texture2D(tex, v_texcoord) * (1.0 - texture2D(texMatte, v_texcoord)[3]); gl_FragColor = texture2D(tex, v_texcoord) * texture2D(texMatte, v_texcoord)[0]; // I know it only uses R, but matte should be black/white anyways.
})#"; })#";
inline const std::string TEXFRAGSRCRGBX = R"#( inline const std::string TEXFRAGSRCRGBX = R"#(