1 /********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
5 Copyright (C) 2007 Rivo Laks <rivolaks@hot.ee>
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 *********************************************************************/
21 #include "explosioneffect.h"
23 #include <kwinglutils.h>
26 #include <KStandardDirs>
35 KWIN_EFFECT( explosion
, ExplosionEffect
)
36 KWIN_EFFECT_SUPPORTED( explosion
, ExplosionEffect::supported() )
38 ExplosionEffect::ExplosionEffect() : Effect()
44 mActiveAnimations
= 0;
49 ExplosionEffect::~ExplosionEffect()
52 delete mStartOffsetTex
;
56 bool ExplosionEffect::supported()
58 return GLShader::fragmentShaderSupported() &&
59 (effects
->compositingType() == OpenGLCompositing
);
62 bool ExplosionEffect::loadData()
65 QString
shadername("explosion");
66 QString fragmentshader
= KGlobal::dirs()->findResource("data", "kwin/explosion.frag");
67 QString vertexshader
= KGlobal::dirs()->findResource("data", "kwin/explosion.vert");
68 QString starttexture
= KGlobal::dirs()->findResource("data", "kwin/explosion-start.png");
69 QString endtexture
= KGlobal::dirs()->findResource("data", "kwin/explosion-end.png");
70 if(fragmentshader
.isEmpty() || vertexshader
.isEmpty())
72 kError(1212) << "Couldn't locate shader files" << endl
;
75 if(starttexture
.isEmpty() || endtexture
.isEmpty())
77 kError(1212) << "Couldn't locate texture 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("startOffsetTexture", 4);
92 mShader
->setUniform("endOffsetTexture", 5);
96 mStartOffsetTex
= new GLTexture(starttexture
);
97 mEndOffsetTex
= new GLTexture(endtexture
);
98 if(mStartOffsetTex
->isNull() || mEndOffsetTex
->isNull())
100 kError(1212) << "The textures failed to load!" << endl
;
105 mStartOffsetTex
->setFilter( GL_LINEAR
);
106 mEndOffsetTex
->setFilter( GL_LINEAR
);
112 void ExplosionEffect::prePaintScreen( ScreenPrePaintData
& data
, int time
)
114 if( mActiveAnimations
> 0 )
115 // We need to mark the screen as transformed. Otherwise the whole screen
116 // won't be repainted, resulting in artefacts
117 data
.mask
|= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS
;
119 effects
->prePaintScreen(data
, time
);
122 void ExplosionEffect::prePaintWindow( EffectWindow
* w
, WindowPrePaintData
& data
, int time
)
124 if( mWindows
.contains( w
))
126 if( mValid
&& !mInited
)
130 mWindows
[ w
] += time
/ animationTime( 700.0 ); // complete change in 700ms
131 if( mWindows
[ w
] < 1 )
133 data
.setTranslucent();
134 data
.setTransformed();
135 w
->enablePainting( EffectWindow::PAINT_DISABLED_BY_DELETE
);
139 mWindows
.remove( w
);
146 effects
->prePaintWindow( w
, data
, time
);
149 void ExplosionEffect::paintWindow( EffectWindow
* w
, int mask
, QRegion region
, WindowPaintData
& data
)
151 // Make sure we have OpenGL compositing and the window is vidible and not a
153 bool useshader
= ( mValid
&& mWindows
.contains( w
) );
156 double maxscaleadd
= 1.5f
;
157 double scale
= 1 + maxscaleadd
*mWindows
[w
];
160 data
.xTranslate
+= int( w
->width() / 2 * ( 1 - scale
));
161 data
.yTranslate
+= int( w
->height() / 2 * ( 1 - scale
));
162 data
.opacity
*= 0.99; // Force blending
164 mShader
->setUniform("factor", (float)mWindows
[w
]);
165 mShader
->setUniform("scale", (float)scale
);
166 glActiveTexture(GL_TEXTURE4
);
167 mStartOffsetTex
->bind();
168 glActiveTexture(GL_TEXTURE5
);
169 mEndOffsetTex
->bind();
170 glActiveTexture(GL_TEXTURE0
);
171 data
.shader
= mShader
;
174 // Call the next effect.
175 effects
->paintWindow( w
, mask
, region
, data
);
180 glActiveTexture(GL_TEXTURE4
);
181 mStartOffsetTex
->unbind();
182 glActiveTexture(GL_TEXTURE5
);
183 mEndOffsetTex
->unbind();
184 glActiveTexture(GL_TEXTURE0
);
188 void ExplosionEffect::postPaintScreen()
190 if( mActiveAnimations
> 0 )
191 effects
->addRepaintFull();
193 // Call the next effect.
194 effects
->postPaintScreen();
197 void ExplosionEffect::windowClosed( EffectWindow
* c
)
199 if( c
->isOnCurrentDesktop() && !c
->isMinimized())
201 mWindows
[ c
] = 0; // count up to 1
208 void ExplosionEffect::windowDeleted( EffectWindow
* c
)
210 mWindows
.remove( c
);