Make a branch to make krunner Good Enough For Aaron™.
[kdebase/uwolfer.git] / workspace / kwin / lib / kwinshadereffect.cpp
blob743707488f4af8808a018c3fc6b904d85c716642
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>
26 #include <kdebug.h>
28 #include <assert.h>
31 namespace KWin
35 ShaderEffect::ShaderEffect(const QString& shadername) : Effect()
37 mTexture = 0;
38 mRenderTarget = 0;
39 mShader = 0;
41 mTime = 0.0f;
42 mValid = loadData(shadername);
43 mEnabled = false;
46 ShaderEffect::~ShaderEffect()
48 delete mTexture;
49 delete mRenderTarget;
50 delete mShader;
53 bool ShaderEffect::loadData(const QString& shadername)
55 #ifndef KWIN_HAVE_OPENGL_COMPOSITING
56 return false;
57 #else
58 // If NPOT textures are not supported, use nearest power-of-two sized
59 // texture. It wastes memory, but it's possible to support systems without
60 // NPOT textures that way
61 int texw = displayWidth();
62 int texh = displayHeight();
63 if( !GLTexture::NPOTTextureSupported() )
65 kWarning( 1212 ) << "NPOT textures not supported, wasting some memory" ;
66 texw = nearestPowerOfTwo(texw);
67 texh = nearestPowerOfTwo(texh);
69 // Create texture and render target
70 mTexture = new GLTexture(texw, texh);
71 mTexture->setFilter(GL_LINEAR_MIPMAP_LINEAR);
72 mTexture->setWrapMode(GL_CLAMP);
74 mRenderTarget = new GLRenderTarget(mTexture);
75 if( !mRenderTarget->valid() )
76 return false;
78 QString fragmentshader = KGlobal::dirs()->findResource("data", "kwin/" + shadername + ".frag");
79 QString vertexshader = KGlobal::dirs()->findResource("data", "kwin/" + shadername + ".vert");
80 if(fragmentshader.isEmpty() || vertexshader.isEmpty())
82 kError() << "Couldn't locate shader files" << endl;
83 return false;
85 mShader = new GLShader(vertexshader, fragmentshader);
86 if(!mShader->isValid())
88 kError() << "The shader failed to load!" << endl;
89 return false;
91 mShader->bind();
92 mShader->setUniform("sceneTex", 0);
93 mShader->setUniform("textureWidth", (float)texw);
94 mShader->setUniform("textureHeight", (float)texh);
95 mShader->unbind();
97 return true;
98 #endif
101 bool ShaderEffect::supported()
103 #ifndef KWIN_HAVE_OPENGL_COMPOSITING
104 return false;
105 #else
106 return GLRenderTarget::supported() &&
107 GLShader::fragmentShaderSupported() &&
108 (effects->compositingType() == OpenGLCompositing);
109 #endif
112 bool ShaderEffect::isEnabled() const
114 return mEnabled;
117 void ShaderEffect::setEnabled(bool enabled)
119 mEnabled = enabled;
120 // Everything needs to be repainted
121 effects->addRepaintFull();
124 GLShader* ShaderEffect::shader() const
126 return mShader;
129 void ShaderEffect::prePaintScreen( ScreenPrePaintData& data, int time )
131 mTime += time / 1000.0f;
132 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
133 if( mValid && mEnabled )
135 data.mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS;
136 // Start rendering to texture
137 effects->pushRenderTarget(mRenderTarget);
139 #endif
141 effects->prePaintScreen(data, time);
144 void ShaderEffect::postPaintScreen()
146 // Call the next effect.
147 effects->postPaintScreen();
149 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
150 if( mValid && mEnabled )
152 // Disable render texture
153 assert( effects->popRenderTarget() == mRenderTarget );
154 mTexture->bind();
156 // Use the shader
157 mShader->bind();
158 mShader->setUniform("time", (float)mTime);
159 mShader->setUniform("cursorX", (float)cursorPos().x());
160 mShader->setUniform("cursorY", (float)cursorPos().y());
162 // Render fullscreen quad with screen contents
163 glBegin(GL_QUADS);
164 glVertex2f(0.0, displayHeight());
165 glVertex2f(displayWidth(), displayHeight());
166 glVertex2f(displayWidth(), 0.0);
167 glVertex2f(0.0, 0.0);
168 glEnd();
170 mShader->unbind();
171 mTexture->unbind();
173 #endif
176 } // namespace