From bad62372181a92447d8dd3ecb072e79ce54a0f50 Mon Sep 17 00:00:00 2001 From: Rivo Laks Date: Wed, 4 Jul 2007 11:39:30 +0000 Subject: [PATCH] - Implement textured shadows. The default texture gives you nice rounded corners, but it can be changed to do something more fancy ;-) - Fix a shadow transformation/rendering problem svn path=/trunk/KDE/kdebase/workspace/; revision=683210 --- effects/data/shadow-texture.png | Bin 0 -> 3126 bytes effects/shadow.cpp | 91 +++++++++++++++++++++----------- effects/shadow.h | 8 +++ 3 files changed, 67 insertions(+), 32 deletions(-) create mode 100644 effects/data/shadow-texture.png diff --git a/effects/data/shadow-texture.png b/effects/data/shadow-texture.png new file mode 100644 index 0000000000000000000000000000000000000000..0be80680432ed945971bd837f54dcdb47231dc28 GIT binary patch literal 3126 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 Qod5s;07*qoM6N<$f?o&Wg8%>k literal 0 HcmV?d00001 diff --git a/effects/shadow.cpp b/effects/shadow.cpp index 7547abd408..c257d02a2e 100644 --- a/effects/shadow.cpp +++ b/effects/shadow.cpp @@ -13,6 +13,7 @@ License. See the file "COPYING" for the exact licensing terms. #include #include +#include namespace KWin { @@ -26,12 +27,20 @@ ShadowEffect::ShadowEffect() shadowYOffset = conf.readEntry( "YOffset", 10 ); shadowOpacity = (float)conf.readEntry( "Opacity", 0.2 ); shadowFuzzyness = conf.readEntry( "Fuzzyness", 10 ); + + QString shadowtexture = KGlobal::dirs()->findResource("data", "kwin/shadow-texture.png"); + mShadowTexture = new GLTexture(shadowtexture); } +QRect ShadowEffect::shadowRectangle(const QRect& windowRectangle) const + { + return windowRectangle.adjusted( shadowXOffset - shadowFuzzyness - 20, shadowYOffset - shadowFuzzyness - 20, + shadowXOffset + shadowFuzzyness + 20, shadowYOffset + shadowFuzzyness + 20); + } void ShadowEffect::prePaintWindow( EffectWindow* w, int* mask, QRegion* paint, QRegion* clip, int time ) { *mask |= PAINT_WINDOW_TRANSLUCENT; - *paint |= ( QRegion( w->geometry()) & *paint ).translated( shadowXOffset, shadowYOffset ); + *paint |= QRegion( shadowRectangle( ( QRegion( w->geometry()) & *paint ).boundingRect() )); effects->prePaintWindow( w, mask, paint, clip, time ); } @@ -49,16 +58,23 @@ void ShadowEffect::postPaintWindow( EffectWindow* w ) QRect ShadowEffect::transformWindowDamage( EffectWindow* w, const QRect& r ) { - QRect r2 = r | r.adjusted( shadowXOffset - shadowFuzzyness, shadowYOffset - shadowFuzzyness, - shadowXOffset + shadowFuzzyness, shadowYOffset + shadowFuzzyness); + QRect r2 = r | shadowRectangle( r ); return effects->transformWindowDamage( w, r2 ); } +void ShadowEffect::addQuadVertices(QVector& verts, float x1, float y1, float x2, float y2) const +{ + verts << x1 << y1; + verts << x1 << y2; + verts << x2 << y2; + verts << x2 << y1; +} + void ShadowEffect::drawShadow( EffectWindow* window, int mask, QRegion region, WindowPaintData& data ) { if(( mask & PAINT_WINDOW_TRANSLUCENT ) == 0 ) return; - glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT ); + glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); @@ -72,34 +88,45 @@ void ShadowEffect::drawShadow( EffectWindow* window, int mask, QRegion region, W int w = window->width(); int h = window->height(); int fuzzy = shadowFuzzyness; - const float verts[ 5 * 4 * 2 ] = - { - // center piece (100% opacity) - 0 + fuzzy, 0 + fuzzy, 0 + fuzzy, h - fuzzy, w - fuzzy, h - fuzzy, w - fuzzy, 0 + fuzzy, - // left - 0 - fuzzy, 0 - fuzzy, 0 - fuzzy, h + fuzzy, 0 + fuzzy, h - fuzzy, 0 + fuzzy, 0 + fuzzy, - // top - 0 - fuzzy, 0 - fuzzy, 0 + fuzzy, 0 + fuzzy, w - fuzzy, 0 + fuzzy, w + fuzzy, 0 - fuzzy, - // right piece - w - fuzzy, 0 + fuzzy, w - fuzzy, h - fuzzy, w + fuzzy, h + fuzzy, w + fuzzy, 0 - fuzzy, - // bottom - 0 + fuzzy, h - fuzzy, 0 - fuzzy, h + fuzzy, w + fuzzy, h + fuzzy, w - fuzzy, h - fuzzy, - }; - float opacity = shadowOpacity * data.opacity; - const float colors[ 5 * 4 * 4 ] = - { - // center - 0, 0, 0, opacity, 0, 0, 0, opacity, 0, 0, 0, opacity, 0, 0, 0, opacity, - // left - 0, 0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, opacity, 0, 0, 0, opacity, - // top - 0, 0, 0, 0 , 0, 0, 0, opacity, 0, 0, 0, opacity, 0, 0, 0, 0 , - // right - 0, 0, 0, opacity, 0, 0, 0, opacity, 0, 0, 0, 0 , 0, 0, 0, 0 , - // bottom - 0, 0, 0, opacity, 0, 0, 0, 0 , 0, 0, 0, 0 , 0, 0, 0, opacity, - }; - renderGLGeometry( mask, region, 5 * 4, verts, 0, colors ); + + QVector verts, texcoords; + // center + addQuadVertices(verts, 0 + fuzzy, 0 + fuzzy, w - fuzzy, h - fuzzy); + addQuadVertices(texcoords, 0.5, 0.5, 0.5, 0.5); + // sides + // left + addQuadVertices(verts, 0 - fuzzy, 0 + fuzzy, 0 + fuzzy, h - fuzzy); + addQuadVertices(texcoords, 0.0, 0.5, 0.5, 0.5); + // top + addQuadVertices(verts, 0 + fuzzy, 0 - fuzzy, w - fuzzy, 0 + fuzzy); + addQuadVertices(texcoords, 0.5, 0.0, 0.5, 0.5); + // right + addQuadVertices(verts, w - fuzzy, 0 + fuzzy, w + fuzzy, h - fuzzy); + addQuadVertices(texcoords, 0.5, 0.5, 1.0, 0.5); + // bottom + addQuadVertices(verts, 0 + fuzzy, h - fuzzy, w - fuzzy, h + fuzzy); + addQuadVertices(texcoords, 0.5, 0.5, 0.5, 1.0); + // corners + // top-left + addQuadVertices(verts, 0 - fuzzy, 0 - fuzzy, 0 + fuzzy, 0 + fuzzy); + addQuadVertices(texcoords, 0.0, 0.0, 0.5, 0.5); + // top-right + addQuadVertices(verts, w - fuzzy, 0 - fuzzy, w + fuzzy, 0 + fuzzy); + addQuadVertices(texcoords, 0.5, 0.0, 1.0, 0.5); + // bottom-left + addQuadVertices(verts, 0 - fuzzy, h - fuzzy, 0 + fuzzy, h + fuzzy); + addQuadVertices(texcoords, 0.0, 0.5, 0.5, 1.0); + // bottom-right + addQuadVertices(verts, w - fuzzy, h - fuzzy, w + fuzzy, h + fuzzy); + addQuadVertices(texcoords, 0.5, 0.5, 1.0, 1.0); + + mShadowTexture->bind(); + glColor4f(0, 0, 0, shadowOpacity * data.opacity); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + // We have two elements per vertex in the verts array + int verticesCount = verts.count() / 2; + renderGLGeometry( mask, region, verticesCount, verts.data(), texcoords.data() ); + mShadowTexture->unbind(); glPopMatrix(); glPopAttrib(); diff --git a/effects/shadow.h b/effects/shadow.h index a9c3a10e91..96ee3e972b 100644 --- a/effects/shadow.h +++ b/effects/shadow.h @@ -13,9 +13,12 @@ License. See the file "COPYING" for the exact licensing terms. #include + namespace KWin { +class GLTexture; + class ShadowEffect : public Effect { @@ -27,9 +30,14 @@ class ShadowEffect virtual QRect transformWindowDamage( EffectWindow* w, const QRect& r ); private: void drawShadow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data ); + void addQuadVertices(QVector& verts, float x1, float y1, float x2, float y2) const; + // transforms window rect -> shadow rect + QRect shadowRectangle(const QRect& windowRectangle) const; + int shadowXOffset, shadowYOffset; float shadowOpacity; int shadowFuzzyness; + GLTexture* mShadowTexture; }; } // namespace