1 //-----------------------------------------------------------------------------
3 // kgravity - Partical Gravity Screen Saver for KDE 2
5 // Copyright (c) Ian Reinhart Geiser 2001
7 // KConfig code and KScreenSaver "Setup..." improvements by
8 // Nick Betcher <nbetcher@usinternet.com> 2001
13 #include <kapplication.h>
16 #include <kcolordialog.h>
17 #include <kbuttonbox.h>
18 #include <kcolorbutton.h>
20 #include "gravity.moc"
22 #include <OpenGL/glu.h>
23 #include <OpenGL/gl.h>
31 #include <qradiobutton.h>
33 #include <kstandarddirs.h>
35 #include <kmessagebox.h>
37 // libkscreensaver interface
38 class KGravitySaverInterface
: public KScreenSaverInterface
43 virtual KAboutData
* aboutData() {
44 return new KAboutData( "kgravity.kss", I18N_NOOP( "Particle Gravity Screen Saver" ), "2.2.0", I18N_NOOP( "Particle Gravity Screen Saver" ) );
48 virtual KScreenSaver
* create( WId id
)
50 return new KGravitySaver( id
);
53 virtual QDialog
* setup()
55 return new KGravitySetup();
59 int main( int argc
, char *argv
[] )
61 KGravitySaverInterface kss
;
62 return kScreenSaverMain( argc
, argv
, kss
);
65 //-----------------------------------------------------------------------------
66 // dialog to setup screen saver parameters
68 KGravitySetup::KGravitySetup( QWidget
*parent
, const char *name
)
69 : SetupUi( parent
, name
, TRUE
)
73 preview
->setFixedSize( 220, 170 );
74 preview
->setBackgroundColor( Qt::black
);
76 preview
->show(); // otherwise saver does not get correct size
78 saver
= new KGravitySaver( preview
->winId() );
80 connect( PushButton1
, SIGNAL( clicked() ), SLOT( slotOkPressed() ) );
81 connect( PushButton2
, SIGNAL( clicked() ), SLOT( reject() ) );
82 connect( PushButton3
, SIGNAL( clicked() ), SLOT( aboutPressed() ) );
83 connect( SpinBox1
, SIGNAL( valueChanged(int)), saver
, SLOT( updateSize(int)));
84 connect( RadioButton1
, SIGNAL( toggled(bool)), saver
, SLOT( doStars(bool)));
88 KGravitySetup::~KGravitySetup()
93 // read settings from config file
94 void KGravitySetup::readSettings()
96 KConfig
config("kssgravityrc", false, false);
98 config
.setGroup( "Settings" );
99 QString boolval
= config
.readEntry( "Stars", "false" );
100 if (boolval
== "true") {
101 RadioButton1
->setDown(true);
102 RadioButton1_2
->setDown(false);
104 if (boolval
== "false")
106 RadioButton1
->setDown(false);
107 RadioButton1_2
->setDown(true);
111 QString starammount
= config
.readEntry("StarSize", "75");
112 SpinBox1
->setValue(starammount
.toInt());
116 // Ok pressed - save settings and exit
117 void KGravitySetup::slotOkPressed()
119 KConfig
config("kssgravityrc", false, false);
120 config
.setGroup( "Settings" );
122 if (RadioButton1
->isOn() == true)
124 config
.writeEntry( "Stars", "true" );
126 if (RadioButton1_2
->isOn() == true)
128 config
.writeEntry( "Stars", "false" );
131 config
.writeEntry( "StarSize", QString::number(SpinBox1
->value()) );
138 void KGravitySetup::aboutPressed()
140 KMessageBox::about(this,
141 i18n("<h3>Gravity</h3>\n<p>Particle Gravity 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>"));
143 //-----------------------------------------------------------------------------
146 KGravitySaver::KGravitySaver( WId id
) : KScreenSaver( id
)
149 kDebug() << "Blank" << endl
;
151 timer
= new QTimer( this );
152 timer
->start( 25, TRUE
);
153 setBackgroundColor( Qt::black
);
155 gravity
= new Gravity();
160 connect( timer
, SIGNAL(timeout()), this, SLOT(blank()) );
163 KGravitySaver::~KGravitySaver()
168 // read configuration settings from config file
169 void KGravitySaver::readSettings()
175 void KGravitySaver::blank()
180 timer
->start( 25, TRUE
);
183 Gravity::Gravity( QWidget
* parent
, const char * name
) : QGLWidget (parent
,name
)
190 // obj = gluNewQuadric();
192 // This has to be here because you can't update the gravity until 'gravity' is created!
193 KConfig
config("kssgravityrc", false, false);
194 config
.setGroup( "Settings" );
195 QString boolval
= config
.readEntry( "Stars", "false" );
196 if (boolval
== "true") {
199 if (boolval
== "false")
205 QString starammount
= config
.readEntry("StarSize", "75");
206 float passvalue
= (starammount
.toInt() / 100.0);
213 glDeleteTextures( 1, &texture
[0] );
214 gluDeleteQuadric(obj
);
217 /** load the particle file */
218 bool Gravity::loadParticle()
220 /* Status indicator */
224 kDebug() << "Loading: " << KStandardDirs::locate("data", "kscreensaver/particle.png") << endl
;
225 if (buf
.load( KStandardDirs::locate("data", "kscreensaver/particle.png") ) )
228 tex
= convertToGLFormat(buf
); // flipped 32bit RGBA
229 kDebug() << "Texture loaded: " << tex
.numBytes () << endl
;
233 QImage
dummy( 32, 32, 32 );
234 dummy
.fill( Qt::white
);
236 tex
= convertToGLFormat( buf
);
239 /* Set the status to true */
241 glGenTextures(1, &texture
[0]); /* create three textures */
242 glBindTexture(GL_TEXTURE_2D
, texture
[0]);
243 /* use linear filtering */
244 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
245 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
246 /* actually generate the texture */
247 glTexImage2D(GL_TEXTURE_2D
, 0, 4, tex
.width(), tex
.height(), 0,
248 GL_RGBA
, GL_UNSIGNED_BYTE
, tex
.bits());
254 /** setup the GL enviroment */
255 void Gravity::initializeGL ()
258 kDebug() << "InitGL" << endl
;
260 if (loadParticle()) // Jump To Texture Loading Routine
262 /* Enable smooth shading */
263 glShadeModel( GL_SMOOTH
);
265 /* Set the background black */
266 glClearColor( 0.0f
, 0.0f
, 0.0f
, 0.0f
);
268 /* Depth buffer setup */
269 glClearDepth( 1.0f
);
271 /* Enables Depth Testing */
272 glDisable( GL_DEPTH_TEST
);
274 /* Enable Blending */
275 glEnable( GL_BLEND
);
276 /* Type Of Blending To Perform */
277 glBlendFunc( GL_SRC_ALPHA
, GL_ONE
);
280 /* Really Nice Perspective Calculations */
281 glHint( GL_PERSPECTIVE_CORRECTION_HINT
, GL_NICEST
);
282 /* Really Nice Point Smoothing */
283 glHint( GL_POINT_SMOOTH_HINT
, GL_NICEST
);
285 /* Enable Texture Mapping */
286 glEnable( GL_TEXTURE_2D
);
287 /* Select Our Texture */
288 glBindTexture( GL_TEXTURE_2D
, texture
[0] );
290 for (loop
=0;loop
<MAX_PARTICLES
;loop
++) // Initials All The Textures
298 /** resize the gl view */
299 void Gravity::resizeGL ( int width
, int height
)
301 kDebug() << "ResizeGL " << width
<< "," <<height
<< endl
;
302 if (height
==0) // Prevent A Divide By Zero By
304 height
=1; // Making Height Equal One
307 glViewport(0,0,width
,height
); // Reset The Current Viewport
309 glMatrixMode(GL_PROJECTION
); // Select The Projection Matrix
310 glLoadIdentity(); // Reset The Projection Matrix
312 // Calculate The Aspect Ratio Of The Window
313 gluPerspective(45.0f
,(GLfloat
)width
/(GLfloat
)height
,0.1f
,100.0f
);
315 glMatrixMode(GL_MODELVIEW
); // Select The Modelview Matrix
318 /** paint the GL view */
319 void Gravity::paintGL ()
321 //kDebug() << "PaintGL" << endl;
322 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
); // Clear Screen And Depth Buffer
324 // Reset The ModelView Matrix
326 //glRotatef(transIndex, 1,0,0);
327 //glRotatef(transIndex, 0,1,0);
328 //glRotatef(transIndex, 0,0,1);
331 glTranslatef( GLfloat(xmax
*sin(3.14*transIndex
/360)-xmax
),
332 GLfloat(ymax
*cos(3.14*transIndex
/360)-ymax
),
334 //glRotatef(transIndex, 0,GLfloat(zmax*cos(3.14*transIndex/360000)), GLfloat(zmax*cos(3.14*transIndex/360000)));
336 for (loop
=0;loop
<MAX_PARTICLES
;loop
++) // Loop Through All The Particles
338 if (particle
[loop
].active
) // If The Particle Is Active
340 float x
=particle
[loop
].x
; // Grab Our Particle X Position
341 float y
=particle
[loop
].y
; // Grab Our Particle Y Position
342 float z
=particle
[loop
].z
+zoom
; // Particle Z Pos + Zoom
343 /* Select Our Texture */
345 /* Draw The Particle Using Our RGB Values,
346 * Fade The Particle Based On It's Life
348 particle
[loop
].life
=(particle
[loop
].index
/particle
[loop
].indexo
)*2.0f
;
349 glColor4f( particle
[loop
].r
,
352 particle
[loop
].life
);
354 /* Build Quad From A Triangle Strip */
356 glBegin( GL_TRIANGLE_STRIP
);
358 glBegin( GL_TRIANGLE_FAN
);
360 glTexCoord2d( 1, 1 );
361 glVertex3f( x
+ particle
[loop
].size
, y
+ particle
[loop
].size
, z
);
363 glTexCoord2d( 0, 1 );
364 glVertex3f( x
- particle
[loop
].size
, y
+ particle
[loop
].size
, z
);
366 glTexCoord2d( 1, 0 );
367 glVertex3f( x
+ particle
[loop
].size
, y
- particle
[loop
].size
, z
);
369 glTexCoord2d( 0, 0 );
370 glVertex3f( x
- particle
[loop
].size
, y
- particle
[loop
].size
, z
);
372 particle
[loop
].x
=(particle
[loop
].xo
*sin(particle
[loop
].index
))*pow((double) particle
[loop
].index
/particle
[loop
].indexo
,(double) 8.0);
373 particle
[loop
].y
=(particle
[loop
].yo
*sin(particle
[loop
].index
))*pow((double) particle
[loop
].index
/particle
[loop
].indexo
,(double) 8.0);
374 particle
[loop
].z
=(particle
[loop
].zo
*sin(particle
[loop
].index
))*pow((double) particle
[loop
].index
/particle
[loop
].indexo
,(double) 8.0);
375 particle
[loop
].index
-=0.05;
376 if (particle
[loop
].index
<0.0f
) // If Particle Is Burned Out
380 // Lets stir some things up
386 void Gravity::setSize( float newSize
)
390 void Gravity::setStars( bool doStars
)
395 void KGravitySaver::updateSize(int newSize
)
397 gravity
->setSize(newSize
/100);
399 void KGravitySaver::doStars(bool starState
)
401 gravity
->setStars(starState
);
404 void Gravity::buildParticle(int loop
)
406 GLfloat colors
[12][3]=
407 {{1.0f
,0.5f
,0.5f
},{1.0f
,0.75f
,0.5f
},{1.0f
,1.0f
,0.5f
},{0.75f
,1.0f
,0.5f
},
408 {0.5f
,1.0f
,0.5f
},{0.5f
,1.0f
,0.75f
},{0.5f
,1.0f
,1.0f
},{0.5f
,0.75f
,1.0f
},
409 {0.5f
,0.5f
,1.0f
},{0.75f
,0.5f
,1.0f
},{1.0f
,0.5f
,1.0f
},{1.0f
,0.5f
,0.75f
}};
410 col
= ( ++col
) % 12;
411 particle
[loop
].active
=true;
412 particle
[loop
].index
=KRandom::random()%100;
413 particle
[loop
].indexo
=particle
[loop
].index
;
414 particle
[loop
].fade
=float(KRandom::random()%100)/1000.0f
+0.003f
; // Random Fade Value
415 particle
[loop
].r
=colors
[col
][0]; // Select Red From Color Table
416 particle
[loop
].g
=colors
[col
][1]; // Select Green From Color Table
417 particle
[loop
].b
=colors
[col
][2]; // Select Blue From Color Table
418 particle
[loop
].size
=size
;
419 particle
[loop
].x
= float(KRandom::random()%100-50)*4.0;
420 particle
[loop
].y
= float(KRandom::random()%20-10)*4.0;
421 particle
[loop
].z
= float(KRandom::random()%100-50)*4.0;
422 particle
[loop
].xo
= particle
[loop
].x
;
423 if ((1+(KRandom::random() % 10) > 5))
424 particle
[loop
].yo
= particle
[loop
].y
;
426 particle
[loop
].yo
= 0.0;
427 particle
[loop
].zo
= particle
[loop
].z
;