From 3150cb2631210996b84ebf357dd94b3e26625e67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Wed, 3 Dec 2008 19:46:20 +0000 Subject: [PATCH] Implement clipping of snow flakes in fragment shader. This fixes painting the flakes several times in multi screen setup as well as during active desktop grid effect. Also honour translations and scaling of the desktop and re-enabling snow during active full screen effect. BUG: 176489 svn path=/trunk/KDE/kdebase/workspace/; revision=892202 --- effects/data/snow.frag | 8 ++++++++ effects/snow.cpp | 40 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/effects/data/snow.frag b/effects/data/snow.frag index d7b23ddc5e..812da9907b 100644 --- a/effects/data/snow.frag +++ b/effects/data/snow.frag @@ -18,8 +18,16 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . *********************************************************************/ uniform sampler2D snowTexture; +uniform int left; +uniform int right; +uniform int top; +uniform int bottom; void main() { gl_FragColor = texture2D( snowTexture, gl_TexCoord[0].st ); + // manual clipping + if( gl_FragCoord.x < float( left ) || gl_FragCoord.x > float( right ) + || gl_FragCoord.y < float( top ) || gl_FragCoord.y > float( bottom ) ) + discard; } diff --git a/effects/snow.cpp b/effects/snow.cpp index b259b4d809..a9d4dada9d 100644 --- a/effects/snow.cpp +++ b/effects/snow.cpp @@ -82,7 +82,7 @@ void SnowEffect::reconfigure( ReconfigureFlags ) void SnowEffect::prePaintScreen( ScreenPrePaintData& data, int time ) { - if ( active && effects->activeFullScreenEffect() == NULL ) + if ( active ) { // if number of active snowflakes is smaller than maximum number // create a random new snowflake @@ -118,8 +118,6 @@ void SnowEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data ) void SnowEffect::snowing( QRegion& region ) { - if( effects->activeFullScreenEffect() != NULL ) - return; if(! texture ) loadTexture(); if( texture ) { @@ -134,6 +132,11 @@ void SnowEffect::snowing( QRegion& region ) if( mUseShader ) { mShader->bind(); + QRect rect = region.boundingRect(); + mShader->setUniform( "left", rect.x() ); + mShader->setUniform( "right", rect.x() + rect.width() ); + mShader->setUniform( "top", rect.y() ); + mShader->setUniform( "bottom", rect.y() + rect.height() ); } else glNewList( list, GL_COMPILE_AND_EXECUTE ); @@ -222,7 +225,36 @@ void SnowEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowP } effects->paintWindow( w, mask, region, data ); if( active && w->isDesktop() && snowBehindWindows ) - snowing( region ); + { + QRect rect = effects->clientArea( FullScreenArea, w->screen(), effects->currentDesktop()); + QRegion snowRegion( rect.x() + data.xTranslate, rect.y() + data.yTranslate, + (double)rect.width()*data.xScale, (double)rect.height()*data.yScale); + if( mUseShader ) + { + // have to adjust the y values to fit OpenGL + // in OpenGL y==0 is at bottom, in Qt at top + int y = 0; + if( effects->numScreens() > 1 ) + { + QRect fullArea = effects->clientArea( FullArea, 0, 1 ); + if( fullArea.height() != rect.height() ) + { + if( rect.y() == 0 ) + y = fullArea.height() - rect.height(); + else + y = fullArea.height() - rect.y() - rect.height(); + } + } + snowRegion = QRegion( rect.x() + data.xTranslate, + y + rect.height() - data.yTranslate - (double)rect.height()*data.yScale, + (double)rect.width()*data.xScale, (double)rect.height()*data.yScale); + } + glPushMatrix(); + glTranslatef( rect.x() + data.xTranslate, rect.y() + data.yTranslate, 0.0 ); + glScalef( data.xScale, data.yScale, 1.0 ); + snowing( snowRegion ); + glPopMatrix(); + } } void SnowEffect::toggle()