2 * Terence Welsh Screensaver - Euphoria
3 * http://www.reallyslick.com/
5 * Ported to KDE by Karl Robillard
6 * Copyright (C) 2002 Terence M. Welsh
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29 #include "Euphoria.moc"
30 #include "EuphoriaTexture.h"
35 #define PIx2 6.28318530718f
38 //----------------------------------------------------------------------------
45 // Returns the system time, in seconds.
49 gettimeofday( &tp
, 0 );
50 return (double)tp
.tv_sec
+ (double)tp
.tv_usec
/ 1000000;
54 //----------------------------------------------------------------------------
64 rsVec(float xx
, float yy
, float zz
);
66 void set(float xx
, float yy
, float zz
);
69 void cross(rsVec
, rsVec
);
71 float & operator [] (int i
) {return v
[i
];}
72 const float & operator [] (int i
) const {return v
[i
];}
73 rsVec
& operator = (const rsVec
&vec
)
74 {v
[0]=vec
[0];v
[1]=vec
[1];v
[2]=vec
[2];return *this;}
75 rsVec
operator + (const rsVec
&vec
)
76 {return(rsVec(v
[0]+vec
[0], v
[1]+vec
[1], v
[2]+vec
[2]));}
77 rsVec
operator - (const rsVec
&vec
)
78 {return(rsVec(v
[0]-vec
[0], v
[1]-vec
[1], v
[2]-vec
[2]));}
79 rsVec
operator * (const float &mul
)
80 {return(rsVec(v
[0]*mul
, v
[1]*mul
, v
[2]*mul
));}
81 rsVec
operator / (const float &div
)
82 {float rec
= 1.0f
/div
; return(rsVec(v
[0]*rec
, v
[1]*rec
, v
[2]*rec
));}
83 rsVec
& operator += (const rsVec
&vec
)
84 {v
[0]+=vec
[0];v
[1]+=vec
[1];v
[2]+=vec
[2];return *this;}
85 rsVec
& operator -= (const rsVec
&vec
)
86 {v
[0]-=vec
[0];v
[1]-=vec
[1];v
[2]-=vec
[2];return *this;}
87 rsVec
& operator *= (const rsVec
&vec
)
88 {v
[0]*=vec
[0];v
[1]*=vec
[1];v
[2]*=vec
[2];return *this;}
89 rsVec
& operator *= (const float &mul
)
90 {v
[0]*=mul
;v
[1]*=mul
;v
[2]*=mul
;return *this;}
94 rsVec::rsVec(float xx
, float yy
, float zz
){
101 void rsVec::set(float xx
, float yy
, float zz
){
108 float rsVec::normalize(){
109 float length
= float(sqrt(v
[0] * v
[0] + v
[1] * v
[1] + v
[2] * v
[2]));
114 float reciprocal
= 1.0f
/ length
;
118 // Really freakin' stupid compiler bug fix for VC++ 5.0
126 float rsVec::dot(rsVec vec1
){
127 return(v
[0] * vec1
[0] + v
[1] * vec1
[1] + v
[2] * vec1
[2]);
131 void rsVec::cross(rsVec vec1
, rsVec vec2
){
132 v
[0] = vec1
[1] * vec2
[2] - vec2
[1] * vec1
[2];
133 v
[1] = vec1
[2] * vec2
[0] - vec2
[2] * vec1
[0];
134 v
[2] = vec1
[0] * vec2
[1] - vec2
[0] * vec1
[1];
138 //----------------------------------------------------------------------------
141 void hsl2rgb(float h
, float s
, float l
, float &r
, float &g
, float &b
)
144 if(h
< 0.166667){ // full red, some green
150 if(h
< 0.5){ // full green
152 if(h
< 0.333333){ // some red
153 r
= 1.0f
- ((h
- 0.166667f
) * 6.0f
);
157 b
= (h
- 0.333333f
) * 6.0f
;
162 if(h
< 0.833333){ // full blue
164 if(h
< 0.666667){ // some green
165 g
= 1.0f
- ((h
- 0.5f
) * 6.0f
);
169 r
= (h
- 0.666667f
) * 6.0f
;
173 else{ // full red, some blue
175 b
= 1.0f
- ((h
- 0.833333f
) * 6.0f
);
181 // saturation influence
182 r
= 1.0f
- (s
* (1.0f
- r
));
183 g
= 1.0f
- (s
* (1.0f
- g
));
184 b
= 1.0f
- (s
* (1.0f
- b
));
186 // luminosity influence
193 // Useful random number macros
194 // Don't forget to initialize with srand()
195 inline int myRandi(int x
){
196 return((rand() * x
) / RAND_MAX
);
198 inline float myRandf(float x
){
199 return(float(rand() * x
) / float(RAND_MAX
));
203 //----------------------------------------------------------------------------
206 // Context pointer to allow many instances.
207 static EuphoriaWidget
* _ec
= 0;
218 void drawAsBackground();
223 float c
[NUMCONSTS
]; // constants
224 float cr
[NUMCONSTS
]; // constants' radial position
225 float cv
[NUMCONSTS
]; // constants' change velocities
229 float saturationSpeed
;
236 float recHalfDens
= 1.0f
/ (float(_ec
->dDensity
) * 0.5f
);
238 density
= _ec
->dDensity
;
239 vertices
= new float**[density
+1];
240 for(i
=0; i
<=density
; i
++)
242 vertices
[i
] = new float*[density
+1];
243 for(j
=0; j
<=density
; j
++)
245 vertices
[i
][j
] = new float[7];
246 vertices
[i
][j
][3] = float(i
) * recHalfDens
- 1.0f
; // x position on grid
247 vertices
[i
][j
][4] = float(j
) * recHalfDens
- 1.0f
; // y position on grid
248 // distance squared from the center
249 vertices
[i
][j
][5] = vertices
[i
][j
][3] * vertices
[i
][j
][3]
250 + vertices
[i
][j
][4] * vertices
[i
][j
][4];
251 vertices
[i
][j
][6] = 0.0f
; // intensity
255 // initialize constants
256 for(i
=0; i
<NUMCONSTS
; i
++)
258 c
[i
] = myRandf(2.0f
) - 1.0f
;
259 cr
[i
] = myRandf(PIx2
);
260 cv
[i
] = myRandf(_ec
->dSpeed
* 0.03f
) + (_ec
->dSpeed
* 0.001f
);
264 hsl
[0] = myRandf(1.0f
);
265 hsl
[1] = 0.1f
+ myRandf(0.9f
);
267 hueSpeed
= myRandf(0.1f
) - 0.05f
;
268 saturationSpeed
= myRandf(0.04f
) + 0.001f
;
276 for(i
=0; i
<=density
; i
++)
278 for(j
=0; j
<=density
; j
++)
280 delete[] vertices
[i
][j
];
282 delete[] vertices
[i
];
291 rsVec up
, right
, crossvec
;
292 // visibility constants
293 static float viscon1
= float(_ec
->dVisibility
) * 0.01f
;
294 static float viscon2
= 1.0f
/ viscon1
;
297 for(i
=0; i
<NUMCONSTS
; i
++){
298 cr
[i
] += cv
[i
] * _ec
->elapsedTime
;
304 // update vertex positions
305 for(i
=0; i
<=density
; i
++){
306 for(j
=0; j
<=density
; j
++){
307 vertices
[i
][j
][0] = vertices
[i
][j
][3] * vertices
[i
][j
][3] * vertices
[i
][j
][4] * c
[0]
308 + vertices
[i
][j
][5] * c
[1] + 0.5f
* c
[2];
309 vertices
[i
][j
][1] = vertices
[i
][j
][4] * vertices
[i
][j
][4] * vertices
[i
][j
][5] * c
[3]
310 + vertices
[i
][j
][3] * c
[4] + 0.5f
* c
[5];
311 vertices
[i
][j
][2] = vertices
[i
][j
][5] * vertices
[i
][j
][5] * vertices
[i
][j
][3] * c
[6]
312 + vertices
[i
][j
][4] * c
[7] + c
[8];
316 // update vertex normals for most of mesh
317 for(i
=1; i
<density
; i
++){
318 for(j
=1; j
<density
; j
++){
319 up
.set(vertices
[i
][j
+1][0] - vertices
[i
][j
-1][0],
320 vertices
[i
][j
+1][1] - vertices
[i
][j
-1][1],
321 vertices
[i
][j
+1][2] - vertices
[i
][j
-1][2]);
322 right
.set(vertices
[i
+1][j
][0] - vertices
[i
-1][j
][0],
323 vertices
[i
+1][j
][1] - vertices
[i
-1][j
][1],
324 vertices
[i
+1][j
][2] - vertices
[i
-1][j
][2]);
327 crossvec
.cross(right
, up
);
328 // Use depth component of normal to compute intensity
329 // This way only edges of wisp are bright
330 if(crossvec
[2] < 0.0f
)
331 crossvec
[2] *= -1.0f
;
332 vertices
[i
][j
][6] = viscon2
* (viscon1
- crossvec
[2]);
333 if(vertices
[i
][j
][6] > 1.0f
)
334 vertices
[i
][j
][6] = 1.0f
;
335 if(vertices
[i
][j
][6] < 0.0f
)
336 vertices
[i
][j
][6] = 0.0f
;
341 hsl
[0] += hueSpeed
* _ec
->elapsedTime
;
346 hsl
[1] += saturationSpeed
* _ec
->elapsedTime
;
349 saturationSpeed
= -saturationSpeed
;
353 saturationSpeed
= -saturationSpeed
;
355 hsl2rgb(hsl
[0], hsl
[1], hsl
[2], rgb
[0], rgb
[1], rgb
[2]);
367 for(i
=1; i
<density
; i
++){
368 glBegin(GL_LINE_STRIP
);
369 for(j
=0; j
<=density
; j
++){
370 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
);
371 glTexCoord2d(vertices
[i
][j
][3] - vertices
[i
][j
][0], vertices
[i
][j
][4] - vertices
[i
][j
][1]);
372 glVertex3fv(vertices
[i
][j
]);
376 for(j
=1; j
<density
; j
++){
377 glBegin(GL_LINE_STRIP
);
378 for(i
=0; i
<=density
; i
++){
379 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
);
380 glTexCoord2d(vertices
[i
][j
][3] - vertices
[i
][j
][0], vertices
[i
][j
][4] - vertices
[i
][j
][1]);
381 glVertex3fv(vertices
[i
][j
]);
388 for(i
=0; i
<density
; i
++){
389 glBegin(GL_TRIANGLE_STRIP
);
390 for(j
=0; j
<=density
; j
++){
391 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
);
392 glTexCoord2d(vertices
[i
+1][j
][3] - vertices
[i
+1][j
][0], vertices
[i
+1][j
][4] - vertices
[i
+1][j
][1]);
393 glVertex3fv(vertices
[i
+1][j
]);
394 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
);
395 glTexCoord2d(vertices
[i
][j
][3] - vertices
[i
][j
][0], vertices
[i
][j
][4] - vertices
[i
][j
][1]);
396 glVertex3fv(vertices
[i
][j
]);
406 void wisp::drawAsBackground()
411 glTranslatef(c
[0] * 0.2f
, c
[1] * 0.2f
, 1.6f
);
415 for(i
=1; i
<density
; i
++){
416 glBegin(GL_LINE_STRIP
);
417 for(j
=0; j
<=density
; j
++){
418 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
);
419 glTexCoord2d(vertices
[i
][j
][3] - vertices
[i
][j
][0], vertices
[i
][j
][4] - vertices
[i
][j
][1]);
420 glVertex3f(vertices
[i
][j
][3], vertices
[i
][j
][4], vertices
[i
][j
][6]);
424 for(j
=1; j
<density
; j
++){
425 glBegin(GL_LINE_STRIP
);
426 for(i
=0; i
<=density
; i
++){
427 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
);
428 glTexCoord2d(vertices
[i
][j
][3] - vertices
[i
][j
][0], vertices
[i
][j
][4] - vertices
[i
][j
][1]);
429 glVertex3f(vertices
[i
][j
][3], vertices
[i
][j
][4], vertices
[i
][j
][6]);
436 for(i
=0; i
<density
; i
++){
437 glBegin(GL_TRIANGLE_STRIP
);
438 for(j
=0; j
<=density
; j
++){
439 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
);
440 glTexCoord2d(vertices
[i
+1][j
][3] - vertices
[i
+1][j
][0], vertices
[i
+1][j
][4] - vertices
[i
+1][j
][1]);
441 glVertex3f(vertices
[i
+1][j
][3], vertices
[i
+1][j
][4], vertices
[i
+1][j
][6]);
442 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
);
443 glTexCoord2d(vertices
[i
][j
][3] - vertices
[i
][j
][0], vertices
[i
][j
][4] - vertices
[i
][j
][1]);
444 glVertex3f(vertices
[i
][j
][3], vertices
[i
][j
][4], vertices
[i
][j
][6]);
454 //----------------------------------------------------------------------------
457 EuphoriaWidget::EuphoriaWidget( QWidget
* parent
)
458 : QGLWidget(parent
), texName(0), _wisps(0), _backwisps(0),
459 feedbackmap(0), feedbacktex(0)
461 setDefaults( Regular
);
463 _frameTime
= 1000 / 60;
464 _timer
= new QTimer( this );
465 _timer
->setSingleShot( true );
466 connect( _timer
, SIGNAL(timeout()), this, SLOT(nextFrame()) );
470 EuphoriaWidget::~EuphoriaWidget()
474 glDeleteTextures( 1, &texName
);
476 glDeleteTextures( 1, &feedbacktex
);
482 void EuphoriaWidget::paintGL()
485 static double lastTime
= timeGetTime();
488 elapsedTime
= timeGetTime() - lastTime
;
489 lastTime
+= elapsedTime
;
494 for(i
=0; i
<dWisps
; i
++)
496 for(i
=0; i
<dBackground
; i
++)
497 _backwisps
[i
].update();
502 float feedbackIntensity
= float(dFeedback
) / 101.0f
;
504 // update feedback variables
507 fr
[i
] += elapsedTime
* fv
[i
];
511 f
[0] = 30.0f
* cos(fr
[0]);
512 f
[1] = 0.2f
* cos(fr
[1]);
513 f
[2] = 0.2f
* cos(fr
[2]);
514 f
[3] = 0.8f
* cos(fr
[3]);
517 lr
[i
] += elapsedTime
* lv
[i
];
524 // Create drawing area for feedback texture
525 glViewport(0, 0, feedbacktexsize
, feedbacktexsize
);
526 glMatrixMode(GL_PROJECTION
);
528 gluPerspective(30.0, aspectRatio
, 0.01f
, 20.0f
);
529 glMatrixMode(GL_MODELVIEW
);
532 glClear(GL_COLOR_BUFFER_BIT
);
533 glColor3f(feedbackIntensity
, feedbackIntensity
, feedbackIntensity
);
534 glBindTexture(GL_TEXTURE_2D
, feedbacktex
);
536 glTranslatef(f
[1] * l
[1], f
[2] * l
[1], f
[3] * l
[2]);
537 glRotatef(f
[0] * l
[0], 0, 0, 1);
538 glBegin(GL_TRIANGLE_STRIP
);
539 glTexCoord2f(-0.5f
, -0.5f
);
540 glVertex3f(-aspectRatio
*2.0f
, -2.0f
, 1.25f
);
541 glTexCoord2f(1.5f
, -0.5f
);
542 glVertex3f(aspectRatio
*2.0f
, -2.0f
, 1.25f
);
543 glTexCoord2f(-0.5f
, 1.5f
);
544 glVertex3f(-aspectRatio
*2.0f
, 2.0f
, 1.25f
);
545 glTexCoord2f(1.5f
, 1.5f
);
546 glVertex3f(aspectRatio
*2.0f
, 2.0f
, 1.25f
);
549 glBindTexture(GL_TEXTURE_2D
, texName
);
550 for(i
=0; i
<dBackground
; i
++)
551 _backwisps
[i
].drawAsBackground();
552 for(i
=0; i
<dWisps
; i
++)
555 // readback feedback texture
556 glReadBuffer(GL_BACK
);
557 glPixelStorei(GL_UNPACK_ROW_LENGTH
, feedbacktexsize
);
558 glBindTexture(GL_TEXTURE_2D
, feedbacktex
);
559 glReadPixels(0, 0, feedbacktexsize
, feedbacktexsize
, GL_RGB
, GL_UNSIGNED_BYTE
, feedbackmap
);
560 glTexSubImage2D(GL_TEXTURE_2D
, 0, 0, 0, feedbacktexsize
, feedbacktexsize
, GL_RGB
, GL_UNSIGNED_BYTE
, feedbackmap
);
562 // create regular drawing area
563 glViewport(viewport
[0], viewport
[1], viewport
[2], viewport
[3]);
564 glMatrixMode(GL_PROJECTION
);
566 gluPerspective(20.0, aspectRatio
, 0.01f
, 20.0f
);
567 glMatrixMode(GL_MODELVIEW
);
570 glClear(GL_COLOR_BUFFER_BIT
);
571 glColor3f(feedbackIntensity
, feedbackIntensity
, feedbackIntensity
);
573 glTranslatef(f
[1] * l
[1], f
[2] * l
[1], f
[3] * l
[2]);
574 glRotatef(f
[0] * l
[0], 0, 0, 1);
575 glBegin(GL_TRIANGLE_STRIP
);
576 glTexCoord2f(-0.5f
, -0.5f
);
577 glVertex3f(-aspectRatio
*2.0f
, -2.0f
, 1.25f
);
578 glTexCoord2f(1.5f
, -0.5f
);
579 glVertex3f(aspectRatio
*2.0f
, -2.0f
, 1.25f
);
580 glTexCoord2f(-0.5f
, 1.5f
);
581 glVertex3f(-aspectRatio
*2.0f
, 2.0f
, 1.25f
);
582 glTexCoord2f(1.5f
, 1.5f
);
583 glVertex3f(aspectRatio
*2.0f
, 2.0f
, 1.25f
);
587 glBindTexture(GL_TEXTURE_2D
, texName
);
590 glClear(GL_COLOR_BUFFER_BIT
);
593 for(i
=0; i
<dBackground
; i
++)
594 _backwisps
[i
].drawAsBackground();
595 for(i
=0; i
<dWisps
; i
++)
602 void EuphoriaWidget::resizeGL( int w
, int h
)
604 glViewport(0, 0, w
, h
);
611 aspectRatio
= (float) w
/ (float) h
;
613 // setup regular drawing area just in case feedback isn't used
614 glMatrixMode(GL_PROJECTION
);
616 gluPerspective(20.0, aspectRatio
, 0.01, 20);
617 glMatrixMode(GL_MODELVIEW
);
619 glTranslatef(0.0, 0.0, -5.0);
623 // Window initialization
624 void EuphoriaWidget::initializeGL()
626 // Need to call this to setup viewport[] parameters used in
627 // the next updateParameters() call
628 resizeGL( width(), height() );
632 _timer
->start( _frameTime
);
637 void EuphoriaWidget::keyPressEvent( QKeyEvent
* e
)
639 if( e
->key() == Qt::Key_0
) { setDefaults( 0 ); updateParameters(); }
640 if( e
->key() == Qt::Key_1
) { setDefaults( 1 ); updateParameters(); }
641 if( e
->key() == Qt::Key_2
) { setDefaults( 2 ); updateParameters(); }
642 if( e
->key() == Qt::Key_3
) { setDefaults( 3 ); updateParameters(); }
643 if( e
->key() == Qt::Key_4
) { setDefaults( 4 ); updateParameters(); }
644 if( e
->key() == Qt::Key_5
) { setDefaults( 5 ); updateParameters(); }
645 if( e
->key() == Qt::Key_6
) { setDefaults( 6 ); updateParameters(); }
646 if( e
->key() == Qt::Key_7
) { setDefaults( 7 ); updateParameters(); }
647 if( e
->key() == Qt::Key_8
) { setDefaults( 8 ); updateParameters(); }
652 void EuphoriaWidget::nextFrame()
655 _timer
->start( _frameTime
);
659 void EuphoriaWidget::updateParameters()
661 srand((unsigned)time(NULL
));
662 rand(); rand(); rand(); rand(); rand();
675 glClearColor(0.0f
, 0.0f
, 0.0f
, 1.0f
);
676 glClear(GL_COLOR_BUFFER_BIT
);
678 glBlendFunc(GL_ONE
, GL_ONE
);
681 // Commented out because smooth lines and textures don't mix on my TNT.
682 // It's like it rendering in software mode
683 glEnable(GL_LINE_SMOOTH
);
684 //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
688 int whichtex
= dTexture
;
689 if(whichtex
== 4) // random texture
690 whichtex
= myRandi(3) + 1;
691 glEnable(GL_TEXTURE_2D
);
692 glTexEnvf(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
693 // Initialize texture
694 glGenTextures(1, &texName
);
695 glBindTexture(GL_TEXTURE_2D
, texName
);
696 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
697 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR_MIPMAP_LINEAR
);
698 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_REPEAT
);
699 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_REPEAT
);
702 gluBuild2DMipmaps(GL_TEXTURE_2D
, 1, TEXSIZE
, TEXSIZE
, GL_LUMINANCE
, GL_UNSIGNED_BYTE
, plasmamap
);
705 gluBuild2DMipmaps(GL_TEXTURE_2D
, 1, TEXSIZE
, TEXSIZE
, GL_LUMINANCE
, GL_UNSIGNED_BYTE
, stringymap
);
708 gluBuild2DMipmaps(GL_TEXTURE_2D
, 1, TEXSIZE
, TEXSIZE
, GL_LUMINANCE
, GL_UNSIGNED_BYTE
, linesmap
);
710 } else if ( texName
) {
711 glDeleteTextures( 1, &texName
);
717 feedbacktexsize
= int(pow(2.0, dFeedbacksize
));
718 while(feedbacktexsize
> viewport
[2] || feedbacktexsize
> viewport
[3]){
720 feedbacktexsize
= int(pow(2.0, dFeedbacksize
));
723 // feedback texture setup
724 glEnable(GL_TEXTURE_2D
);
725 delete [] feedbackmap
;
726 feedbackmap
= new unsigned char[feedbacktexsize
*feedbacktexsize
*3];
727 glGenTextures(1, &feedbacktex
);
728 glBindTexture(GL_TEXTURE_2D
, feedbacktex
);
729 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
730 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
731 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP
);
732 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP
);
733 glTexImage2D(GL_TEXTURE_2D
, 0, 3, feedbacktexsize
, feedbacktexsize
, 0, GL_RGB
, GL_UNSIGNED_BYTE
, feedbackmap
);
735 // feedback velocity variable setup
736 fv
[0] = float(dFeedbackspeed
) * (myRandf(0.025f
) + 0.025f
);
737 fv
[1] = float(dFeedbackspeed
) * (myRandf(0.05f
) + 0.05f
);
738 fv
[2] = float(dFeedbackspeed
) * (myRandf(0.05f
) + 0.05f
);
739 fv
[3] = float(dFeedbackspeed
) * (myRandf(0.1f
) + 0.1f
);
740 lv
[0] = float(dFeedbackspeed
) * (myRandf(0.0025f
) + 0.0025f
);
741 lv
[1] = float(dFeedbackspeed
) * (myRandf(0.0025f
) + 0.0025f
);
742 lv
[2] = float(dFeedbackspeed
) * (myRandf(0.0025f
) + 0.0025f
);
743 } else if ( feedbacktex
) {
744 glDeleteTextures( 1, &feedbacktex
);
752 _wisps
= new wisp
[dWisps
];
753 _backwisps
= new wisp
[dBackground
];
758 May be called at any time - makes no OpenGL calls.
760 void EuphoriaWidget::setDefaults(int which
)
885 //----------------------------------------------------------------------------
894 // libkscreensaver interface
895 class KEuphoriaSaverInterface
: public KScreenSaverInterface
900 virtual KAboutData
* aboutData() {
901 return new KAboutData( "keuphoria.kss", 0, ki18n( "Euphoria" ), "1.0", ki18n( "Euphoria" ) );
905 virtual KScreenSaver
* create( WId id
)
907 return new KEuphoriaScreenSaver( id
);
910 virtual QDialog
* setup()
912 return new KEuphoriaSetup
;
916 int main( int argc
, char *argv
[] )
918 KEuphoriaSaverInterface kss
;
919 return kScreenSaverMain( argc
, argv
, kss
);
923 //----------------------------------------------------------------------------
926 KEuphoriaScreenSaver::KEuphoriaScreenSaver( WId id
) : KScreenSaver( id
)
928 _effect
= new EuphoriaWidget
;
937 KEuphoriaScreenSaver::~KEuphoriaScreenSaver()
942 static int filterRandom( int n
)
944 if( (n
< 0) || (n
>= EuphoriaWidget::DefaultModes
) )
946 srand((unsigned)time(NULL
));
947 n
= rand() % EuphoriaWidget::DefaultModes
;
953 void KEuphoriaScreenSaver::readSettings()
955 KConfigGroup
config(KGlobal::config(), "Settings");
957 _mode
= config
.readEntry( "Mode", (int)EuphoriaWidget::Regular
);
958 _effect
->setDefaults( filterRandom(_mode
) );
963 Any invalid mode will select one at random.
965 void KEuphoriaScreenSaver::setMode( int id
)
968 _effect
->setDefaults( filterRandom(id
) );
969 _effect
->updateParameters();
973 //----------------------------------------------------------------------------
978 #include <qcombobox.h>
979 #include <kmessagebox.h>
982 static const char* defaultText
[] =
984 I18N_NOOP( "Regular" ),
986 I18N_NOOP( "Cubism" ),
987 I18N_NOOP( "Bad Math" ),
988 I18N_NOOP( "M-Theory" ),
989 I18N_NOOP( "UHFTEM" ), //"ultra high frequency tunneling electron microscope",
990 I18N_NOOP( "Nowhere" ),
992 I18N_NOOP( "Kaleidoscope" ),
993 I18N_NOOP( "(Random)" ),
998 KEuphoriaSetup::KEuphoriaSetup( QWidget
* parent
)
1001 setCaption(i18n("Setup Euphoria Screen Saver"));
1002 setButtons(Ok
|Cancel
|Help
);
1003 setDefaultButton(Ok
);
1005 showButtonSeparator(true);
1006 setButtonText( Help
, i18n( "A&bout" ) );
1008 QWidget
*main
= new QWidget(this);
1009 setMainWidget(main
);
1011 QHBoxLayout
* top
= new QHBoxLayout( main
);
1012 top
->setSpacing( spacingHint() );
1013 QVBoxLayout
* leftCol
= new QVBoxLayout
;
1014 top
->addLayout( leftCol
);
1016 QLabel
* label
= new QLabel( i18n("Mode:"), main
);
1017 leftCol
->addWidget( label
);
1019 modeW
= new QComboBox( main
);
1021 while (defaultText
[i
])
1022 modeW
->addItem( i18n(defaultText
[i
++]) );
1023 leftCol
->addWidget( modeW
);
1025 leftCol
->addStretch();
1029 preview
= new QWidget( main
);
1030 preview
->setFixedSize( 220, 170 );
1033 palette
.setColor( preview
->backgroundRole(), Qt::black
);
1034 preview
->setPalette( palette
);
1036 preview
->show(); // otherwise saver does not get correct size
1037 _saver
= new KEuphoriaScreenSaver( preview
->winId() );
1038 top
->addWidget(preview
);
1040 // Now that we have _saver...
1041 modeW
->setCurrentIndex( _saver
->mode() ); // set before we connect
1042 connect( modeW
, SIGNAL(activated(int)), _saver
, SLOT(setMode(int)) );
1043 connect(this,SIGNAL(okClicked()),SLOT(slotOk()));
1044 connect(this,SIGNAL(helpClicked()),SLOT(slotHelp()));
1046 setMinimumSize( sizeHint() );
1050 KEuphoriaSetup::~KEuphoriaSetup()
1056 void KEuphoriaSetup::slotHelp()
1058 KMessageBox::about(this,
1059 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>"),
1060 QString(), KMessageBox::AllowLink
);
1065 Ok pressed - save settings and exit
1067 void KEuphoriaSetup::slotOk()
1069 KConfigGroup
config( KGlobal::config(), "Settings");
1071 config
.writeEntry("Mode", QString::number( modeW
->currentIndex() ) );
1077 //----------------------------------------------------------------------------
1081 // moc Euphoria.h -o Euphoria.moc
1082 // g++ -g -DUNIT_TEST Euphoria.cpp -I/usr/lib/qt3/include -lqt -L/usr/lib/qt3/lib -lGLU -lGL
1084 #include <qapplication.h>
1086 int main( int argc
, char** argv
)
1088 QApplication
app( argc
, argv
);
1091 w
.setDefaults( EuphoriaWidget::UHFTEM
);
1092 app
.setMainWidget( &w
);