diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 8c6ccdbd..5c3e672e 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -37,6 +37,7 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() { m_shRGBA.alpha = glGetUniformLocation(prog, "alpha"); m_shRGBA.texAttrib = glGetAttribLocation(prog, "texcoord"); m_shRGBA.posAttrib = glGetAttribLocation(prog, "pos"); + m_shRGBA.discardOpaque = glGetUniformLocation(prog, "discardOpaque"); prog = createProgram(TEXVERTSRC, TEXFRAGSRCRGBX); m_shRGBX.program = prog; @@ -45,6 +46,7 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() { m_shRGBX.alpha = glGetUniformLocation(prog, "alpha"); m_shRGBX.texAttrib = glGetAttribLocation(prog, "texcoord"); m_shRGBX.posAttrib = glGetAttribLocation(prog, "pos"); + m_shRGBX.discardOpaque = glGetUniformLocation(prog, "discardOpaque"); prog = createProgram(TEXVERTSRC, TEXFRAGSRCEXT); m_shEXT.program = prog; @@ -53,6 +55,7 @@ CHyprOpenGLImpl::CHyprOpenGLImpl() { m_shEXT.alpha = glGetUniformLocation(prog, "alpha"); m_shEXT.posAttrib = glGetAttribLocation(prog, "pos"); m_shEXT.texAttrib = glGetAttribLocation(prog, "texcoord"); + m_shEXT.discardOpaque = glGetUniformLocation(prog, "discardOpaque"); prog = createProgram(TEXVERTSRC, FRAGBLUR1); m_shBLUR1.program = prog; @@ -263,7 +266,7 @@ void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float al scissor((wlr_box*)nullptr); } -void CHyprOpenGLImpl::renderTextureInternal(const CTexture& tex, wlr_box* pBox, float alpha, int round) { +void CHyprOpenGLImpl::renderTextureInternal(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardOpaque) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!"); @@ -306,6 +309,7 @@ void CHyprOpenGLImpl::renderTextureInternal(const CTexture& tex, wlr_box* pBox, glUniformMatrix3fv(shader->proj, 1, GL_FALSE, glMatrix); glUniform1i(shader->tex, 0); glUniform1f(shader->alpha, alpha / 255.f); + glUniform1i(shader->discardOpaque, (int)discardOpaque); // round is in px // so we need to do some maf @@ -383,8 +387,8 @@ void CHyprOpenGLImpl::renderTextureWithBlurInternal(const CTexture& tex, wlr_box glStencilFunc(GL_ALWAYS, 1, -1); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - // render our window to the mirror FB while also writing to the stencil - renderTextureInternal(tex, pBox, a, round); + // render our window to the mirror FB while also writing to the stencil, discard opaque pixels + renderTextureInternal(tex, pBox, a, round, true); // then we disable writing to the mask and ONLY accept writing within the stencil glStencilFunc(GL_EQUAL, 1, -1); @@ -446,14 +450,13 @@ void CHyprOpenGLImpl::renderTextureWithBlurInternal(const CTexture& tex, wlr_box glBindTexture(tex.m_iTarget, 0); - // when the blur is done, let's render the window itself - // we get it from the mirrored FB full because it's the FB 255 alpha cuz we rendered with a before, same for rounding - renderTextureInternal(m_mMonitorRenderResources[m_RenderData.pMonitor].mirrorFB.m_cTex, &fullMonBox, 255.f, 0); - - // and disable the stencil + // disable the stencil glStencilMask(-1); glStencilFunc(GL_ALWAYS, 1, 0xFF); glDisable(GL_STENCIL_TEST); + + // when the blur is done, let's render the window itself. We can't use mirror because it had discardOpaque + renderTextureInternal(tex, pBox, a, round); } void pushVert2D(float x, float y, float* arr, int& counter, wlr_box* box) { diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index ae22a477..deaa1b2e 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -89,7 +89,7 @@ private: GLuint compileShader(const GLuint&, std::string); void createBGTextureForMonitor(SMonitor*); - void renderTextureInternal(const CTexture&, wlr_box* pBox, float a, int round = 0); + void renderTextureInternal(const CTexture&, wlr_box* pBox, float a, int round = 0, bool discardOpaque = false); void renderTextureWithBlurInternal(const CTexture&, wlr_box*, float a, int round = 0); }; diff --git a/src/render/Shader.hpp b/src/render/Shader.hpp index 630dd32f..49272857 100644 --- a/src/render/Shader.hpp +++ b/src/render/Shader.hpp @@ -17,4 +17,5 @@ public: GLint alpha; GLint posAttrib; GLint texAttrib; + GLint discardOpaque; }; \ No newline at end of file diff --git a/src/render/Shaders.hpp b/src/render/Shaders.hpp index 53a8c439..0263f22f 100644 --- a/src/render/Shaders.hpp +++ b/src/render/Shaders.hpp @@ -47,8 +47,17 @@ uniform vec2 bottomRight; uniform vec2 fullSize; uniform float radius; +uniform int discardOpaque; + void main() { + vec4 pixColor = texture2D(tex, v_texcoord); + + if (discardOpaque == 1 && pixColor[3] == 1.0) { + discard; + return; + } + vec2 pixCoord = fullSize * v_texcoord; if (pixCoord[0] < topLeft[0]) { @@ -84,7 +93,7 @@ void main() { } } - gl_FragColor = texture2D(tex, v_texcoord) * alpha; + gl_FragColor = pixColor * alpha; })#"; inline const std::string TEXFRAGSRCRGBX = R"#( @@ -98,7 +107,14 @@ uniform vec2 bottomRight; uniform vec2 fullSize; uniform float radius; +uniform int discardOpaque; + void main() { + + if (discardOpaque == 1) { + discard; + return; + } vec2 pixCoord = fullSize * v_texcoord; @@ -252,8 +268,17 @@ uniform vec2 bottomRight; uniform vec2 fullSize; uniform float radius; +uniform int discardOpaque; + void main() { + vec4 pixColor = texture2D(texture0, v_texcoord); + + if (discardOpaque == 1 && pixColor[3] == 1.0) { + discard; + return; + } + vec2 pixCoord = fullSize * v_texcoord; if (pixCoord[0] < topLeft[0]) { @@ -289,5 +314,5 @@ void main() { } } - gl_FragColor = texture2D(texture0, v_texcoord) * alpha; + gl_FragColor = pixColor * alpha; })#";