not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / kwin / lib / kwinshadereffect.cpp
blob9a079ab92b4cb3cb5956b9add03951532e6d6774
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>
30 #ifdef KWIN_HAVE_OPENGL_COMPOSITING
32 namespace KWin
36 ShaderEffect::ShaderEffect(const QString& shadername) : Effect()
38 mTexture = 0;
39 mRenderTarget = 0;
40 mShader = 0;
42 mTime = 0.0f;
43 mValid = loadData(shadername);
44 mEnabled = false;
47 ShaderEffect::~ShaderEffect()
49 delete mTexture;
50 delete mRenderTarget;
51 delete mShader;
54 bool ShaderEffect::loadData(const QString& shadername)
56 #ifndef KWIN_HAVE_OPENGL_COMPOSITING
57 return false;
58 #else
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() )
77 return false;
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;
84 return false;
86 mShader = new GLShader(vertexshader, fragmentshader);
87 if(!mShader->isValid())
89 kError(1212) << "The shader failed to load!" << endl;
90 return false;
92 mShader->bind();
93 mShader->setUniform("sceneTex", 0);
94 mShader->setUniform("textureWidth", (float)texw);
95 mShader->setUniform("textureHeight", (float)texh);
96 mShader->unbind();
98 return true;
99 #endif
102 bool ShaderEffect::supported()
104 #ifndef KWIN_HAVE_OPENGL_COMPOSITING
105 return false;
106 #else
107 return GLRenderTarget::supported() &&
108 GLShader::fragmentShaderSupported() &&
109 (effects->compositingType() == OpenGLCompositing);
110 #endif
113 bool ShaderEffect::isEnabled() const
115 return mEnabled;
118 void ShaderEffect::setEnabled(bool enabled)
120 mEnabled = enabled;
121 // Everything needs to be repainted
122 effects->addRepaintFull();
125 GLShader* ShaderEffect::shader() const
127 return mShader;
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);
140 #endif
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 );
155 mTexture->bind();
157 // Use the shader
158 mShader->bind();
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
164 glBegin(GL_QUADS);
165 glVertex2f(0.0, displayHeight());
166 glVertex2f(displayWidth(), displayHeight());
167 glVertex2f(displayWidth(), 0.0);
168 glVertex2f(0.0, 0.0);
169 glEnd();
171 mShader->unbind();
172 mTexture->unbind();
174 #endif
177 } // namespace
179 #endif