1 /********************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
5 Copyright (C) 2006-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 "kwinshadereffect.h"
23 #include "kwinglutils.h"
25 #include <kstandarddirs.h>
30 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
36 ShaderEffect::ShaderEffect(const QString
& shadername
) : Effect()
43 mValid
= loadData(shadername
);
47 ShaderEffect::~ShaderEffect()
54 bool ShaderEffect::loadData(const QString
& shadername
)
56 #ifndef KWIN_HAVE_OPENGL_COMPOSITING
59 // If NPOT textures are not supported, use nearest power-of-two sized
60 // texture. It wastes memory, but it's possible to support systems without
61 // NPOT textures that way
62 int texw
= displayWidth();
63 int texh
= displayHeight();
64 if( !GLTexture::NPOTTextureSupported() )
66 kWarning( 1212 ) << "NPOT textures not supported, wasting some memory" ;
67 texw
= nearestPowerOfTwo(texw
);
68 texh
= nearestPowerOfTwo(texh
);
70 // Create texture and render target
71 mTexture
= new GLTexture(texw
, texh
);
72 mTexture
->setFilter(GL_LINEAR_MIPMAP_LINEAR
);
73 mTexture
->setWrapMode(GL_CLAMP
);
75 mRenderTarget
= new GLRenderTarget(mTexture
);
76 if( !mRenderTarget
->valid() )
79 QString fragmentshader
= KGlobal::dirs()->findResource("data", "kwin/" + shadername
+ ".frag");
80 QString vertexshader
= KGlobal::dirs()->findResource("data", "kwin/" + shadername
+ ".vert");
81 if(fragmentshader
.isEmpty() || vertexshader
.isEmpty())
83 kError(1212) << "Couldn't locate shader files" << endl
;
86 mShader
= new GLShader(vertexshader
, fragmentshader
);
87 if(!mShader
->isValid())
89 kError(1212) << "The shader failed to load!" << endl
;
93 mShader
->setUniform("sceneTex", 0);
94 mShader
->setUniform("textureWidth", (float)texw
);
95 mShader
->setUniform("textureHeight", (float)texh
);
102 bool ShaderEffect::supported()
104 #ifndef KWIN_HAVE_OPENGL_COMPOSITING
107 return GLRenderTarget::supported() &&
108 GLShader::fragmentShaderSupported() &&
109 (effects
->compositingType() == OpenGLCompositing
);
113 bool ShaderEffect::isEnabled() const
118 void ShaderEffect::setEnabled(bool enabled
)
121 // Everything needs to be repainted
122 effects
->addRepaintFull();
125 GLShader
* ShaderEffect::shader() const
130 void ShaderEffect::prePaintScreen( ScreenPrePaintData
& data
, int time
)
132 mTime
+= time
/ 1000.0f
;
133 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
134 if( mValid
&& mEnabled
)
136 data
.mask
|= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS
;
137 // Start rendering to texture
138 effects
->pushRenderTarget(mRenderTarget
);
142 effects
->prePaintScreen(data
, time
);
145 void ShaderEffect::postPaintScreen()
147 // Call the next effect.
148 effects
->postPaintScreen();
150 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
151 if( mValid
&& mEnabled
)
153 // Disable render texture
154 assert( effects
->popRenderTarget() == mRenderTarget
);
159 mShader
->setUniform("time", (float)mTime
);
160 mShader
->setUniform("cursorX", (float)cursorPos().x());
161 mShader
->setUniform("cursorY", (float)cursorPos().y());
163 // Render fullscreen quad with screen contents
165 glVertex2f(0.0, displayHeight());
166 glVertex2f(displayWidth(), displayHeight());
167 glVertex2f(displayWidth(), 0.0);
168 glVertex2f(0.0, 0.0);