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>
35 ShaderEffect::ShaderEffect(const QString
& shadername
) : Effect()
42 mValid
= loadData(shadername
);
46 ShaderEffect::~ShaderEffect()
53 bool ShaderEffect::loadData(const QString
& shadername
)
55 #ifndef KWIN_HAVE_OPENGL_COMPOSITING
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() )
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
;
85 mShader
= new GLShader(vertexshader
, fragmentshader
);
86 if(!mShader
->isValid())
88 kError() << "The shader failed to load!" << endl
;
92 mShader
->setUniform("sceneTex", 0);
93 mShader
->setUniform("textureWidth", (float)texw
);
94 mShader
->setUniform("textureHeight", (float)texh
);
101 bool ShaderEffect::supported()
103 #ifndef KWIN_HAVE_OPENGL_COMPOSITING
106 return GLRenderTarget::supported() &&
107 GLShader::fragmentShaderSupported() &&
108 (effects
->compositingType() == OpenGLCompositing
);
112 bool ShaderEffect::isEnabled() const
117 void ShaderEffect::setEnabled(bool enabled
)
120 // Everything needs to be repainted
121 effects
->addRepaintFull();
124 GLShader
* ShaderEffect::shader() const
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
);
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
);
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
164 glVertex2f(0.0, displayHeight());
165 glVertex2f(displayWidth(), displayHeight());
166 glVertex2f(displayWidth(), 0.0);
167 glVertex2f(0.0, 0.0);