1 /********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
5 Copyright (C) 2008 Martin Gräßlin <ubuntu@martin-graesslin.com>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *********************************************************************/
24 #include <KStandardDirs>
25 #include <kconfiggroup.h>
34 KWIN_EFFECT( sphere
, SphereEffect
)
35 KWIN_EFFECT_SUPPORTED( sphere
, SphereEffect::supported() )
37 SphereEffect::SphereEffect()
45 reconfigure( ReconfigureAll
);
48 SphereEffect::~SphereEffect()
53 void SphereEffect::reconfigure( ReconfigureFlags
)
55 loadConfig( "Sphere" );
57 animateDesktopChange
= false;
58 KConfigGroup conf
= effects
->effectConfig( "Sphere" );
59 zPosition
= conf
.readEntry( "ZPosition", 450.0 );
60 capDeformationFactor
= conf
.readEntry( "CapDeformation", 0 )/100.0f
;
64 bool SphereEffect::supported()
66 return GLShader::fragmentShaderSupported() &&
67 (effects
->compositingType() == OpenGLCompositing
);
70 bool SphereEffect::loadData()
73 QString fragmentshader
= KGlobal::dirs()->findResource("data", "kwin/cylinder.frag");
74 QString vertexshader
= KGlobal::dirs()->findResource("data", "kwin/sphere.vert");
75 if( fragmentshader
.isEmpty() || vertexshader
.isEmpty() )
77 kError(1212) << "Couldn't locate shader files" << endl
;
81 mShader
= new GLShader( vertexshader
, fragmentshader
);
82 if( !mShader
->isValid() )
84 kError(1212) << "The shader failed to load!" << endl
;
90 mShader
->setUniform( "winTexture", 0 );
91 mShader
->setUniform( "opacity", cubeOpacity
);
92 QRect rect
= effects
->clientArea( FullScreenArea
, activeScreen
, effects
->currentDesktop());
93 if( effects
->numScreens() > 1 && (slide
|| bigCube
) )
94 rect
= effects
->clientArea( FullArea
, activeScreen
, effects
->currentDesktop() );
95 mShader
->setUniform( "width", (float)rect
.width() );
96 mShader
->setUniform( "height", (float)rect
.height() );
102 void SphereEffect::prePaintWindow( EffectWindow
* w
, WindowPrePaintData
& data
, int time
)
108 if( w
->isOnDesktop( painting_desktop
))
110 data
.quads
= data
.quads
.makeGrid( 40 );
111 QRect rect
= effects
->clientArea( FullArea
, activeScreen
, painting_desktop
);
112 if( w
->x() < rect
.width()/2 && w
->x() + w
->width() > rect
.width()/ 2 )
113 data
.quads
= data
.quads
.splitAtX( rect
.width()/2 - w
->x() );
114 w
->enablePainting( EffectWindow::PAINT_DISABLED_BY_DESKTOP
);
118 w
->disablePainting( EffectWindow::PAINT_DISABLED_BY_DESKTOP
);
122 effects
->prePaintWindow( w
, data
, time
);
125 void SphereEffect::paintWindow( EffectWindow
* w
, int mask
, QRegion region
, WindowPaintData
& data
)
127 if( activated
&& cube_painting
)
129 if( mValid
&& !mInited
)
131 bool useShader
= mValid
;
135 mShader
->setUniform( "windowWidth", (float)w
->width() );
136 mShader
->setUniform( "windowHeight", (float)w
->height() );
137 mShader
->setUniform( "xCoord", (float)w
->x() );
138 mShader
->setUniform( "yCoord", (float)w
->y() );
139 mShader
->setUniform( "cubeAngle", (effects
->numberOfDesktops() - 2 )/(float)effects
->numberOfDesktops() * 180.0f
);
140 data
.shader
= mShader
;
142 CubeEffect::paintWindow( w
, mask
, region
, data
);
149 effects
->paintWindow( w
, mask
, region
, data
);
152 void SphereEffect::paintCap( float z
, float zTexture
)
157 glScalef( 1.0, -1.0, 1.0 );
159 CubeEffect::paintCap( z
, zTexture
);
164 void SphereEffect::paintCapStep( float z
, float zTexture
, bool texture
)
166 QRect rect
= effects
->clientArea( FullArea
, activeScreen
, painting_desktop
);
167 float cubeAngle
= (effects
->numberOfDesktops() - 2 )/(float)effects
->numberOfDesktops() * 180.0f
;
168 float radius
= (rect
.width()*0.5)/cos(cubeAngle
*0.5*M_PI
/180.0);
169 float angle
= acos( (rect
.height()*0.5)/radius
)*180.0/M_PI
;
174 glTranslatef( 0.0, -rect
.height()*0.5, 0.0 );
176 for( int i
=0; i
<30; i
++ )
178 float topAngle
= angle
*i
*M_PI
/180.0;
179 float bottomAngle
= angle
*(i
+1)*M_PI
/180.0;
180 float yTop
= rect
.height() - radius
* cos( topAngle
);
181 yTop
-= (yTop
-rect
.height()*0.5)*capDeformationFactor
;
182 float yBottom
= rect
.height() -radius
* cos( bottomAngle
);
183 yBottom
-= (yBottom
-rect
.height()*0.5)*capDeformationFactor
;
184 for( int j
=0; j
<36; j
++ )
186 float x
= radius
* sin( topAngle
) * sin( (90.0+j
*10.0)*M_PI
/180.0 );
187 float z
= radius
* sin( topAngle
) * cos( (90.0+j
*10.0)*M_PI
/180.0 );
189 glTexCoord2f( x
/(rect
.width())+0.5, 0.5 - z
/zTexture
* 0.5 );
190 glVertex3f( x
, yTop
, z
);
191 x
= radius
* sin( bottomAngle
) * sin( (90.0+j
*10.0)*M_PI
/180.00 );
192 z
= radius
* sin( bottomAngle
) * cos( (90.0+j
*10.0)*M_PI
/180.0 );
194 glTexCoord2f( x
/(rect
.width())+0.5, 0.5 - z
/zTexture
* 0.5 );
195 glVertex3f( x
, yBottom
, z
);
196 x
= radius
* sin( bottomAngle
) * sin( (90.0+(j
+1)*10.0)*M_PI
/180.0 );
197 z
= radius
* sin( bottomAngle
) * cos( (90.0+(j
+1)*10.0)*M_PI
/180.0 );
199 glTexCoord2f( x
/(rect
.width())+0.5, 0.5 - z
/zTexture
* 0.5 );
200 glVertex3f( x
, yBottom
, z
);
201 x
= radius
* sin( topAngle
) * sin( (90.0+(j
+1)*10.0)*M_PI
/180.0 );
202 z
= radius
* sin( topAngle
) * cos( (90.0+(j
+1)*10.0)*M_PI
/180.0 );
204 glTexCoord2f( x
/(rect
.width())+0.5, 0.5 - z
/zTexture
* 0.5 );
205 glVertex3f( x
, yTop
, z
);
212 capTexture
->unbind();