1 //============================================================================
3 // Terence Welsh Screensaver - Euphoria
4 // http://www.reallyslick.com/
6 // Ported to KDE by Karl Robillard
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 //============================================================================
33 #include <QVBoxLayout>
34 #include <QHBoxLayout>
37 #include "Euphoria.moc"
38 #include "EuphoriaTexture.h"
42 #define PIx2 6.28318530718f
45 //----------------------------------------------------------------------------
52 // Returns the system time, in seconds.
56 gettimeofday( &tp
, 0 );
57 return (double)tp
.tv_sec
+ (double)tp
.tv_usec
/ 1000000;
61 //----------------------------------------------------------------------------
71 rsVec(float xx
, float yy
, float zz
);
73 void set(float xx
, float yy
, float zz
);
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
){
108 void rsVec::set(float xx
, float yy
, float zz
){
115 float rsVec::normalize(){
116 float length
= float(sqrt(v
[0] * v
[0] + v
[1] * v
[1] + v
[2] * v
[2]));
121 float reciprocal
= 1.0f
/ length
;
125 // Really freakin' stupid compiler bug fix for VC++ 5.0
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
)
151 if(h
< 0.166667){ // full red, some green
157 if(h
< 0.5){ // full green
159 if(h
< 0.333333){ // some red
160 r
= 1.0f
- ((h
- 0.166667f
) * 6.0f
);
164 b
= (h
- 0.333333f
) * 6.0f
;
169 if(h
< 0.833333){ // full blue
171 if(h
< 0.666667){ // some green
172 g
= 1.0f
- ((h
- 0.5f
) * 6.0f
);
176 r
= (h
- 0.666667f
) * 6.0f
;
180 else{ // full red, some blue
182 b
= 1.0f
- ((h
- 0.833333f
) * 6.0f
);
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
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;
225 void drawAsBackground();
230 float c
[NUMCONSTS
]; // constants
231 float cr
[NUMCONSTS
]; // constants' radial position
232 float cv
[NUMCONSTS
]; // constants' change velocities
236 float saturationSpeed
;
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
);
271 hsl
[0] = myRandf(1.0f
);
272 hsl
[1] = 0.1f
+ myRandf(0.9f
);
274 hueSpeed
= myRandf(0.1f
) - 0.05f
;
275 saturationSpeed
= myRandf(0.04f
) + 0.001f
;
283 for(i
=0; i
<=density
; i
++)
285 for(j
=0; j
<=density
; j
++)
287 delete[] vertices
[i
][j
];
289 delete[] vertices
[i
];
298 rsVec up
, right
, crossvec
;
299 // visibility constants
300 static float viscon1
= float(_ec
->dVisibility
) * 0.01f
;
301 static float viscon2
= 1.0f
/ viscon1
;
304 for(i
=0; i
<NUMCONSTS
; i
++){
305 cr
[i
] += cv
[i
] * _ec
->elapsedTime
;
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]);
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
;
348 hsl
[0] += hueSpeed
* _ec
->elapsedTime
;
353 hsl
[1] += saturationSpeed
* _ec
->elapsedTime
;
356 saturationSpeed
= -saturationSpeed
;
360 saturationSpeed
= -saturationSpeed
;
362 hsl2rgb(hsl
[0], hsl
[1], hsl
[2], rgb
[0], rgb
[1], rgb
[2]);
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
]);
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
]);
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
]);
413 void wisp::drawAsBackground()
418 glTranslatef(c
[0] * 0.2f
, c
[1] * 0.2f
, 1.6f
);
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]);
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]);
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]);
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()
480 glDeleteTextures( 1, &texName
);
482 glDeleteTextures( 1, &feedbacktex
);
488 void EuphoriaWidget::paintGL()
491 static double lastTime
= timeGetTime();
494 elapsedTime
= timeGetTime() - lastTime
;
495 lastTime
+= elapsedTime
;
500 for(i
=0; i
<dWisps
; i
++)
502 for(i
=0; i
<dBackground
; i
++)
503 _backwisps
[i
].update();
508 float feedbackIntensity
= float(dFeedback
) / 101.0f
;
510 // update feedback variables
513 fr
[i
] += elapsedTime
* fv
[i
];
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]);
523 lr
[i
] += elapsedTime
* lv
[i
];
530 // Create drawing area for feedback texture
531 glViewport(0, 0, feedbacktexsize
, feedbacktexsize
);
532 glMatrixMode(GL_PROJECTION
);
534 gluPerspective(30.0, aspectRatio
, 0.01f
, 20.0f
);
535 glMatrixMode(GL_MODELVIEW
);
538 glClear(GL_COLOR_BUFFER_BIT
);
539 glColor3f(feedbackIntensity
, feedbackIntensity
, feedbackIntensity
);
540 glBindTexture(GL_TEXTURE_2D
, feedbacktex
);
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
);
555 glBindTexture(GL_TEXTURE_2D
, texName
);
556 for(i
=0; i
<dBackground
; i
++)
557 _backwisps
[i
].drawAsBackground();
558 for(i
=0; i
<dWisps
; i
++)
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
);
572 gluPerspective(20.0, aspectRatio
, 0.01f
, 20.0f
);
573 glMatrixMode(GL_MODELVIEW
);
576 glClear(GL_COLOR_BUFFER_BIT
);
577 glColor3f(feedbackIntensity
, feedbackIntensity
, feedbackIntensity
);
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
);
593 glBindTexture(GL_TEXTURE_2D
, texName
);
596 glClear(GL_COLOR_BUFFER_BIT
);
599 for(i
=0; i
<dBackground
; i
++)
600 _backwisps
[i
].drawAsBackground();
601 for(i
=0; i
<dWisps
; i
++)
608 void EuphoriaWidget::resizeGL( int w
, int h
)
610 glViewport(0, 0, w
, h
);
617 aspectRatio
= (float) w
/ (float) h
;
619 // setup regular drawing area just in case feedback isn't used
620 glMatrixMode(GL_PROJECTION
);
622 gluPerspective(20.0, aspectRatio
, 0.01, 20);
623 glMatrixMode(GL_MODELVIEW
);
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() );
638 _timer
->start( _frameTime
, true );
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(); }
658 void EuphoriaWidget::nextFrame()
661 _timer
->start( _frameTime
, true );
665 void EuphoriaWidget::updateParameters()
667 srand((unsigned)time(NULL
));
668 rand(); rand(); rand(); rand(); rand();
681 glClearColor(0.0f
, 0.0f
, 0.0f
, 1.0f
);
682 glClear(GL_COLOR_BUFFER_BIT
);
684 glBlendFunc(GL_ONE
, GL_ONE
);
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);
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
);
708 gluBuild2DMipmaps(GL_TEXTURE_2D
, 1, TEXSIZE
, TEXSIZE
, GL_LUMINANCE
, GL_UNSIGNED_BYTE
, plasmamap
);
711 gluBuild2DMipmaps(GL_TEXTURE_2D
, 1, TEXSIZE
, TEXSIZE
, GL_LUMINANCE
, GL_UNSIGNED_BYTE
, stringymap
);
714 gluBuild2DMipmaps(GL_TEXTURE_2D
, 1, TEXSIZE
, TEXSIZE
, GL_LUMINANCE
, GL_UNSIGNED_BYTE
, linesmap
);
716 } else if ( texName
) {
717 glDeleteTextures( 1, &texName
);
723 feedbacktexsize
= int(pow(2, dFeedbacksize
));
724 while(feedbacktexsize
> viewport
[2] || feedbacktexsize
> viewport
[3]){
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
);
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
)
891 //----------------------------------------------------------------------------
900 // libkscreensaver interface
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
;
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
;
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
)
965 _effect
->setDefaults( filterRandom(id
) );
966 _effect
->updateParameters();
970 //----------------------------------------------------------------------------
975 #include <qcombobox.h>
976 #include <kmessagebox.h>
979 static const char* defaultText
[] =
981 I18N_NOOP( "Regular" ),
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" ),
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
);
1012 while (defaultText
[i
])
1013 modeW
->insertItem( i18n(defaultText
[i
++]) );
1014 leftCol
->addWidget( modeW
);
1016 leftCol
->addStretch();
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()
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");
1058 val
.setNum( modeW
->currentItem() );
1059 config
->writeEntry("Mode", val
);
1065 //----------------------------------------------------------------------------
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
);
1079 w
.setDefaults( EuphoriaWidget::UHFTEM
);
1080 app
.setMainWidget( &w
);