Option to snow behind windows and small performance improvement by using a glList

svn path=/trunk/KDE/kdebase/workspace/; revision=882720
icc-effect-5.14.5
Martin Gräßlin 2008-11-11 11:31:12 +00:00
parent 98b787c75b
commit 9f96d84a12
4 changed files with 73 additions and 35 deletions

View File

@ -49,6 +49,7 @@ SnowEffect::SnowEffect()
: texture( NULL )
, flakes( NULL )
, active( false)
, snowBehindWindows( false )
{
srandom( std::time( NULL ) );
lastFlakeTime = QTime::currentTime();
@ -75,6 +76,7 @@ void SnowEffect::reconfigure( ReconfigureFlags )
mMaxFlakeSize = conf.readEntry("MaxFlakes", 50);
mMaxVSpeed = conf.readEntry("MaxVSpeed", 2);
mMaxHSpeed = conf.readEntry("MaxHSpeed", 1);
snowBehindWindows = conf.readEntry("BehindWindows", false);
}
void SnowEffect::prePaintScreen( ScreenPrePaintData& data, int time )
@ -133,42 +135,48 @@ void SnowEffect::prePaintScreen( ScreenPrePaintData& data, int time )
void SnowEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
{
effects->paintScreen( mask, region, data ); // paint normal screen
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
if( active )
{
if(! texture ) loadTexture();
if( texture )
{
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT );
texture->bind();
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
if( active && !snowBehindWindows )
snowing( region );
}
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();
}
texture->unbind();
glPopAttrib();
void SnowEffect::snowing( QRegion& region )
{
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
if(! texture ) loadTexture();
if( texture )
{
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT );
texture->bind();
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
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();
}
glEndList();
glDisable( GL_BLEND );
texture->unbind();
glPopAttrib();
}
#endif
}
@ -182,10 +190,25 @@ void SnowEffect::postPaintScreen()
effects->postPaintScreen();
}
void SnowEffect::paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data )
{
effects->paintWindow( w, mask, region, data );
if( active && w->isDesktop() && snowBehindWindows )
snowing( region );
}
void SnowEffect::toggle()
{
active = !active;
if (!active) flakes->clear();
if( active )
{
list = glGenLists(1);
}
else
{
glDeleteLists( list, 1 );
flakes->clear();
}
effects->addRepaintFull();
}

View File

@ -71,11 +71,13 @@ class SnowEffect
virtual void prePaintScreen( ScreenPrePaintData& data, int time );
virtual void paintScreen( int mask, QRegion region, ScreenPaintData& data );
virtual void postPaintScreen();
virtual void paintWindow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
private slots:
void toggle();
private:
void loadTexture();
void snowing( QRegion& region );
GLTexture* texture;
QList<SnowFlake>* flakes;
QTime lastFlakeTime;
@ -86,6 +88,8 @@ class SnowEffect
int mMaxVSpeed;
int mMaxHSpeed;
bool active;
GLuint list;
bool snowBehindWindows;
};
} // namespace

View File

@ -56,6 +56,7 @@ SnowEffectConfig::SnowEffectConfig(QWidget* parent, const QVariantList& args) :
connect(m_ui->maxSizeFlake, SIGNAL(valueChanged(int)), this, SLOT(changed()));
connect(m_ui->maxVSpeed, SIGNAL(valueChanged(int)), this, SLOT(changed()));
connect(m_ui->maxHSpeed, SIGNAL(valueChanged(int)), this, SLOT(changed()));
connect(m_ui->snowBehindWindows, SIGNAL(stateChanged(int)), this, SLOT(changed()));
m_actionCollection = new KActionCollection( this, componentData() );
m_actionCollection->setConfigGroup("Snow");
@ -88,6 +89,7 @@ void SnowEffectConfig::load()
int maxFlake = conf.readEntry("MaxFlakes", 50);
int maxVSpeed = conf.readEntry("MaxVSpeed", 2);
int maxHSpeed = conf.readEntry("MaxHSpeed", 1);
m_ui->snowBehindWindows->setChecked( conf.readEntry("BehindWindows", false));
m_ui->numberFlakes->setValue( number );
m_ui->minSizeFlake->setValue( minFlake );
m_ui->maxSizeFlake->setValue( maxFlake );
@ -108,6 +110,7 @@ void SnowEffectConfig::save()
conf.writeEntry("MaxFlakes", m_ui->maxSizeFlake->value());
conf.writeEntry("MaxVSpeed", m_ui->maxVSpeed->value());
conf.writeEntry("MaxHSpeed", m_ui->maxHSpeed->value());
conf.writeEntry("BehindWindows", m_ui->snowBehindWindows->isChecked());
m_ui->editor->save(); // undo() will restore to this state from now on
@ -125,6 +128,7 @@ void SnowEffectConfig::defaults()
m_ui->maxSizeFlake->setValue( 50 );
m_ui->maxVSpeed->setValue( 2 );
m_ui->maxHSpeed->setValue( 1 );
m_ui->snowBehindWindows->setChecked( false );
m_ui->editor->allDefault();
emit changed(true);
}

View File

@ -179,6 +179,13 @@
</property>
</widget>
</item>
<item row="5" column="0" >
<widget class="QCheckBox" name="snowBehindWindows" >
<property name="text" >
<string>Snow &amp;behind windows</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>