Adding optional shader to snow effect. Shader is used when hardware support is available.
Using shader reduces CPU load from approximately 50 % to less than 20 % on my system. svn path=/trunk/KDE/kdebase/workspace/; revision=883348
This commit is contained in:
parent
5535a9de5e
commit
8ecaefebcc
5 changed files with 158 additions and 21 deletions
|
@ -166,6 +166,8 @@ if(KWIN_HAVE_OPENGL_COMPOSITING)
|
|||
data/lookingglass.frag
|
||||
data/lookingglass.vert
|
||||
data/shadow-texture.png
|
||||
data/snow.frag
|
||||
data/snow.vert
|
||||
data/snowflake.png
|
||||
data/circle.png
|
||||
data/circle-edgy.png
|
||||
|
|
25
effects/data/snow.frag
Normal file
25
effects/data/snow.frag
Normal file
|
@ -0,0 +1,25 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2008 Martin Gräßlin <ubuntu@martin-graesslin.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
uniform sampler2D snowTexture;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = texture2D( snowTexture, gl_TexCoord[0].st );
|
||||
}
|
31
effects/data/snow.vert
Normal file
31
effects/data/snow.vert
Normal file
|
@ -0,0 +1,31 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2008 Martin Gräßlin <ubuntu@martin-graesslin.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
attribute float angle;
|
||||
attribute float x;
|
||||
attribute float y;
|
||||
|
||||
void main()
|
||||
{
|
||||
float radian = radians(angle);
|
||||
mat2 rotation = mat2( cos(radian), sin(radian), -sin(radian), cos(radian) );
|
||||
vec2 vertex = (gl_Vertex.xy-vec2(x, y))*rotation+vec2(x, y);
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = gl_ModelViewProjectionMatrix * vec4(vertex, gl_Vertex.zw);
|
||||
}
|
117
effects/snow.cpp
117
effects/snow.cpp
|
@ -50,6 +50,9 @@ SnowEffect::SnowEffect()
|
|||
, flakes( NULL )
|
||||
, active( false)
|
||||
, snowBehindWindows( false )
|
||||
, mShader( 0 )
|
||||
, mInited( false )
|
||||
, mUseShader( true )
|
||||
{
|
||||
srandom( std::time( NULL ) );
|
||||
lastFlakeTime = QTime::currentTime();
|
||||
|
@ -66,6 +69,7 @@ SnowEffect::~SnowEffect()
|
|||
{
|
||||
delete texture;
|
||||
delete flakes;
|
||||
delete mShader;
|
||||
}
|
||||
|
||||
void SnowEffect::reconfigure( ReconfigureFlags )
|
||||
|
@ -145,35 +149,73 @@ void SnowEffect::snowing( QRegion& region )
|
|||
if(! texture ) loadTexture();
|
||||
if( texture )
|
||||
{
|
||||
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT );
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
texture->bind();
|
||||
if( mUseShader && !mInited )
|
||||
mUseShader = loadShader();
|
||||
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
glNewList( list, GL_COMPILE_AND_EXECUTE );
|
||||
if( mUseShader )
|
||||
{
|
||||
mShader->bind();
|
||||
glNewList( list, GL_COMPILE_AND_EXECUTE );
|
||||
glBegin( GL_QUADS );
|
||||
}
|
||||
else
|
||||
glNewList( list, GL_COMPILE_AND_EXECUTE );
|
||||
for (int i=0; i<flakes->count(); i++)
|
||||
{
|
||||
SnowFlake flake = flakes->at(i);
|
||||
|
||||
// save the matrix
|
||||
glPushMatrix();
|
||||
|
||||
// translate to the center of the flake
|
||||
glTranslatef(flake.getWidth()/2 + flake.getX(), flake.getHeight()/2 + flake.getY(), 0);
|
||||
|
||||
// rotate around the Z-axis
|
||||
glRotatef(flake.getRotationAngle(), 0.0, 0.0, 1.0);
|
||||
|
||||
// translate back to the starting point
|
||||
glTranslatef(-flake.getWidth()/2 - flake.getX(), -flake.getHeight()/2 - flake.getY(), 0);
|
||||
|
||||
// paint the snowflake
|
||||
texture->render( region, flake.getRect());
|
||||
|
||||
// restore the matrix
|
||||
glPopMatrix();
|
||||
if( snowBehindWindows && !region.contains( flake.getRect() ) )
|
||||
continue;
|
||||
|
||||
if( mUseShader )
|
||||
{
|
||||
// use shader
|
||||
mShader->setAttribute( "angle", flake.getRotationAngle() );
|
||||
mShader->setAttribute( "x", flake.getWidth()/2 + flake.getX() );
|
||||
mShader->setAttribute( "y", flake.getHeight()/2 + flake.getY() );
|
||||
glTexCoord2f( 0.0f, 0.0f );
|
||||
glVertex2i( flake.getRect().x(), flake.getRect().y() );
|
||||
glTexCoord2f( 1.0f, 0.0f );
|
||||
glVertex2i( flake.getRect().x()+flake.getRect().width(), flake.getRect().y() );
|
||||
glTexCoord2f( 1.0f, 1.0f );
|
||||
glVertex2i( flake.getRect().x()+flake.getRect().width(), flake.getRect().y()+flake.getRect().height() );
|
||||
glTexCoord2f( 0.0f, 1.0f );
|
||||
glVertex2i( flake.getRect().x(), flake.getRect().y()+flake.getRect().height() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// no shader
|
||||
// save the matrix
|
||||
glPushMatrix();
|
||||
|
||||
// translate to the center of the flake
|
||||
glTranslatef(flake.getWidth()/2 + flake.getX(), flake.getHeight()/2 + flake.getY(), 0);
|
||||
|
||||
// rotate around the Z-axis
|
||||
glRotatef(flake.getRotationAngle(), 0.0, 0.0, 1.0);
|
||||
|
||||
// translate back to the starting point
|
||||
glTranslatef(-flake.getWidth()/2 - flake.getX(), -flake.getHeight()/2 - flake.getY(), 0);
|
||||
|
||||
// paint the snowflake
|
||||
texture->render( region, flake.getRect());
|
||||
|
||||
// restore the matrix
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
glEndList();
|
||||
if( mUseShader )
|
||||
{
|
||||
glEnd();
|
||||
glEndList();
|
||||
mShader->unbind();
|
||||
}
|
||||
else
|
||||
glEndList();
|
||||
glDisable( GL_BLEND );
|
||||
texture->unbind();
|
||||
glPopAttrib();
|
||||
|
@ -212,6 +254,39 @@ void SnowEffect::toggle()
|
|||
effects->addRepaintFull();
|
||||
}
|
||||
|
||||
bool SnowEffect::loadShader()
|
||||
{
|
||||
mInited = true;
|
||||
if( !(GLShader::fragmentShaderSupported() &&
|
||||
(effects->compositingType() == OpenGLCompositing)) )
|
||||
{
|
||||
kDebug() << "Shaders not supported - waisting CPU cycles" << endl;
|
||||
return false;
|
||||
}
|
||||
QString fragmentshader = KGlobal::dirs()->findResource("data", "kwin/snow.frag");
|
||||
QString vertexshader = KGlobal::dirs()->findResource("data", "kwin/snow.vert");
|
||||
if(fragmentshader.isEmpty() || vertexshader.isEmpty())
|
||||
{
|
||||
kDebug() << "Couldn't locate shader files" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
mShader = new GLShader(vertexshader, fragmentshader);
|
||||
if(!mShader->isValid())
|
||||
{
|
||||
kDebug() << "The shader failed to load!" << endl;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mShader->bind();
|
||||
mShader->setUniform( "snowTexture", 0 );
|
||||
mShader->unbind();
|
||||
}
|
||||
kDebug() << "using shader";
|
||||
return true;
|
||||
}
|
||||
|
||||
void SnowEffect::loadTexture()
|
||||
{
|
||||
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||
|
|
|
@ -78,6 +78,7 @@ class SnowEffect
|
|||
private:
|
||||
void loadTexture();
|
||||
void snowing( QRegion& region );
|
||||
bool loadShader();
|
||||
GLTexture* texture;
|
||||
QList<SnowFlake>* flakes;
|
||||
QTime lastFlakeTime;
|
||||
|
@ -90,6 +91,9 @@ class SnowEffect
|
|||
bool active;
|
||||
GLuint list;
|
||||
bool snowBehindWindows;
|
||||
GLShader* mShader;
|
||||
bool mInited;
|
||||
bool mUseShader;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
Loading…
Reference in a new issue