//============================================================================
//
// Terence Welsh Screensaver - Flux
// http://www.reallyslick.com/
//
// Ported to KDE by Karl Robillard
//
/*
* Copyright ( C ) 2002 Terence M . Welsh
*
* Flux is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* Flux is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
//============================================================================
/*
TODO
[ ] Regular and others are messed up after Sparkler .
Insane seems to reset them .
*/
# include <stdio.h>
# include <stdlib.h>
# include <math.h>
# include <time.h>
# include <tqtimer.h>
# include "Flux.h"
# include "Flux.moc"
# define NUMCONSTS 8
# define PIx2 6.28318530718f
# define DEG2RAD 0.0174532925f
void hsl2rgb ( float h , float s , float l , float & r , float & g , float & b )
{
// hue influence
if ( h < 0.166667 ) { // full red, some green
r = 1.0 ;
g = h * 6.0f ;
b = 0.0 ;
}
else {
if ( h < 0.5 ) { // full green
g = 1.0 ;
if ( h < 0.333333 ) { // some red
r = 1.0f - ( ( h - 0.166667f ) * 6.0f ) ;
b = 0.0 ;
}
else { // some blue
b = ( h - 0.333333f ) * 6.0f ;
r = 0.0 ;
}
}
else {
if ( h < 0.833333 ) { // full blue
b = 1.0 ;
if ( h < 0.666667 ) { // some green
g = 1.0f - ( ( h - 0.5f ) * 6.0f ) ;
r = 0.0 ;
}
else { // some red
r = ( h - 0.666667f ) * 6.0f ;
g = 0.0 ;
}
}
else { // full red, some blue
r = 1.0 ;
b = 1.0f - ( ( h - 0.833333f ) * 6.0f ) ;
g = 0.0 ;
}
}
}
// saturation influence
r = 1.0f - ( s * ( 1.0f - r ) ) ;
g = 1.0f - ( s * ( 1.0f - g ) ) ;
b = 1.0f - ( s * ( 1.0f - b ) ) ;
// luminosity influence
r * = l ;
g * = l ;
b * = l ;
}
// Useful random number macros
// Don't forget to initialize with srand()
inline int myRandi ( int x ) {
return ( ( rand ( ) * x ) / RAND_MAX ) ;
}
inline float myRandf ( float x ) {
return ( float ( rand ( ) * x ) / float ( RAND_MAX ) ) ;
}
//----------------------------------------------------------------------------
// Flux context to allow many instances.
static FluxWidget * _fc = 0 ;
static int whichparticle ;
// This class is poorly named. It's actually a whole trail of particles.
class particle
{
public :
particle ( ) ;
~ particle ( ) ;
float update ( float * c ) ;
private :
float * * vertices ;
short trails ;
short counter ;
float offset [ 3 ] ;
} ;
particle : : particle ( )
{
// Offsets are somewhat like default positions for the head of each
// particle trail. Offsets spread out the particle trails and keep
// them from all overlapping.
offset [ 0 ] = cos ( PIx2 * float ( whichparticle ) / float ( _fc - > dParticles ) ) ;
offset [ 1 ] = float ( whichparticle ) / float ( _fc - > dParticles ) - 0.5f ;
offset [ 2 ] = sin ( PIx2 * float ( whichparticle ) / float ( _fc - > dParticles ) ) ;
whichparticle + + ;
// Initialize memory and set initial positions out of view of the camera
trails = _fc - > dTrail ;
vertices = new float * [ trails ] ;
int i ;
for ( i = 0 ; i < trails ; i + + )
{
vertices [ i ] = new float [ 5 ] ; // 0,1,2 = position, 3 = hue, 4 = saturation
vertices [ i ] [ 0 ] = 0.0f ;
vertices [ i ] [ 1 ] = 3.0f ;
vertices [ i ] [ 2 ] = 0.0f ;
vertices [ i ] [ 3 ] = 0.0f ;
vertices [ i ] [ 4 ] = 0.0f ;
}
counter = 0 ;
}
particle : : ~ particle ( )
{
for ( int i = 0 ; i < trails ; i + + )
delete [ ] vertices [ i ] ;
delete [ ] vertices ;
}
float particle : : update ( float * c )
{
int i , p , growth ;
float rgb [ 3 ] ;
float cx , cy , cz ; // Containment variables
float luminosity ;
static float expander = 1.0f + 0.0005f * float ( _fc - > dExpansion ) ;
static float blower = 0.001f * float ( _fc - > dWind ) ;
//static float otherxyz[3];
float depth = 0 ;
// Record old position
int oldc = counter ;
float oldpos [ 3 ] ;
oldpos [ 0 ] = vertices [ oldc ] [ 0 ] ;
oldpos [ 1 ] = vertices [ oldc ] [ 1 ] ;
oldpos [ 2 ] = vertices [ oldc ] [ 2 ] ;
counter + + ;
if ( counter > = _fc - > dTrail )
counter = 0 ;
// Here's the iterative math for calculating new vertex positions
// first calculate limiting terms which keep vertices from constantly
// flying off to infinity
cx = vertices [ oldc ] [ 0 ] * ( 1.0f - 1.0f / ( vertices [ oldc ] [ 0 ] * vertices [ oldc ] [ 0 ] + 1.0f ) ) ;
cy = vertices [ oldc ] [ 1 ] * ( 1.0f - 1.0f / ( vertices [ oldc ] [ 1 ] * vertices [ oldc ] [ 1 ] + 1.0f ) ) ;
cz = vertices [ oldc ] [ 2 ] * ( 1.0f - 1.0f / ( vertices [ oldc ] [ 2 ] * vertices [ oldc ] [ 2 ] + 1.0f ) ) ;
// then calculate new positions
vertices [ counter ] [ 0 ] = vertices [ oldc ] [ 0 ] + c [ 6 ] * offset [ 0 ] - cx
+ c [ 2 ] * vertices [ oldc ] [ 1 ]
+ c [ 5 ] * vertices [ oldc ] [ 2 ] ;
vertices [ counter ] [ 1 ] = vertices [ oldc ] [ 1 ] + c [ 6 ] * offset [ 1 ] - cy
+ c [ 1 ] * vertices [ oldc ] [ 2 ]
+ c [ 4 ] * vertices [ oldc ] [ 0 ] ;
vertices [ counter ] [ 2 ] = vertices [ oldc ] [ 2 ] + c [ 6 ] * offset [ 2 ] - cz
+ c [ 0 ] * vertices [ oldc ] [ 0 ]
+ c [ 3 ] * vertices [ oldc ] [ 1 ] ;
// Pick a hue
vertices [ counter ] [ 3 ] = cx * cx + cy * cy + cz * cz ;
if ( vertices [ counter ] [ 3 ] > 1.0f )
vertices [ counter ] [ 3 ] = 1.0f ;
vertices [ counter ] [ 3 ] + = c [ 7 ] ;
// Limit the hue (0 - 1)
if ( vertices [ counter ] [ 3 ] > 1.0f )
vertices [ counter ] [ 3 ] - = 1.0f ;
if ( vertices [ counter ] [ 3 ] < 0.0f )
vertices [ counter ] [ 3 ] + = 1.0f ;
// Pick a saturation
vertices [ counter ] [ 4 ] = c [ 0 ] + vertices [ counter ] [ 3 ] ;
// Limit the saturation (0 - 1)
if ( vertices [ counter ] [ 4 ] < 0.0f )
vertices [ counter ] [ 4 ] = - vertices [ counter ] [ 4 ] ;
vertices [ counter ] [ 4 ] - = float ( int ( vertices [ counter ] [ 4 ] ) ) ;
vertices [ counter ] [ 4 ] = 1.0f - ( vertices [ counter ] [ 4 ] * vertices [ counter ] [ 4 ] ) ;
// Bring particles back if they escape
if ( ! counter ) {
if ( ( vertices [ 0 ] [ 0 ] > 1000000000.0f ) | | ( vertices [ 0 ] [ 0 ] < - 1000000000.0f )
| | ( vertices [ 0 ] [ 1 ] > 1000000000.0f ) | | ( vertices [ 0 ] [ 1 ] < - 1000000000.0f )
| | ( vertices [ 2 ] [ 2 ] > 1000000000.0f ) | | ( vertices [ 0 ] [ 2 ] < - 1000000000.0f ) ) {
vertices [ 0 ] [ 0 ] = myRandf ( 2.0f ) - 1.0f ;
vertices [ 0 ] [ 1 ] = myRandf ( 2.0f ) - 1.0f ;
vertices [ 0 ] [ 2 ] = myRandf ( 2.0f ) - 1.0f ;
}
}
// Draw every vertex in particle trail
p = counter ;
growth = 0 ;
luminosity = _fc - > lumdiff ;
for ( i = 0 ; i < _fc - > dTrail ; i + + ) {
p + + ;
if ( p > = _fc - > dTrail )
p = 0 ;
growth + + ;
// assign color to particle
hsl2rgb ( vertices [ p ] [ 3 ] , vertices [ p ] [ 4 ] , luminosity , rgb [ 0 ] , rgb [ 1 ] , rgb [ 2 ] ) ;
glColor3fv ( rgb ) ;
glPushMatrix ( ) ;
if ( _fc - > dGeometry = = 1 ) // Spheres
glTranslatef ( vertices [ p ] [ 0 ] , vertices [ p ] [ 1 ] , vertices [ p ] [ 2 ] ) ;
else { // Points or lights
depth = _fc - > cosCameraAngle * vertices [ p ] [ 2 ] - _fc - > sinCameraAngle * vertices [ p ] [ 0 ] ;
glTranslatef ( _fc - > cosCameraAngle * vertices [ p ] [ 0 ] + _fc - > sinCameraAngle
* vertices [ p ] [ 2 ] , vertices [ p ] [ 1 ] , depth ) ;
}
if ( _fc - > dGeometry ) { // Spheres or lights
switch ( _fc - > dTrail - growth ) {
case 0 :
glScalef ( 0.259f , 0.259f , 0.259f ) ;
break ;
case 1 :
glScalef ( 0.5f , 0.5f , 0.5f ) ;
break ;
case 2 :
glScalef ( 0.707f , 0.707f , 0.707f ) ;
break ;
case 3 :
glScalef ( 0.866f , 0.866f , 0.866f ) ;
break ;
case 4 :
glScalef ( 0.966f , 0.966f , 0.966f ) ;
}
}
switch ( _fc - > dGeometry ) {
case 0 : // Points
switch ( _fc - > dTrail - growth ) {
case 0 :
glPointSize ( float ( _fc - > dSize * ( depth + 200.0f ) * 0.001036f ) ) ;
break ;
case 1 :
glPointSize ( float ( _fc - > dSize * ( depth + 200.0f ) * 0.002f ) ) ;
break ;
case 2 :
glPointSize ( float ( _fc - > dSize * ( depth + 200.0f ) * 0.002828f ) ) ;
break ;
case 3 :
glPointSize ( float ( _fc - > dSize * ( depth + 200.0f ) * 0.003464f ) ) ;
break ;
case 4 :
glPointSize ( float ( _fc - > dSize * ( depth + 200.0f ) * 0.003864f ) ) ;
break ;
default :
glPointSize ( float ( _fc - > dSize * ( depth + 200.0f ) * 0.004f ) ) ;
}
glBegin ( GL_POINTS ) ;
glVertex3f ( 0.0f , 0.0f , 0.0f ) ;
glEnd ( ) ;
break ;
case 1 : // Spheres
case 2 : // Lights
glCallList ( 1 ) ;
}
glPopMatrix ( ) ;
vertices [ p ] [ 0 ] * = expander ;
vertices [ p ] [ 1 ] * = expander ;
vertices [ p ] [ 2 ] * = expander ;
vertices [ p ] [ 2 ] + = blower ;
luminosity + = _fc - > lumdiff ;
}
// Find distance between new position and old position and return it
oldpos [ 0 ] - = vertices [ counter ] [ 0 ] ;
oldpos [ 1 ] - = vertices [ counter ] [ 1 ] ;
oldpos [ 2 ] - = vertices [ counter ] [ 2 ] ;
return ( float ( sqrt ( oldpos [ 0 ] * oldpos [ 0 ] + oldpos [ 1 ] * oldpos [ 1 ] + oldpos [ 2 ] * oldpos [ 2 ] ) ) ) ;
}
// This class is a set of particle trails and constants that enter
// into their equations of motion.
class flux
{
public :
flux ( ) ;
~ flux ( ) ;
void update ( ) ;
particle * particles ;
int randomize ;
float c [ NUMCONSTS ] ; // constants
float cv [ NUMCONSTS ] ; // constants' change velocities
int currentSmartConstant ;
float oldDistance ;
} ;
flux : : flux ( )
{
whichparticle = 0 ;
particles = new particle [ _fc - > dParticles ] ;
randomize = 1 ;
float instability = _fc - > dInstability ;
int i ;
for ( i = 0 ; i < NUMCONSTS ; i + + )
{
c [ i ] = myRandf ( 2.0f ) - 1.0f ;
cv [ i ] = myRandf ( 0.000005f * instability * instability )
+ 0.000001f * instability * instability ;
}
currentSmartConstant = 0 ;
oldDistance = 0.0f ;
}
flux : : ~ flux ( )
{
delete [ ] particles ;
}
void flux : : update ( )
{
int i ;
// randomize constants
if ( _fc - > dRandomize ) {
randomize - - ;
if ( randomize < = 0 ) {
for ( i = 0 ; i < NUMCONSTS ; i + + )
c [ i ] = myRandf ( 2.0f ) - 1.0f ;
int temp = 101 - _fc - > dRandomize ;
temp = temp * temp ;
randomize = temp + myRandi ( temp ) ;
}
}
// update constants
for ( i = 0 ; i < NUMCONSTS ; i + + ) {
c [ i ] + = cv [ i ] ;
if ( c [ i ] > = 1.0f ) {
c [ i ] = 1.0f ;
cv [ i ] = - cv [ i ] ;
}
if ( c [ i ] < = - 1.0f ) {
c [ i ] = - 1.0f ;
cv [ i ] = - cv [ i ] ;
}
}
// update all particles in this flux field
float dist ;
for ( i = 0 ; i < _fc - > dParticles ; i + + )
dist = particles [ i ] . update ( c ) ;
// use dist from last particle to activate smart constants
_fc - > dSmart = 0 ;
if ( _fc - > dSmart ) {
const float upper = 0.4f ;
const float lower = 0.2f ;
int beSmart = 0 ;
if ( dist > upper & & dist > oldDistance )
beSmart = 1 ;
if ( dist < lower & & dist < oldDistance )
beSmart = 1 ;
if ( beSmart ) {
cv [ currentSmartConstant ] = - cv [ currentSmartConstant ] ;
currentSmartConstant + + ;
if ( currentSmartConstant > = _fc - > dSmart )
currentSmartConstant = 0 ;
}
oldDistance = dist ;
}
}
//----------------------------------------------------------------------------
FluxWidget : : FluxWidget ( TQWidget * parent , const char * name )
: TQGLWidget ( parent , name ) , _fluxes ( 0 )
{
setDefaults ( Regular ) ;
_frameTime = 1000 / 60 ;
_timer = new TQTimer ( this ) ;
connect ( _timer , TQT_SIGNAL ( timeout ( ) ) , this , TQT_SLOT ( nextFrame ( ) ) ) ;
}
FluxWidget : : ~ FluxWidget ( )
{
// Free memory
delete [ ] _fluxes ;
}
void FluxWidget : : paintGL ( )
{
// clear the screen
glLoadIdentity ( ) ;
if ( dBlur ) // partially
{
int viewport [ 4 ] ;
glGetIntegerv ( GL_VIEWPORT , viewport ) ;
float viewRatio = float ( viewport [ 2 ] ) / float ( viewport [ 3 ] ) ;
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
glEnable ( GL_BLEND ) ;
glDisable ( GL_DEPTH_TEST ) ;
glColor4f ( 0.0f , 0.0f , 0.0f , 0.5f - ( float ( sqrt ( sqrt ( double ( dBlur ) ) ) ) * 0.15495f ) ) ;
glBegin ( GL_TRIANGLE_STRIP ) ;
glVertex3f ( - 3.0f * viewRatio , - 3.0f , 0.0f ) ;
glVertex3f ( 3.0f * viewRatio , - 3.0f , 0.0f ) ;
glVertex3f ( - 3.0f * viewRatio , 3.0f , 0.0f ) ;
glVertex3f ( 3.0f * viewRatio , 3.0f , 0.0f ) ;
glEnd ( ) ;
}
else // completely
{
glClear ( GL_COLOR_BUFFER_BIT ) ;
}
cameraAngle + = 0.01f * float ( dRotation ) ;
if ( cameraAngle > = 360.0f )
cameraAngle - = 360.0f ;
if ( dGeometry = = 1 ) // Only rotate for spheres
glRotatef ( cameraAngle , 0.0f , 1.0f , 0.0f ) ;
else
{
cosCameraAngle = cos ( cameraAngle * DEG2RAD ) ;
sinCameraAngle = sin ( cameraAngle * DEG2RAD ) ;
}
// set up blend modes for rendering particles
switch ( dGeometry )
{
case 0 : // Blending for points
glBlendFunc ( GL_SRC_ALPHA , GL_ONE ) ;
glEnable ( GL_BLEND ) ;
glEnable ( GL_POINT_SMOOTH ) ;
glHint ( GL_POINT_SMOOTH_HINT , GL_NICEST ) ;
break ;
case 1 : // No blending for spheres, but we need z-buffering
glDisable ( GL_BLEND ) ;
glEnable ( GL_DEPTH_TEST ) ;
glClear ( GL_DEPTH_BUFFER_BIT ) ;
break ;
case 2 : // Blending for lights
glBlendFunc ( GL_ONE , GL_ONE ) ;
glEnable ( GL_BLEND ) ;
}
// Update particles
if ( _fluxes )
{
_fc = this ;
int i ;
for ( i = 0 ; i < dFluxes ; i + + )
_fluxes [ i ] . update ( ) ;
}
glFlush ( ) ;
}
void FluxWidget : : resizeGL ( int w , int h )
{
glViewport ( 0 , 0 , w , h ) ;
glMatrixMode ( GL_PROJECTION ) ;
glLoadIdentity ( ) ;
gluPerspective ( 100.0 , ( float ) w / ( float ) h , 0.01 , 200 ) ;
glTranslatef ( 0.0 , 0.0 , - 2.5 ) ;
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity ( ) ;
}
// Window initialization
void FluxWidget : : initializeGL ( )
{
//resizeGL( width(), height() );
updateParameters ( ) ;
_timer - > start ( _frameTime , true ) ;
}
# ifdef UNIT_TEST
void FluxWidget : : keyPressEvent ( TQKeyEvent * e )
{
if ( e - > key ( ) = = Qt : : Key_0 ) { setDefaults ( 0 ) ; updateParameters ( ) ; }
if ( e - > key ( ) = = Qt : : Key_1 ) { setDefaults ( 1 ) ; updateParameters ( ) ; }
if ( e - > key ( ) = = Qt : : Key_2 ) { setDefaults ( 2 ) ; updateParameters ( ) ; }
if ( e - > key ( ) = = Qt : : Key_3 ) { setDefaults ( 3 ) ; updateParameters ( ) ; }
if ( e - > key ( ) = = Qt : : Key_4 ) { setDefaults ( 4 ) ; updateParameters ( ) ; }
if ( e - > key ( ) = = Qt : : Key_5 ) { setDefaults ( 5 ) ; updateParameters ( ) ; }
}
# endif
void FluxWidget : : nextFrame ( )
{
updateGL ( ) ;
_timer - > start ( _frameTime , true ) ;
}
/**
May be called at any time - makes no OpenGL calls .
*/
void FluxWidget : : setDefaults ( int which )
{
switch ( which )
{
case Hypnotic :
dFluxes = 2 ;
dParticles = 10 ;
dTrail = 40 ;
dGeometry = 2 ;
dSize = 15 ;
dRandomize = 80 ;
dExpansion = 20 ;
dRotation = 0 ;
dWind = 40 ;
dInstability = 10 ;
dBlur = 30 ;
break ;
case Insane :
dFluxes = 4 ;
dParticles = 30 ;
dTrail = 8 ;
dGeometry = 2 ;
dSize = 25 ;
dRandomize = 0 ;
dExpansion = 80 ;
dRotation = 60 ;
dWind = 40 ;
dInstability = 100 ;
dBlur = 10 ;
break ;
case Sparklers :
dFluxes = 3 ;
dParticles = 20 ;
dTrail = 6 ;
dGeometry = 1 ;
dSize = 20 ;
dComplexity = 3 ;
dRandomize = 85 ;
dExpansion = 60 ;
dRotation = 30 ;
dWind = 20 ;
dInstability = 30 ;
dBlur = 0 ;
break ;
case Paradigm :
dFluxes = 1 ;
dParticles = 40 ;
dTrail = 40 ;
dGeometry = 2 ;
dSize = 5 ;
dRandomize = 90 ;
dExpansion = 30 ;
dRotation = 20 ;
dWind = 10 ;
dInstability = 5 ;
dBlur = 10 ;
break ;
case Galactic :
dFluxes = 1 ;
dParticles = 2 ;
dTrail = 1500 ;
dGeometry = 2 ;
dSize = 10 ;
dRandomize = 0 ;
dExpansion = 5 ;
dRotation = 25 ;
dWind = 0 ;
dInstability = 5 ;
dBlur = 0 ;
break ;
case Regular :
default :
dFluxes = 1 ;
dParticles = 20 ;
dTrail = 40 ;
dGeometry = 2 ;
dSize = 15 ;
dRandomize = 0 ;
dExpansion = 40 ;
dRotation = 30 ;
dWind = 20 ;
dInstability = 20 ;
dBlur = 0 ;
break ;
}
}
/**
Called after dGeometry , dTrail , or dFluxes is changed
( such as with setDefaults ) .
*/
void FluxWidget : : updateParameters ( )
{
int i , j ;
float x , y , temp ;
srand ( ( unsigned ) time ( NULL ) ) ;
rand ( ) ; rand ( ) ; rand ( ) ; rand ( ) ; rand ( ) ;
cameraAngle = 0.0f ;
glFrontFace ( GL_CCW ) ;
glEnable ( GL_CULL_FACE ) ;
glClearColor ( 0.0f , 0.0f , 0.0f , 1.0f ) ;
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
if ( dGeometry = = 0 )
{
glDisable ( GL_LIGHTING ) ;
glDisable ( GL_COLOR_MATERIAL ) ;
glDisable ( GL_TEXTURE_2D ) ;
glEnable ( GL_POINT_SMOOTH ) ;
//glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
}
else if ( dGeometry = = 1 ) // Spheres and their lighting
{
glNewList ( 1 , GL_COMPILE ) ;
GLUquadricObj * qobj = gluNewQuadric ( ) ;
gluSphere ( qobj , 0.005f * dSize , dComplexity + 2 , dComplexity + 1 ) ;
gluDeleteQuadric ( qobj ) ;
glEndList ( ) ;
glDisable ( GL_TEXTURE_2D ) ;
glEnable ( GL_LIGHTING ) ;
glEnable ( GL_LIGHT0 ) ;
float ambient [ 4 ] = { 0.0f , 0.0f , 0.0f , 0.0f } ;
float diffuse [ 4 ] = { 1.0f , 1.0f , 1.0f , 0.0f } ;
float specular [ 4 ] = { 1.0f , 1.0f , 1.0f , 0.0f } ;
float position [ 4 ] = { 500.0f , 500.0f , 500.0f , 0.0f } ;
glLightfv ( GL_LIGHT0 , GL_AMBIENT , ambient ) ;
glLightfv ( GL_LIGHT0 , GL_DIFFUSE , diffuse ) ;
glLightfv ( GL_LIGHT0 , GL_SPECULAR , specular ) ;
glLightfv ( GL_LIGHT0 , GL_POSITION , position ) ;
glEnable ( GL_COLOR_MATERIAL ) ;
glColorMaterial ( GL_FRONT , GL_AMBIENT_AND_DIFFUSE ) ;
}
else if ( dGeometry = = 2 ) // Init lights
{
for ( i = 0 ; i < LIGHTSIZE ; i + + )
{
for ( j = 0 ; j < LIGHTSIZE ; j + + )
{
x = float ( i - LIGHTSIZE / 2 ) / float ( LIGHTSIZE / 2 ) ;
y = float ( j - LIGHTSIZE / 2 ) / float ( LIGHTSIZE / 2 ) ;
temp = 1.0f - float ( sqrt ( ( x * x ) + ( y * y ) ) ) ;
if ( temp > 1.0f )
temp = 1.0f ;
if ( temp < 0.0f )
temp = 0.0f ;
lightTexture [ i ] [ j ] = ( unsigned char ) ( 255.0f * temp * temp ) ;
}
}
glDisable ( GL_LIGHTING ) ;
glDisable ( GL_COLOR_MATERIAL ) ;
glEnable ( GL_TEXTURE_2D ) ;
glBindTexture ( GL_TEXTURE_2D , 1 ) ;
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_MODULATE ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
glTexImage2D ( GL_TEXTURE_2D , 0 , 1 , LIGHTSIZE , LIGHTSIZE , 0 ,
GL_LUMINANCE , GL_UNSIGNED_BYTE , lightTexture ) ;
temp = float ( dSize ) * 0.005f ;
glNewList ( 1 , GL_COMPILE ) ;
glBindTexture ( GL_TEXTURE_2D , 1 ) ;
glBegin ( GL_TRIANGLES ) ;
glTexCoord2f ( 0.0f , 0.0f ) ;
glVertex3f ( - temp , - temp , 0.0f ) ;
glTexCoord2f ( 1.0f , 0.0f ) ;
glVertex3f ( temp , - temp , 0.0f ) ;
glTexCoord2f ( 1.0f , 1.0f ) ;
glVertex3f ( temp , temp , 0.0f ) ;
glTexCoord2f ( 0.0f , 0.0f ) ;
glVertex3f ( - temp , - temp , 0.0f ) ;
glTexCoord2f ( 1.0f , 1.0f ) ;
glVertex3f ( temp , temp , 0.0f ) ;
glTexCoord2f ( 0.0f , 1.0f ) ;
glVertex3f ( - temp , temp , 0.0f ) ;
glEnd ( ) ;
glEndList ( ) ;
}
// Initialize luminosity difference
lumdiff = 1.0f / float ( dTrail ) ;
_fc = this ;
delete [ ] _fluxes ;
_fluxes = new flux [ dFluxes ] ;
}
//----------------------------------------------------------------------------
# ifndef UNIT_TEST
# include <klocale.h>
# include <kglobal.h>
# include <kconfig.h>
// libkscreensaver interface
extern " C "
{
KDE_EXPORT const char * kss_applicationName = " kflux.kss " ;
KDE_EXPORT const char * kss_description = I18N_NOOP ( " Flux " ) ;
KDE_EXPORT const char * kss_version = " 1.0 " ;
KDE_EXPORT KScreenSaver * kss_create ( WId id )
{
return new KFluxScreenSaver ( id ) ;
}
KDE_EXPORT TQDialog * kss_setup ( )
{
return new KFluxSetup ;
}
}
//----------------------------------------------------------------------------
KFluxScreenSaver : : KFluxScreenSaver ( WId id ) : KScreenSaver ( id )
{
_flux = new FluxWidget ;
readSettings ( ) ;
embed ( _flux ) ;
_flux - > show ( ) ;
}
KFluxScreenSaver : : ~ KFluxScreenSaver ( )
{
}
static int filterRandom ( int n )
{
if ( ( n < 0 ) | | ( n > = FluxWidget : : DefaultModes ) )
{
srand ( ( unsigned ) time ( NULL ) ) ;
n = rand ( ) % FluxWidget : : DefaultModes ;
}
return n ;
}
void KFluxScreenSaver : : readSettings ( )
{
KConfig * config = KGlobal : : config ( ) ;
config - > setGroup ( " Settings " ) ;
_mode = config - > readNumEntry ( " Mode " , FluxWidget : : Regular ) ;
_flux - > setDefaults ( filterRandom ( _mode ) ) ;
}
/**
Any invalid mode will select one at random .
*/
void KFluxScreenSaver : : setMode ( int id )
{
_mode = id ;
_flux - > setDefaults ( filterRandom ( id ) ) ;
_flux - > updateParameters ( ) ;
}
//----------------------------------------------------------------------------
# include <tqlayout.h>
# include <tqpushbutton.h>
# include <tqlabel.h>
# include <tqcombobox.h>
# include <kbuttonbox.h>
# include <kmessagebox.h>
static const char * defaultText [ ] =
{
I18N_NOOP ( " Regular " ) ,
I18N_NOOP ( " Hypnotic " ) ,
I18N_NOOP ( " Insane " ) ,
I18N_NOOP ( " Sparklers " ) ,
I18N_NOOP ( " Paradigm " ) ,
I18N_NOOP ( " Galactic " ) ,
I18N_NOOP ( " (Random) " ) ,
0
} ;
KFluxSetup : : KFluxSetup ( TQWidget * parent , const char * name )
: KDialogBase ( parent , name , true , i18n ( " Setup Flux Screen Saver " ) ,
Ok | Cancel | Help , Ok , true )
{
setButtonText ( Help , i18n ( " A&bout " ) ) ;
TQWidget * main = makeMainWidget ( ) ;
TQHBoxLayout * top = new TQHBoxLayout ( main , 0 , spacingHint ( ) ) ;
TQVBoxLayout * leftCol = new TQVBoxLayout ;
top - > addLayout ( leftCol ) ;
// Parameters
TQLabel * label = new TQLabel ( i18n ( " Mode: " ) , main ) ;
leftCol - > addWidget ( label ) ;
modeW = new TQComboBox ( main ) ;
int i = 0 ;
while ( defaultText [ i ] )
modeW - > insertItem ( i18n ( defaultText [ i + + ] ) ) ;
leftCol - > addWidget ( modeW ) ;
leftCol - > addStretch ( ) ;
// Preview
TQWidget * preview ;
preview = new TQWidget ( main ) ;
preview - > setFixedSize ( 220 , 165 ) ;
preview - > setBackgroundColor ( black ) ;
preview - > show ( ) ; // otherwise saver does not get correct size
_saver = new KFluxScreenSaver ( preview - > winId ( ) ) ;
top - > addWidget ( preview ) ;
// Now that we have _saver...
modeW - > setCurrentItem ( _saver - > mode ( ) ) ; // set before we connect
connect ( modeW , TQT_SIGNAL ( activated ( int ) ) , _saver , TQT_SLOT ( setMode ( int ) ) ) ;
}
KFluxSetup : : ~ KFluxSetup ( )
{
delete _saver ;
}
void KFluxSetup : : slotHelp ( )
{
KMessageBox : : about ( this ,
i18n ( " <h3>Flux 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> " ) ,
TQString : : null , KMessageBox : : AllowLink ) ;
}
/**
Ok pressed - save settings and exit
*/
void KFluxSetup : : slotOk ( )
{
KConfig * config = KGlobal : : config ( ) ;
config - > setGroup ( " Settings " ) ;
TQString val ;
val . setNum ( modeW - > currentItem ( ) ) ;
config - > writeEntry ( " Mode " , val ) ;
config - > sync ( ) ;
accept ( ) ;
}
# endif
//----------------------------------------------------------------------------
# ifdef UNIT_TEST
// moc Flux.h -o Flux.moc
// g++ -g -DUNIT_TEST Flux.cpp -I/usr/lib/qt3/include -lqt -L/usr/lib/qt3/lib -lGLU -lGL
# include <tqapplication.h>
int main ( int argc , char * * argv )
{
TQApplication app ( argc , argv ) ;
FluxWidget w ;
w . setDefaults ( FluxWidget : : Sparklers ) ;
app . setMainWidget ( & w ) ;
w . show ( ) ;
return app . exec ( ) ;
}
# endif
//EOF