Qt3to4
[kdeartwork.git] / kscreensaver / kdesavers / Euphoria.cpp
blob8e136bf31cb1af3ef22444574cb9e75adf2d5e7a
1 //============================================================================
2 //
3 // Terence Welsh Screensaver - Euphoria
4 // http://www.reallyslick.com/
5 //
6 // Ported to KDE by Karl Robillard
7 //
8 /*
9 * Copyright (C) 2002 Terence M. Welsh
11 * Euphoria is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * Euphoria is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301 USA
24 //============================================================================
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <math.h>
30 #include <time.h>
31 #include <qtimer.h>
32 //Added by qt3to4:
33 #include <QVBoxLayout>
34 #include <QHBoxLayout>
35 #include <QKeyEvent>
36 #include "Euphoria.h"
37 #include "Euphoria.moc"
38 #include "EuphoriaTexture.h"
41 #define NUMCONSTS 9
42 #define PIx2 6.28318530718f
45 //----------------------------------------------------------------------------
48 #include <sys/time.h>
49 #include <unistd.h>
52 // Returns the system time, in seconds.
53 double timeGetTime()
55 struct timeval tp;
56 gettimeofday( &tp, 0 );
57 return (double)tp.tv_sec + (double)tp.tv_usec / 1000000;
61 //----------------------------------------------------------------------------
64 class rsVec
66 public:
68 float v[3];
70 rsVec() {}
71 rsVec(float xx, float yy, float zz);
73 void set(float xx, float yy, float zz);
74 float normalize();
75 float dot(rsVec);
76 void cross(rsVec, rsVec);
78 float & operator [] (int i) {return v[i];}
79 const float & operator [] (int i) const {return v[i];}
80 rsVec & operator = (const rsVec &vec)
81 {v[0]=vec[0];v[1]=vec[1];v[2]=vec[2];return *this;};
82 rsVec operator + (const rsVec &vec)
83 {return(rsVec(v[0]+vec[0], v[1]+vec[1], v[2]+vec[2]));};
84 rsVec operator - (const rsVec &vec)
85 {return(rsVec(v[0]-vec[0], v[1]-vec[1], v[2]-vec[2]));};
86 rsVec operator * (const float &mul)
87 {return(rsVec(v[0]*mul, v[1]*mul, v[2]*mul));};
88 rsVec operator / (const float &div)
89 {float rec = 1.0f/div; return(rsVec(v[0]*rec, v[1]*rec, v[2]*rec));};
90 rsVec & operator += (const rsVec &vec)
91 {v[0]+=vec[0];v[1]+=vec[1];v[2]+=vec[2];return *this;};
92 rsVec & operator -= (const rsVec &vec)
93 {v[0]-=vec[0];v[1]-=vec[1];v[2]-=vec[2];return *this;};
94 rsVec & operator *= (const rsVec &vec)
95 {v[0]*=vec[0];v[1]*=vec[1];v[2]*=vec[2];return *this;};
96 rsVec & operator *= (const float &mul)
97 {v[0]*=mul;v[1]*=mul;v[2]*=mul;return *this;};
101 rsVec::rsVec(float xx, float yy, float zz){
102 v[0] = xx;
103 v[1] = yy;
104 v[2] = zz;
108 void rsVec::set(float xx, float yy, float zz){
109 v[0] = xx;
110 v[1] = yy;
111 v[2] = zz;
115 float rsVec::normalize(){
116 float length = float(sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]));
117 if(length == 0.0f){
118 v[1] = 1.0f;
119 return(0.0f);
121 float reciprocal = 1.0f / length;
122 v[0] *= reciprocal;
123 v[1] *= reciprocal;
124 v[2] *= reciprocal;
125 // Really freakin' stupid compiler bug fix for VC++ 5.0
126 /*v[0] /= length;
127 v[1] /= length;
128 v[2] /= length;*/
129 return(length);
133 float rsVec::dot(rsVec vec1){
134 return(v[0] * vec1[0] + v[1] * vec1[1] + v[2] * vec1[2]);
138 void rsVec::cross(rsVec vec1, rsVec vec2){
139 v[0] = vec1[1] * vec2[2] - vec2[1] * vec1[2];
140 v[1] = vec1[2] * vec2[0] - vec2[2] * vec1[0];
141 v[2] = vec1[0] * vec2[1] - vec2[0] * vec1[1];
145 //----------------------------------------------------------------------------
148 void hsl2rgb(float h, float s, float l, float &r, float &g, float &b)
150 // hue influence
151 if(h < 0.166667){ // full red, some green
152 r = 1.0;
153 g = h * 6.0f;
154 b = 0.0;
156 else {
157 if(h < 0.5){ // full green
158 g = 1.0;
159 if(h < 0.333333){ // some red
160 r = 1.0f - ((h - 0.166667f) * 6.0f);
161 b = 0.0;
163 else{ // some blue
164 b = (h - 0.333333f) * 6.0f;
165 r = 0.0;
168 else{
169 if(h < 0.833333){ // full blue
170 b = 1.0;
171 if(h < 0.666667){ // some green
172 g = 1.0f - ((h - 0.5f) * 6.0f);
173 r = 0.0;
175 else{ // some red
176 r = (h - 0.666667f) * 6.0f;
177 g = 0.0;
180 else{ // full red, some blue
181 r = 1.0;
182 b = 1.0f - ((h - 0.833333f) * 6.0f);
183 g = 0.0;
188 // saturation influence
189 r = 1.0f - (s * (1.0f - r));
190 g = 1.0f - (s * (1.0f - g));
191 b = 1.0f - (s * (1.0f - b));
193 // luminosity influence
194 r *= l;
195 g *= l;
196 b *= l;
200 // Useful random number macros
201 // Don't forget to initialize with srand()
202 inline int myRandi(int x){
203 return((rand() * x) / RAND_MAX);
205 inline float myRandf(float x){
206 return(float(rand() * x) / float(RAND_MAX));
210 //----------------------------------------------------------------------------
213 // Context pointer to allow many instances.
214 static EuphoriaWidget* _ec = 0;
217 class wisp
219 public:
221 wisp();
222 ~wisp();
223 void update();
224 void draw();
225 void drawAsBackground();
228 int density;
229 float*** vertices;
230 float c[NUMCONSTS]; // constants
231 float cr[NUMCONSTS]; // constants' radial position
232 float cv[NUMCONSTS]; // constants' change velocities
233 float hsl[3];
234 float rgb[3];
235 float hueSpeed;
236 float saturationSpeed;
240 wisp::wisp()
242 int i, j;
243 float recHalfDens = 1.0f / (float(_ec->dDensity) * 0.5f);
245 density = _ec->dDensity;
246 vertices = new float**[density+1];
247 for(i=0; i<=density; i++)
249 vertices[i] = new float*[density+1];
250 for(j=0; j<=density; j++)
252 vertices[i][j] = new float[7];
253 vertices[i][j][3] = float(i) * recHalfDens - 1.0f; // x position on grid
254 vertices[i][j][4] = float(j) * recHalfDens - 1.0f; // y position on grid
255 // distance squared from the center
256 vertices[i][j][5] = vertices[i][j][3] * vertices[i][j][3]
257 + vertices[i][j][4] * vertices[i][j][4];
258 vertices[i][j][6] = 0.0f; // intensity
262 // initialize constants
263 for(i=0; i<NUMCONSTS; i++)
265 c[i] = myRandf(2.0f) - 1.0f;
266 cr[i] = myRandf(PIx2);
267 cv[i] = myRandf(_ec->dSpeed * 0.03f) + (_ec->dSpeed * 0.001f);
270 // pick color
271 hsl[0] = myRandf(1.0f);
272 hsl[1] = 0.1f + myRandf(0.9f);
273 hsl[2] = 1.0f;
274 hueSpeed = myRandf(0.1f) - 0.05f;
275 saturationSpeed = myRandf(0.04f) + 0.001f;
279 wisp::~wisp()
281 int i, j;
283 for(i=0; i<=density; i++)
285 for(j=0; j<=density; j++)
287 delete[] vertices[i][j];
289 delete[] vertices[i];
291 delete[] vertices;
295 void wisp::update()
297 int i, j;
298 rsVec up, right, crossvec;
299 // visibility constants
300 static float viscon1 = float(_ec->dVisibility) * 0.01f;
301 static float viscon2 = 1.0f / viscon1;
303 // update constants
304 for(i=0; i<NUMCONSTS; i++){
305 cr[i] += cv[i] * _ec->elapsedTime;
306 if(cr[i] > PIx2)
307 cr[i] -= PIx2;
308 c[i] = cos(cr[i]);
311 // update vertex positions
312 for(i=0; i<=density; i++){
313 for(j=0; j<=density; j++){
314 vertices[i][j][0] = vertices[i][j][3] * vertices[i][j][3] * vertices[i][j][4] * c[0]
315 + vertices[i][j][5] * c[1] + 0.5f * c[2];
316 vertices[i][j][1] = vertices[i][j][4] * vertices[i][j][4] * vertices[i][j][5] * c[3]
317 + vertices[i][j][3] * c[4] + 0.5f * c[5];
318 vertices[i][j][2] = vertices[i][j][5] * vertices[i][j][5] * vertices[i][j][3] * c[6]
319 + vertices[i][j][4] * c[7] + c[8];
323 // update vertex normals for most of mesh
324 for(i=1; i<density; i++){
325 for(j=1; j<density; j++){
326 up.set(vertices[i][j+1][0] - vertices[i][j-1][0],
327 vertices[i][j+1][1] - vertices[i][j-1][1],
328 vertices[i][j+1][2] - vertices[i][j-1][2]);
329 right.set(vertices[i+1][j][0] - vertices[i-1][j][0],
330 vertices[i+1][j][1] - vertices[i-1][j][1],
331 vertices[i+1][j][2] - vertices[i-1][j][2]);
332 up.normalize();
333 right.normalize();
334 crossvec.cross(right, up);
335 // Use depth component of normal to compute intensity
336 // This way only edges of wisp are bright
337 if(crossvec[2] < 0.0f)
338 crossvec[2] *= -1.0f;
339 vertices[i][j][6] = viscon2 * (viscon1 - crossvec[2]);
340 if(vertices[i][j][6] > 1.0f)
341 vertices[i][j][6] = 1.0f;
342 if(vertices[i][j][6] < 0.0f)
343 vertices[i][j][6] = 0.0f;
347 // update color
348 hsl[0] += hueSpeed * _ec->elapsedTime;
349 if(hsl[0] < 0.0f)
350 hsl[0] += 1.0f;
351 if(hsl[0] > 1.0f)
352 hsl[0] -= 1.0f;
353 hsl[1] += saturationSpeed * _ec->elapsedTime;
354 if(hsl[1] <= 0.1f){
355 hsl[1] = 0.1f;
356 saturationSpeed = -saturationSpeed;
358 if(hsl[1] >= 1.0f){
359 hsl[1] = 1.0f;
360 saturationSpeed = -saturationSpeed;
362 hsl2rgb(hsl[0], hsl[1], hsl[2], rgb[0], rgb[1], rgb[2]);
366 void wisp::draw()
368 int i, j;
370 glPushMatrix();
372 if(_ec->dWireframe)
374 for(i=1; i<density; i++){
375 glBegin(GL_LINE_STRIP);
376 for(j=0; j<=density; j++){
377 glColor3f(rgb[0] + vertices[i][j][6] - 1.0f, rgb[1] + vertices[i][j][6] - 1.0f, rgb[2] + vertices[i][j][6] - 1.0f);
378 glTexCoord2d(vertices[i][j][3] - vertices[i][j][0], vertices[i][j][4] - vertices[i][j][1]);
379 glVertex3fv(vertices[i][j]);
381 glEnd();
383 for(j=1; j<density; j++){
384 glBegin(GL_LINE_STRIP);
385 for(i=0; i<=density; i++){
386 glColor3f(rgb[0] + vertices[i][j][6] - 1.0f, rgb[1] + vertices[i][j][6] - 1.0f, rgb[2] + vertices[i][j][6] - 1.0f);
387 glTexCoord2d(vertices[i][j][3] - vertices[i][j][0], vertices[i][j][4] - vertices[i][j][1]);
388 glVertex3fv(vertices[i][j]);
390 glEnd();
393 else
395 for(i=0; i<density; i++){
396 glBegin(GL_TRIANGLE_STRIP);
397 for(j=0; j<=density; j++){
398 glColor3f(rgb[0] + vertices[i+1][j][6] - 1.0f, rgb[1] + vertices[i+1][j][6] - 1.0f, rgb[2] + vertices[i+1][j][6] - 1.0f);
399 glTexCoord2d(vertices[i+1][j][3] - vertices[i+1][j][0], vertices[i+1][j][4] - vertices[i+1][j][1]);
400 glVertex3fv(vertices[i+1][j]);
401 glColor3f(rgb[0] + vertices[i][j][6] - 1.0f, rgb[1] + vertices[i][j][6] - 1.0f, rgb[2] + vertices[i][j][6] - 1.0f);
402 glTexCoord2d(vertices[i][j][3] - vertices[i][j][0], vertices[i][j][4] - vertices[i][j][1]);
403 glVertex3fv(vertices[i][j]);
405 glEnd();
409 glPopMatrix();
413 void wisp::drawAsBackground()
415 int i, j;
417 glPushMatrix();
418 glTranslatef(c[0] * 0.2f, c[1] * 0.2f, 1.6f);
420 if(_ec->dWireframe)
422 for(i=1; i<density; i++){
423 glBegin(GL_LINE_STRIP);
424 for(j=0; j<=density; j++){
425 glColor3f(rgb[0] + vertices[i][j][6] - 1.0f, rgb[1] + vertices[i][j][6] - 1.0f, rgb[2] + vertices[i][j][6] - 1.0f);
426 glTexCoord2d(vertices[i][j][3] - vertices[i][j][0], vertices[i][j][4] - vertices[i][j][1]);
427 glVertex3f(vertices[i][j][3], vertices[i][j][4], vertices[i][j][6]);
429 glEnd();
431 for(j=1; j<density; j++){
432 glBegin(GL_LINE_STRIP);
433 for(i=0; i<=density; i++){
434 glColor3f(rgb[0] + vertices[i][j][6] - 1.0f, rgb[1] + vertices[i][j][6] - 1.0f, rgb[2] + vertices[i][j][6] - 1.0f);
435 glTexCoord2d(vertices[i][j][3] - vertices[i][j][0], vertices[i][j][4] - vertices[i][j][1]);
436 glVertex3f(vertices[i][j][3], vertices[i][j][4], vertices[i][j][6]);
438 glEnd();
441 else
443 for(i=0; i<density; i++){
444 glBegin(GL_TRIANGLE_STRIP);
445 for(j=0; j<=density; j++){
446 glColor3f(rgb[0] + vertices[i+1][j][6] - 1.0f, rgb[1] + vertices[i+1][j][6] - 1.0f, rgb[2] + vertices[i+1][j][6] - 1.0f);
447 glTexCoord2d(vertices[i+1][j][3] - vertices[i+1][j][0], vertices[i+1][j][4] - vertices[i+1][j][1]);
448 glVertex3f(vertices[i+1][j][3], vertices[i+1][j][4], vertices[i+1][j][6]);
449 glColor3f(rgb[0] + vertices[i][j][6] - 1.0f, rgb[1] + vertices[i][j][6] - 1.0f, rgb[2] + vertices[i][j][6] - 1.0f);
450 glTexCoord2d(vertices[i][j][3] - vertices[i][j][0], vertices[i][j][4] - vertices[i][j][1]);
451 glVertex3f(vertices[i][j][3], vertices[i][j][4], vertices[i][j][6]);
453 glEnd();
457 glPopMatrix();
461 //----------------------------------------------------------------------------
464 EuphoriaWidget::EuphoriaWidget( QWidget* parent, const char* name )
465 : QGLWidget(parent, name), texName(0), _wisps(0), _backwisps(0),
466 feedbackmap(0), feedbacktex(0)
468 setDefaults( Regular );
470 _frameTime = 1000 / 60;
471 _timer = new QTimer( this );
472 connect( _timer, SIGNAL(timeout()), this, SLOT(nextFrame()) );
476 EuphoriaWidget::~EuphoriaWidget()
478 // Free memory
479 if ( texName )
480 glDeleteTextures( 1, &texName );
481 if ( feedbacktex )
482 glDeleteTextures( 1, &feedbacktex );
483 delete[] _wisps;
484 delete[] _backwisps;
488 void EuphoriaWidget::paintGL()
490 int i;
491 static double lastTime = timeGetTime();
493 // update time
494 elapsedTime = timeGetTime() - lastTime;
495 lastTime += elapsedTime;
497 _ec = this;
499 // Update wisps
500 for(i=0; i<dWisps; i++)
501 _wisps[i].update();
502 for(i=0; i<dBackground; i++)
503 _backwisps[i].update();
506 if(dFeedback)
508 float feedbackIntensity = float(dFeedback) / 101.0f;
510 // update feedback variables
511 for(i=0; i<4; i++)
513 fr[i] += elapsedTime * fv[i];
514 if(fr[i] > PIx2)
515 fr[i] -= PIx2;
517 f[0] = 30.0f * cos(fr[0]);
518 f[1] = 0.2f * cos(fr[1]);
519 f[2] = 0.2f * cos(fr[2]);
520 f[3] = 0.8f * cos(fr[3]);
521 for(i=0; i<3; i++)
523 lr[i] += elapsedTime * lv[i];
524 if(lr[i] > PIx2)
525 lr[i] -= PIx2;
526 l[i] = cos(lr[i]);
527 l[i] = l[i] * l[i];
530 // Create drawing area for feedback texture
531 glViewport(0, 0, feedbacktexsize, feedbacktexsize);
532 glMatrixMode(GL_PROJECTION);
533 glLoadIdentity();
534 gluPerspective(30.0, aspectRatio, 0.01f, 20.0f);
535 glMatrixMode(GL_MODELVIEW);
537 // Draw
538 glClear(GL_COLOR_BUFFER_BIT);
539 glColor3f(feedbackIntensity, feedbackIntensity, feedbackIntensity);
540 glBindTexture(GL_TEXTURE_2D, feedbacktex);
541 glPushMatrix();
542 glTranslatef(f[1] * l[1], f[2] * l[1], f[3] * l[2]);
543 glRotatef(f[0] * l[0], 0, 0, 1);
544 glBegin(GL_TRIANGLE_STRIP);
545 glTexCoord2f(-0.5f, -0.5f);
546 glVertex3f(-aspectRatio*2.0f, -2.0f, 1.25f);
547 glTexCoord2f(1.5f, -0.5f);
548 glVertex3f(aspectRatio*2.0f, -2.0f, 1.25f);
549 glTexCoord2f(-0.5f, 1.5f);
550 glVertex3f(-aspectRatio*2.0f, 2.0f, 1.25f);
551 glTexCoord2f(1.5f, 1.5f);
552 glVertex3f(aspectRatio*2.0f, 2.0f, 1.25f);
553 glEnd();
554 glPopMatrix();
555 glBindTexture(GL_TEXTURE_2D, texName);
556 for(i=0; i<dBackground; i++)
557 _backwisps[i].drawAsBackground();
558 for(i=0; i<dWisps; i++)
559 _wisps[i].draw();
561 // readback feedback texture
562 glReadBuffer(GL_BACK);
563 glPixelStorei(GL_UNPACK_ROW_LENGTH, feedbacktexsize);
564 glBindTexture(GL_TEXTURE_2D, feedbacktex);
565 glReadPixels(0, 0, feedbacktexsize, feedbacktexsize, GL_RGB, GL_UNSIGNED_BYTE, feedbackmap);
566 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, feedbacktexsize, feedbacktexsize, GL_RGB, GL_UNSIGNED_BYTE, feedbackmap);
568 // create regular drawing area
569 glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
570 glMatrixMode(GL_PROJECTION);
571 glLoadIdentity();
572 gluPerspective(20.0, aspectRatio, 0.01f, 20.0f);
573 glMatrixMode(GL_MODELVIEW);
575 // Draw again
576 glClear(GL_COLOR_BUFFER_BIT);
577 glColor3f(feedbackIntensity, feedbackIntensity, feedbackIntensity);
578 glPushMatrix();
579 glTranslatef(f[1] * l[1], f[2] * l[1], f[3] * l[2]);
580 glRotatef(f[0] * l[0], 0, 0, 1);
581 glBegin(GL_TRIANGLE_STRIP);
582 glTexCoord2f(-0.5f, -0.5f);
583 glVertex3f(-aspectRatio*2.0f, -2.0f, 1.25f);
584 glTexCoord2f(1.5f, -0.5f);
585 glVertex3f(aspectRatio*2.0f, -2.0f, 1.25f);
586 glTexCoord2f(-0.5f, 1.5f);
587 glVertex3f(-aspectRatio*2.0f, 2.0f, 1.25f);
588 glTexCoord2f(1.5f, 1.5f);
589 glVertex3f(aspectRatio*2.0f, 2.0f, 1.25f);
590 glEnd();
591 glPopMatrix();
593 glBindTexture(GL_TEXTURE_2D, texName);
595 else
596 glClear(GL_COLOR_BUFFER_BIT);
599 for(i=0; i<dBackground; i++)
600 _backwisps[i].drawAsBackground();
601 for(i=0; i<dWisps; i++)
602 _wisps[i].draw();
604 glFlush();
608 void EuphoriaWidget::resizeGL( int w, int h )
610 glViewport(0, 0, w, h );
612 viewport[0] = 0;
613 viewport[1] = 0;
614 viewport[2] = w;
615 viewport[3] = h;
617 aspectRatio = (float) w / (float) h;
619 // setup regular drawing area just in case feedback isn't used
620 glMatrixMode(GL_PROJECTION);
621 glLoadIdentity();
622 gluPerspective(20.0, aspectRatio, 0.01, 20);
623 glMatrixMode(GL_MODELVIEW);
624 glLoadIdentity();
625 glTranslatef(0.0, 0.0, -5.0);
629 // Window initialization
630 void EuphoriaWidget::initializeGL()
632 // Need to call this to setup viewport[] parameters used in
633 // the next updateParameters() call
634 resizeGL( width(), height() );
636 updateParameters();
638 _timer->start( _frameTime, true );
642 #ifdef UNIT_TEST
643 void EuphoriaWidget::keyPressEvent( QKeyEvent* e )
645 if( e->key() == Qt::Key_0 ) { setDefaults( 0 ); updateParameters(); }
646 if( e->key() == Qt::Key_1 ) { setDefaults( 1 ); updateParameters(); }
647 if( e->key() == Qt::Key_2 ) { setDefaults( 2 ); updateParameters(); }
648 if( e->key() == Qt::Key_3 ) { setDefaults( 3 ); updateParameters(); }
649 if( e->key() == Qt::Key_4 ) { setDefaults( 4 ); updateParameters(); }
650 if( e->key() == Qt::Key_5 ) { setDefaults( 5 ); updateParameters(); }
651 if( e->key() == Qt::Key_6 ) { setDefaults( 6 ); updateParameters(); }
652 if( e->key() == Qt::Key_7 ) { setDefaults( 7 ); updateParameters(); }
653 if( e->key() == Qt::Key_8 ) { setDefaults( 8 ); updateParameters(); }
655 #endif
658 void EuphoriaWidget::nextFrame()
660 updateGL();
661 _timer->start( _frameTime, true );
665 void EuphoriaWidget::updateParameters()
667 srand((unsigned)time(NULL));
668 rand(); rand(); rand(); rand(); rand();
670 elapsedTime = 0.0f;
672 fr[0] = 0.0f;
673 fr[1] = 0.0f;
674 fr[2] = 0.0f;
675 fr[3] = 0.0f;
677 lr[0] = 0.0f;
678 lr[1] = 0.0f;
679 lr[2] = 0.0f;
681 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
682 glClear(GL_COLOR_BUFFER_BIT);
683 glEnable(GL_BLEND);
684 glBlendFunc(GL_ONE, GL_ONE);
685 glLineWidth(2.0f);
687 // Commented out because smooth lines and textures don't mix on my TNT.
688 // It's like it rendering in software mode
689 glEnable(GL_LINE_SMOOTH);
690 //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
692 if(dTexture)
694 int whichtex = dTexture;
695 if(whichtex == 4) // random texture
696 whichtex = myRandi(3) + 1;
697 glEnable(GL_TEXTURE_2D);
698 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
699 // Initialize texture
700 glGenTextures(1, &texName);
701 glBindTexture(GL_TEXTURE_2D, texName);
702 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
703 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
704 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
705 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
706 switch(whichtex){
707 case 1:
708 gluBuild2DMipmaps(GL_TEXTURE_2D, 1, TEXSIZE, TEXSIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, plasmamap);
709 break;
710 case 2:
711 gluBuild2DMipmaps(GL_TEXTURE_2D, 1, TEXSIZE, TEXSIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, stringymap);
712 break;
713 case 3:
714 gluBuild2DMipmaps(GL_TEXTURE_2D, 1, TEXSIZE, TEXSIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, linesmap);
716 } else if ( texName ) {
717 glDeleteTextures( 1, &texName );
718 texName = 0;
721 if(dFeedback)
723 feedbacktexsize = int(pow(2, dFeedbacksize));
724 while(feedbacktexsize > viewport[2] || feedbacktexsize > viewport[3]){
725 dFeedbacksize -= 1;
726 feedbacktexsize = int(pow(2, dFeedbacksize));
729 // feedback texture setup
730 glEnable(GL_TEXTURE_2D);
731 delete [] feedbackmap;
732 feedbackmap = new unsigned char[feedbacktexsize*feedbacktexsize*3];
733 glGenTextures(1, &feedbacktex);
734 glBindTexture(GL_TEXTURE_2D, feedbacktex);
735 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
736 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
737 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
738 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
739 glTexImage2D(GL_TEXTURE_2D, 0, 3, feedbacktexsize, feedbacktexsize, 0, GL_RGB, GL_UNSIGNED_BYTE, feedbackmap);
741 // feedback velocity variable setup
742 fv[0] = float(dFeedbackspeed) * (myRandf(0.025f) + 0.025f);
743 fv[1] = float(dFeedbackspeed) * (myRandf(0.05f) + 0.05f);
744 fv[2] = float(dFeedbackspeed) * (myRandf(0.05f) + 0.05f);
745 fv[3] = float(dFeedbackspeed) * (myRandf(0.1f) + 0.1f);
746 lv[0] = float(dFeedbackspeed) * (myRandf(0.0025f) + 0.0025f);
747 lv[1] = float(dFeedbackspeed) * (myRandf(0.0025f) + 0.0025f);
748 lv[2] = float(dFeedbackspeed) * (myRandf(0.0025f) + 0.0025f);
749 } else if ( feedbacktex ) {
750 glDeleteTextures( 1, &feedbacktex );
751 feedbacktex = 0;
754 // Initialize wisps
755 _ec = this;
756 delete[] _wisps;
757 delete[] _backwisps;
758 _wisps = new wisp[dWisps];
759 _backwisps = new wisp[dBackground];
764 May be called at any time - makes no OpenGL calls.
766 void EuphoriaWidget::setDefaults(int which)
768 switch(which)
770 case Grid:
771 dWisps = 4;
772 dBackground = 1;
773 dDensity = 25;
774 dVisibility = 70;
775 dSpeed = 15;
776 dFeedback = 0;
777 dFeedbackspeed = 1;
778 dFeedbacksize = 8;
779 dWireframe = 1;
780 dTexture = 0;
781 break;
783 case Cubism:
784 dWisps = 15;
785 dBackground = 0;
786 dDensity = 4;
787 dVisibility = 15;
788 dSpeed = 10;
789 dFeedback = 0;
790 dFeedbackspeed = 1;
791 dFeedbacksize = 8;
792 dWireframe = 0;
793 dTexture = 0;
794 break;
796 case BadMath:
797 dWisps = 2;
798 dBackground = 2;
799 dDensity = 20;
800 dVisibility = 40;
801 dSpeed = 30;
802 dFeedback = 40;
803 dFeedbackspeed = 5;
804 dFeedbacksize = 8;
805 dWireframe = 1;
806 dTexture = 2;
807 break;
809 case MTheory:
810 dWisps = 3;
811 dBackground = 0;
812 dDensity = 25;
813 dVisibility = 15;
814 dSpeed = 20;
815 dFeedback = 40;
816 dFeedbackspeed = 20;
817 dFeedbacksize = 8;
818 dWireframe = 0;
819 dTexture = 0;
820 break;
822 case UHFTEM:
823 dWisps = 0;
824 dBackground = 3;
825 dDensity = 35;
826 dVisibility = 5;
827 dSpeed = 50;
828 dFeedback = 0;
829 dFeedbackspeed = 1;
830 dFeedbacksize = 8;
831 dWireframe = 0;
832 dTexture = 0;
833 break;
835 case Nowhere:
836 dWisps = 0;
837 dBackground = 3;
838 dDensity = 30;
839 dVisibility = 40;
840 dSpeed = 20;
841 dFeedback = 80;
842 dFeedbackspeed = 10;
843 dFeedbacksize = 8;
844 dWireframe = 1;
845 dTexture = 3;
846 break;
848 case Echo:
849 dWisps = 3;
850 dBackground = 0;
851 dDensity = 25;
852 dVisibility = 30;
853 dSpeed = 20;
854 dFeedback = 85;
855 dFeedbackspeed = 30;
856 dFeedbacksize = 8;
857 dWireframe = 0;
858 dTexture = 1;
859 break;
861 case Kaleidoscope:
862 dWisps = 3;
863 dBackground = 0;
864 dDensity = 25;
865 dVisibility = 40;
866 dSpeed = 15;
867 dFeedback = 90;
868 dFeedbackspeed = 3;
869 dFeedbacksize = 8;
870 dWireframe = 0;
871 dTexture = 0;
872 break;
874 case Regular:
875 default:
876 dWisps = 5;
877 dBackground = 0;
878 dDensity = 25;
879 dVisibility = 35;
880 dSpeed = 15;
881 dFeedback = 0;
882 dFeedbackspeed = 1;
883 dFeedbacksize = 8;
884 dWireframe = 0;
885 dTexture = 2;
886 break;
891 //----------------------------------------------------------------------------
894 #ifndef UNIT_TEST
895 #include <klocale.h>
896 #include <kglobal.h>
897 #include <kconfig.h>
900 // libkscreensaver interface
901 extern "C"
903 KDE_EXPORT const char* kss_applicationName = "keuphoria.kss";
904 KDE_EXPORT const char* kss_description = I18N_NOOP( "Euphoria" );
905 KDE_EXPORT const char* kss_version = "1.0";
907 KDE_EXPORT KScreenSaver* kss_create( WId id )
909 return new KEuphoriaScreenSaver( id );
912 KDE_EXPORT QDialog* kss_setup()
914 return new KEuphoriaSetup;
919 //----------------------------------------------------------------------------
922 KEuphoriaScreenSaver::KEuphoriaScreenSaver( WId id ) : KScreenSaver( id )
924 _effect = new EuphoriaWidget;
926 readSettings();
928 embed( _effect );
929 _effect->show();
933 KEuphoriaScreenSaver::~KEuphoriaScreenSaver()
938 static int filterRandom( int n )
940 if( (n < 0) || (n >= EuphoriaWidget::DefaultModes) )
942 srand((unsigned)time(NULL));
943 n = rand() % EuphoriaWidget::DefaultModes;
945 return n;
949 void KEuphoriaScreenSaver::readSettings()
951 KConfig* config = KGlobal::config();
952 config->setGroup("Settings");
954 _mode = config->readNumEntry( "Mode", EuphoriaWidget::Regular );
955 _effect->setDefaults( filterRandom(_mode) );
960 Any invalid mode will select one at random.
962 void KEuphoriaScreenSaver::setMode( int id )
964 _mode = id;
965 _effect->setDefaults( filterRandom(id) );
966 _effect->updateParameters();
970 //----------------------------------------------------------------------------
973 #include <qlayout.h>
974 #include <qlabel.h>
975 #include <qcombobox.h>
976 #include <kmessagebox.h>
979 static const char* defaultText[] =
981 I18N_NOOP( "Regular" ),
982 I18N_NOOP( "Grid" ),
983 I18N_NOOP( "Cubism" ),
984 I18N_NOOP( "Bad Math" ),
985 I18N_NOOP( "M-Theory" ),
986 I18N_NOOP( "UHFTEM" ), //"ultra high frequency tunneling electron microscope",
987 I18N_NOOP( "Nowhere" ),
988 I18N_NOOP( "Echo" ),
989 I18N_NOOP( "Kaleidoscope" ),
990 I18N_NOOP( "(Random)" ),
995 KEuphoriaSetup::KEuphoriaSetup( QWidget* parent, const char* name )
996 : KDialogBase( parent, name, true, i18n("Setup Euphoria Screen Saver"),
997 Ok|Cancel|Help, Ok, true )
999 setButtonText( Help, i18n( "A&bout" ) );
1001 QWidget *main = makeMainWidget();
1003 QHBoxLayout* top = new QHBoxLayout(main, 0, spacingHint());
1004 QVBoxLayout* leftCol = new QVBoxLayout;
1005 top->addLayout( leftCol );
1007 QLabel* label = new QLabel( i18n("Mode:"), main );
1008 leftCol->addWidget( label );
1010 modeW = new QComboBox( main );
1011 int i = 0;
1012 while (defaultText[i])
1013 modeW->insertItem( i18n(defaultText[i++]) );
1014 leftCol->addWidget( modeW );
1016 leftCol->addStretch();
1018 // Preview
1019 QWidget* preview;
1020 preview = new QWidget( main );
1021 preview->setFixedSize( 220, 170 );
1022 preview->setBackgroundColor( black );
1023 preview->show(); // otherwise saver does not get correct size
1024 _saver = new KEuphoriaScreenSaver( preview->winId() );
1025 top->addWidget(preview);
1027 // Now that we have _saver...
1028 modeW->setCurrentItem( _saver->mode() ); // set before we connect
1029 connect( modeW, SIGNAL(activated(int)), _saver, SLOT(setMode(int)) );
1031 setMinimumSize( sizeHint() );
1035 KEuphoriaSetup::~KEuphoriaSetup()
1037 delete _saver;
1041 void KEuphoriaSetup::slotHelp()
1043 KMessageBox::about(this,
1044 i18n("<h3>Euphoria 1.0</h3>\n<p>Copyright (c) 2002 Terence M. Welsh<br>\n<a href=\"http://www.reallyslick.com/\">http://www.reallyslick.com/</a></p>\n\n<p>Ported to KDE by Karl Robillard</p>"),
1045 QString::null, KMessageBox::AllowLink);
1050 Ok pressed - save settings and exit
1052 void KEuphoriaSetup::slotOk()
1054 KConfig* config = KGlobal::config();
1055 config->setGroup("Settings");
1057 QString val;
1058 val.setNum( modeW->currentItem() );
1059 config->writeEntry("Mode", val );
1061 config->sync();
1062 accept();
1064 #endif
1065 //----------------------------------------------------------------------------
1068 #ifdef UNIT_TEST
1069 // moc Euphoria.h -o Euphoria.moc
1070 // g++ -g -DUNIT_TEST Euphoria.cpp -I/usr/lib/qt3/include -lqt -L/usr/lib/qt3/lib -lGLU -lGL
1072 #include <qapplication.h>
1074 int main( int argc, char** argv )
1076 QApplication app( argc, argv );
1078 EuphoriaWidget w;
1079 w.setDefaults( EuphoriaWidget::UHFTEM );
1080 app.setMainWidget( &w );
1081 w.show();
1083 return app.exec();
1085 #endif
1088 //EOF