diff options
Diffstat (limited to 'kscreensaver/kdesavers/fountain.cpp')
-rw-r--r-- | kscreensaver/kdesavers/fountain.cpp | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/kscreensaver/kdesavers/fountain.cpp b/kscreensaver/kdesavers/fountain.cpp new file mode 100644 index 00000000..51d88343 --- /dev/null +++ b/kscreensaver/kdesavers/fountain.cpp @@ -0,0 +1,461 @@ +//----------------------------------------------------------------------------- +// +// kfountain - Partical Fountain Screen Saver for KDE 2 +// +// Copyright (c) Ian Reinhart Geiser 2001 +// +// KConfig code and KScreenSaver "Setup..." improvements by +// Nick Betcher <nbetcher@usinternet.com> 2001 +// +#include <stdlib.h> +#include <qlabel.h> +#include <qlayout.h> +#include <kapplication.h> +#include <klocale.h> +#include <kconfig.h> +#include <kcolordialog.h> +#include <kbuttonbox.h> +#include <kcolorbutton.h> +#include <kglobal.h> +#include "fountain.h" +#include "fountain.moc" +#ifdef Q_WS_MACX +#include <OpenGL/gl.h> +#include <OpenGL/glu.h> +#else +#include <GL/glu.h> +#include <GL/gl.h> +#endif +#include <qimage.h> +#include <kdebug.h> +#include <qpainter.h> +#include <qradiobutton.h> +#include <qspinbox.h> +#include <kstandarddirs.h> +#include <math.h> +#include <kmessagebox.h> +// libkscreensaver interface +extern "C" +{ + KDE_EXPORT const char *kss_applicationName = "kfountain.kss"; + KDE_EXPORT const char *kss_description = I18N_NOOP( "Particle Fountain Screen Saver" ); + KDE_EXPORT const char *kss_version = "2.2.0"; + + KDE_EXPORT KScreenSaver *kss_create( WId id ) + { + return new KFountainSaver( id ); + } + + KDE_EXPORT QDialog *kss_setup() + { + return new KFountainSetup(); + } +} + +//----------------------------------------------------------------------------- +// dialog to setup screen saver parameters +// +KFountainSetup::KFountainSetup( QWidget *parent, const char *name ) + : SetupUi( parent, name, TRUE ) +{ + readSettings(); + + //QLabel *label; + //QPushButton *button; + + //setCaption( i18n("Setup Particle Fountain") ); + + //QVBoxLayout *tl = new QVBoxLayout(this, 10); + //QHBoxLayout *tl1 = new QHBoxLayout; + //tl->addLayout(tl1); + + //QVBoxLayout *tl11 = new QVBoxLayout(5); + //tl1->addLayout(tl11); + + //label = new QLabel( i18n("No options here yet...:"), this ); + ///tl11->addWidget(label);; + + //preview = new QWidget( this ); + preview->setFixedSize( 220, 170 ); + preview->setBackgroundColor( black ); + preview->show(); // otherwise saver does not get correct size + saver = new KFountainSaver( preview->winId() ); + //tl1->addWidget(preview); + + //KButtonBox *bbox = new KButtonBox(this); + //bbox->addStretch(1); +; + connect( PushButton1, SIGNAL( clicked() ), SLOT( slotOkPressed() ) ); + connect( PushButton2, SIGNAL( clicked() ), SLOT( reject() ) ); + connect( PushButton3, SIGNAL( clicked() ), SLOT( aboutPressed() ) ); + connect( SpinBox1, SIGNAL( valueChanged(int)), saver, SLOT( updateSize(int))); + connect( RadioButton1, SIGNAL( toggled(bool)), saver, SLOT( doStars(bool))); + +} + +// read settings from config file +void KFountainSetup::readSettings() +{ + KConfig config("kssfountainrc", false, false); + + config.setGroup( "Settings" ); + QString boolval = config.readEntry( "Stars", "false" ); + if (boolval == "true") { + RadioButton1->setDown(true); + RadioButton1_2->setDown(false); + } else { + if (boolval == "false") + { + RadioButton1->setDown(false); + RadioButton1_2->setDown(true); + } + } + + QString starammount = config.readEntry("StarSize", "75"); + SpinBox1->setValue(starammount.toInt()); + +} + +// Ok pressed - save settings and exit +void KFountainSetup::slotOkPressed() +{ + KConfig config("kssfountainrc", false, false); + config.setGroup( "Settings" ); + + if (RadioButton1->isOn() == true) + { + config.writeEntry( "Stars", "true" ); + } else { + if (RadioButton1_2->isOn() == true) + { + config.writeEntry( "Stars", "false" ); + } + } + config.writeEntry( "StarSize", QString::number(SpinBox1->value()) ); + + config.sync(); + + accept(); +} + +void KFountainSetup::aboutPressed() +{ + KMessageBox::about(this, + i18n("<h3>Particle Fountain</h3>\n<p>Particle Fountain Screen Saver for KDE</p>\nCopyright (c) Ian Reinhart Geiser 2001<br>\n\n<p>KConfig code and KScreenSaver \"Setup...\" improvements by Nick Betcher <nbetcher@usinternet.com> 2001</p>")); +} +//----------------------------------------------------------------------------- + + +KFountainSaver::KFountainSaver( WId id ) : KScreenSaver( id ) +{ + + kdDebug() << "Blank" << endl; + + timer = new QTimer( this ); + timer->start( 25, TRUE ); + setBackgroundColor( black ); + erase(); + fountain = new Fountain(); + embed(fountain); + fountain->show(); + connect( timer, SIGNAL(timeout()), this, SLOT(blank()) ); +} + +KFountainSaver::~KFountainSaver() +{ + +} + +// read configuration settings from config file +void KFountainSaver::readSettings() +{ +// Please remove me + +} + +void KFountainSaver::blank() +{ + // Play fountain + + fountain->updateGL(); + timer->start( 25, TRUE ); + +} +Fountain::Fountain( QWidget * parent, const char * name) : QGLWidget (parent,name) +{ + rainbow=true; + slowdown=2.0f; + zoom=-40.0f; + index=0; + size = 0.75f; + obj = gluNewQuadric(); + +// This has to be here because you can't update the fountain until 'fountain' is created! + KConfig config("kssfountainrc", false, false); + config.setGroup( "Settings" ); + QString boolval = config.readEntry( "Stars", "false" ); + if (boolval == "true") { + setStars(true); + } else { + if (boolval == "false") + { + setStars(false); + } + } + + QString starammount = config.readEntry("StarSize", "75"); + float passvalue = (starammount.toInt() / 100.0); + setSize(passvalue); + +} + +Fountain::~Fountain() +{ + glDeleteTextures( 1, &texture[0] ); + gluDeleteQuadric(obj); +} + +/** load the particle file */ +bool Fountain::loadParticle() +{ + /* Status indicator */ + bool Status = TRUE; + QImage buf; + + kdDebug() << "Loading: " << locate("data", "kscreensaver/particle.png") << endl; + if (buf.load( locate("data", "kscreensaver/particle.png") ) ) + + { + tex = convertToGLFormat(buf); // flipped 32bit RGBA + kdDebug() << "Texture loaded: " << tex.numBytes () << endl; + } + else + { + QImage dummy( 32, 32, 32 ); + dummy.fill( Qt::white.rgb() ); + buf = dummy; + tex = convertToGLFormat( buf ); + } + + /* Set the status to true */ + //Status = TRUE; + glGenTextures(1, &texture[0]); /* create three textures */ + glBindTexture(GL_TEXTURE_2D, texture[0]); + /* use linear filtering */ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + /* actually generate the texture */ + glTexImage2D(GL_TEXTURE_2D, 0, 4, tex.width(), tex.height(), 0, + GL_RGBA, GL_UNSIGNED_BYTE, tex.bits()); + + + + return Status; +} +/** setup the GL enviroment */ +void Fountain::initializeGL () +{ + + kdDebug() << "InitGL" << endl; + GLfloat colors[12][3]= + {{1.0f,0.5f,0.5f},{1.0f,0.75f,0.5f},{1.0f,1.0f,0.5f},{0.75f,1.0f,0.5f}, + {0.5f,1.0f,0.5f},{0.5f,1.0f,0.75f},{0.5f,1.0f,1.0f},{0.5f,0.75f,1.0f}, + {0.5f,0.5f,1.0f},{0.75f,0.5f,1.0f},{1.0f,0.5f,1.0f},{1.0f,0.5f,0.75f}}; + + if (loadParticle()) // Jump To Texture Loading Routine + { + /* Enable smooth shading */ + glShadeModel( GL_SMOOTH ); + + /* Set the background black */ + glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); + + /* Depth buffer setup */ + glClearDepth( 1.0f ); + + /* Enables Depth Testing */ + glDisable( GL_DEPTH_TEST ); + + /* Enable Blending */ + glEnable( GL_BLEND ); + /* Type Of Blending To Perform */ + glBlendFunc( GL_SRC_ALPHA, GL_ONE ); + + + /* Really Nice Perspective Calculations */ + glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); + /* Really Nice Point Smoothing */ + glHint( GL_POINT_SMOOTH_HINT, GL_NICEST ); + + /* Enable Texture Mapping */ + glEnable( GL_TEXTURE_2D ); + /* Select Our Texture */ + glBindTexture( GL_TEXTURE_2D, texture[0] ); + + for (loop=0;loop<MAX_PARTICLES;loop++) // Initials All The Textures + { + particle[loop].active=true; // Make All The Particles Active + particle[loop].life=1.0f; // Give All The Particles Full Life + particle[loop].fade=float(KApplication::random()%100)/1000.0f+0.003f; // Random Fade Speed + particle[loop].r=colors[(loop+1)/(MAX_PARTICLES/12)][0]; // Select Red Rainbow Color + particle[loop].g=colors[(loop+1)/(MAX_PARTICLES/12)][1]; // Select Green Rainbow Color + particle[loop].b=colors[(loop+1)/(MAX_PARTICLES/12)][2]; // Select Blue Rainbow Color + particle[loop].xi=float((KApplication::random()%50)-26.0f)*10.0f; // Random Speed On X Axis + particle[loop].yi=float((KApplication::random()%50)-25.0f)*10.0f; // Random Speed On Y Axis + particle[loop].zi=float((KApplication::random()%50)-25.0f)*10.0f; // Random Speed On Z Axis + particle[loop].xg=0.0f; // Set Horizontal Pull To Zero + particle[loop].yg=-0.8f; // Set Vertical Pull Downward + particle[loop].zg=0.0f; // Set Pull On Z Axis To Zero + particle[loop].size=size; // Set particle size. + } + } + else + exit(0); +} +/** resize the gl view */ +void Fountain::resizeGL ( int width, int height ) +{ + kdDebug() << "ResizeGL " << width << "," <<height<< endl; + if (height==0) // Prevent A Divide By Zero By + { + height=1; // Making Height Equal One + } + + glViewport(0,0,width,height); // Reset The Current Viewport + + glMatrixMode(GL_PROJECTION); // Select The Projection Matrix + glLoadIdentity(); // Reset The Projection Matrix + + // Calculate The Aspect Ratio Of The Window + gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,200.0f); + + glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix + glLoadIdentity(); +} +/** paint the GL view */ +void Fountain::paintGL () +{ + //kdDebug() << "PaintGL" << endl; + + GLfloat colors[12][3]= + {{1.0f,0.5f,0.5f},{1.0f,0.75f,0.5f},{1.0f,1.0f,0.5f},{0.75f,1.0f,0.5f}, + {0.5f,1.0f,0.5f},{0.5f,1.0f,0.75f},{0.5f,1.0f,1.0f},{0.5f,0.75f,1.0f}, + {0.5f,0.5f,1.0f},{0.75f,0.5f,1.0f},{1.0f,0.5f,1.0f},{1.0f,0.5f,0.75f}}; + col = ( ++col ) % 12; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer + + glLoadIdentity(); + // Reset The ModelView Matrix + transIndex++; + glTranslatef( GLfloat(5.0*sin(4*3.14*transIndex/360)), GLfloat(4.0*cos(2*3.14*transIndex/360)), 0.0 ); + xspeed = GLfloat(100.0*cos(3*3.14*transIndex/360)+100); + yspeed = GLfloat(100.0*sin(3*3.14*transIndex/360)+100); + //slowdown = GLfloat(4.0*sin(2*3.14*transIndex/360)+4.01); + + for (loop=0;loop<MAX_PARTICLES;loop++) // Loop Through All The Particles + { + if (particle[loop].active) // If The Particle Is Active + { + float x=particle[loop].x; // Grab Our Particle X Position + float y=particle[loop].y; // Grab Our Particle Y Position + float z=particle[loop].z+zoom; // Particle Z Pos + Zoom + /* Select Our Texture */ + + /* Draw The Particle Using Our RGB Values, + * Fade The Particle Based On It's Life + */ + + glColor4f( particle[loop].r, + particle[loop].g, + particle[loop].b, + particle[loop].life ); + + /* Build Quad From A Triangle Strip */ + if( !stars ) + glBegin( GL_TRIANGLE_STRIP ); + else + glBegin( GL_TRIANGLE_FAN ); + /* Top Right */ + glTexCoord2d( 1, 1 ); + glVertex3f( x + particle[loop].size, y + particle[loop].size, z ); + /* Top Left */ + glTexCoord2d( 0, 1 ); + glVertex3f( x - particle[loop].size, y + particle[loop].size, z ); + /* Bottom Right */ + glTexCoord2d( 1, 0 ); + glVertex3f( x + particle[loop].size, y - particle[loop].size, z ); + /* Bottom Left */ + glTexCoord2d( 0, 0 ); + glVertex3f( x - particle[loop].size, y - particle[loop].size, z ); + glEnd( ); + + particle[loop].x+=particle[loop].xi/(slowdown*1000);// Move On The X Axis By X Speed + particle[loop].y+=particle[loop].yi/(slowdown*1000);// Move On The Y Axis By Y Speed + particle[loop].z+=particle[loop].zi/(slowdown*1000);// Move On The Z Axis By Z Speed + + particle[loop].xi+=particle[loop].xg; // Take Pull On X Axis Into Account + particle[loop].yi+=particle[loop].yg; // Take Pull On Y Axis Into Account + particle[loop].zi+=particle[loop].zg; // Take Pull On Z Axis Into Account + particle[loop].life-=particle[loop].fade; // Reduce Particles Life By 'Fade' + + if (particle[loop].life<0.0f) // If Particle Is Burned Out + { + particle[loop].life=2.0f; // Give It New Life + particle[loop].fade=float(KApplication::random()%100)/1000.0f+0.003f; // Random Fade Value + particle[loop].x=0.0f; // Center On X Axis + particle[loop].y=0.0f; // Center On Y Axis + particle[loop].z=0.0f; // Center On Z Axis + particle[loop].xi=xspeed+float((KApplication::random()%60)-32.0f); // X Axis Speed And Direction + particle[loop].yi=yspeed+float((KApplication::random()%60)-30.0f); // Y Axis Speed And Direction + particle[loop].zi=float((KApplication::random()%60)-30.0f); // Z Axis Speed And Direction + particle[loop].r=colors[col][0]; // Select Red From Color Table + particle[loop].g=colors[col][1]; // Select Green From Color Table + particle[loop].b=colors[col][2]; // Select Blue From Color Table + particle[loop].size=size; + if ((1+(random()%20)) == 10) + { + // Explode + particle[loop].active=true; // Make All The Particles Active + particle[loop].life=1.0f; // Give All The Particles Full Life + particle[loop].fade=float(KApplication::random()%100)/1000.0f+0.003f; // Random Fade Speed + particle[loop].r=colors[(loop+1)/(MAX_PARTICLES/12)][0]; // Select Red Rainbow Color + particle[loop].g=colors[(loop+1)/(MAX_PARTICLES/12)][1]; // Select Green Rainbow Color + particle[loop].b=colors[(loop+1)/(MAX_PARTICLES/12)][2]; // Select Blue Rainbow Color + particle[loop].xi=float((KApplication::random()%50)-26.0f)*10.0f; // Random Speed On X Axis + particle[loop].yi=float((KApplication::random()%50)-25.0f)*10.0f; // Random Speed On Y Axis + particle[loop].zi=float((KApplication::random()%50)-25.0f)*10.0f; // Random Speed On Z Axis + particle[loop].xg=0.0f; // Set Horizontal Pull To Zero + particle[loop].yg=-0.8f; // Set Vertical Pull Downward + particle[loop].zg=0.0f; // Set Pull On Z Axis To Zero + particle[loop].size=size; // Set particle size. + } + } + // Lets stir some things up + index += 0.001; + particle[loop].yg =2.0*sin(2*3.14*transIndex/360); + particle[loop].xg =2.0*cos(2*3.14*transIndex/360); + particle[loop].zg =4.0+(4.0*cos(2*3.14*transIndex/360)); + + } + } + + glFlush(); +} +void Fountain::setSize( float newSize ) +{ + size = newSize; +} +void Fountain::setStars( bool doStars ) +{ + stars = doStars; +} + +void KFountainSaver::updateSize(int newSize) +{ + fountain->setSize(newSize/100); +} +void KFountainSaver::doStars(bool starState) +{ + fountain->setStars(starState); +} + |