2
* Copyright (C) 2002 Terence M. Welsh
3
* Ported to Linux by Tugrul Galatali <tugrul@galatali.com>
5
* Solar Winds is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License version 2 as
7
* published by the Free Software Foundation.
9
* Solar Winds is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
// Solar Winds screen saver
27
#include "rsDefines.h"
30
const char *hack_name = "solarwinds";
47
float cosCameraAngle, sinCameraAngle;
48
unsigned char lightTexture[LIGHTSIZE][LIGHTSIZE];
50
// Parameters edited in the dialog box
81
emitters = new float *[dEmitters];
83
for (i = 0; i < dEmitters; i++) {
84
emitters[i] = new float[3];
86
emitters[i][0] = rsRandf (60.0f) - 30.0f;
87
emitters[i][1] = rsRandf (60.0f) - 30.0f;
88
emitters[i][2] = rsRandf (30.0f) - 15.0f;
91
particles = new float *[dParticles];
93
for (i = 0; i < dParticles; i++) {
94
particles[i] = new float[6]; // 3 for pos, 3 for color
96
particles[i][2] = 100.0f; // start particles behind viewer
101
if (dGeometry == 2) { // allocate memory for lines
102
linelist = new int *[dParticles];
104
for (i = 0; i < dParticles; i++) {
105
linelist[i] = new int[2];
110
lastparticle = new int[dEmitters];
112
for (i = 0; i < dEmitters; i++)
116
for (i = 0; i < NUMCONSTS; i++) {
117
ct[i] = rsRandf (PIx2);
118
cv[i] = rsRandf (0.00005f * float (dWindspeed) * float (dWindspeed))
119
+ 0.00001f * float (dWindspeed) * float (dWindspeed);
127
for (i = 0; i < dEmitters; i++)
131
for (i = 0; i < dParticles; i++)
132
delete[]particles[i];
135
if (dGeometry == 2) {
136
for (i = 0; i < dParticles; i++)
139
delete[]lastparticle;
149
static float evel = float (dEmitterspeed) * 0.01f;
150
static float pvel = float (dParticlespeed) * 0.01f;
151
static float pointsize = 0.04f * float (dSize);
152
static float linesize = 0.005f * float (dSize);
155
for (i = 0; i < NUMCONSTS; i++) {
162
// calculate emissions
163
for (i = 0; i < dEmitters; i++) {
164
emitters[i][2] += evel; // emitter moves toward viewer
165
if (emitters[i][2] > 15.0f) { // reset emitter
166
emitters[i][0] = rsRandf (60.0f) - 30.0f;
167
emitters[i][1] = rsRandf (60.0f) - 30.0f;
168
emitters[i][2] = -15.0f;
170
particles[whichparticle][0] = emitters[i][0];
171
particles[whichparticle][1] = emitters[i][1];
172
particles[whichparticle][2] = emitters[i][2];
173
if (dGeometry == 2) { // link particles to form lines
174
if (linelist[whichparticle][0] >= 0)
175
linelist[linelist[whichparticle][0]][1] = -1;
176
linelist[whichparticle][0] = -1;
177
if (emitters[i][2] == -15.0f)
178
linelist[whichparticle][1] = -1;
180
linelist[whichparticle][1] = lastparticle[i];
181
linelist[lastparticle[i]][0] = whichparticle;
182
lastparticle[i] = whichparticle;
185
if (whichparticle >= dParticles)
189
// calculate particle positions and colors
190
// first modify constants that affect colors
191
c[6] *= 9.0f / float (dParticlespeed);
192
c[7] *= 9.0f / float (dParticlespeed);
193
c[8] *= 9.0f / float (dParticlespeed);
195
// then update each particle
196
for (i = 0; i < dParticles; i++) {
197
// store old positions
201
// make new positions
202
particles[i][0] = x + (c[0] * y + c[1] * z) * pvel;
203
particles[i][1] = y + (c[2] * z + c[3] * x) * pvel;
204
particles[i][2] = z + (c[4] * x + c[5] * y) * pvel;
206
particles[i][3] = float (fabs ((particles[i][0] - x) * c[6]));
207
particles[i][4] = float (fabs ((particles[i][1] - y) * c[7]));
208
particles[i][5] = float (fabs ((particles[i][2] - z) * c[8]));
211
if (particles[i][3] > 1.0f)
212
particles[i][3] = 1.0f;
213
if (particles[i][4] > 1.0f)
214
particles[i][4] = 1.0f;
215
if (particles[i][5] > 1.0f)
216
particles[i][5] = 1.0f;
222
for (i = 0; i < dParticles; i++) {
223
glColor3fv (&particles[i][3]);
225
glTranslatef (particles[i][0], particles[i][1], particles[i][2]);
231
for (i = 0; i < dParticles; i++) {
232
temp = particles[i][2] + 40.0f;
235
glPointSize (pointsize * temp);
237
glColor3fv (&particles[i][3]);
238
glVertex3fv (particles[i]);
243
for (i = 0; i < dParticles; i++) {
244
temp = particles[i][2] + 40.0f;
247
glLineWidth (linesize * temp);
249
if (linelist[i][1] >= 0) {
250
glColor3fv (&particles[i][3]);
251
if (linelist[i][0] == -1)
252
glColor3f (0.0f, 0.0f, 0.0f);
253
glVertex3fv (particles[i]);
254
glColor3fv (&particles[linelist[i][1]][3]);
255
if (linelist[linelist[i][1]][1] == -1)
256
glColor3f (0.0f, 0.0f, 0.0f);
257
glVertex3fv (particles[linelist[i][1]]);
264
void hack_draw (xstuff_t * XStuff, double currentTime, float frameTime)
269
glClear (GL_COLOR_BUFFER_BIT);
271
glMatrixMode(GL_PROJECTION);
274
glOrtho(0.0, 1.0, 0.0, 1.0, 1.0, -1.0);
275
glMatrixMode(GL_MODELVIEW);
277
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
278
glColor4f(0.0f, 0.0f, 0.0f, 0.5f - (float(dBlur) * 0.0049f));
279
glBegin(GL_TRIANGLE_STRIP);
280
glVertex3f(0.0f, 0.0f, 0.0f);
281
glVertex3f(1.0f, 0.0f, 0.0f);
282
glVertex3f(0.0f, 1.0f, 0.0f);
283
glVertex3f(1.0f, 1.0f, 0.0f);
286
glBlendFunc(GL_ONE, GL_ONE);
288
glBlendFunc(GL_SRC_ALPHA, GL_ONE); // Necessary for point and line smoothing (I don't know why)
289
// Maybe it's just my video card...
290
glMatrixMode(GL_PROJECTION);
294
glMatrixMode(GL_MODELVIEW);
296
glTranslatef(0.0, 0.0, -15.0);
298
// You should need to draw twice if using blur, once to each buffer.
299
// But wglSwapLayerBuffers appears to copy the back to the
300
// front instead of just switching the pointers to them. It turns
301
// out that both NVidia and 3dfx prefer to use PFD_SWAP_COPY instead
302
// of PFD_SWAP_EXCHANGE in the PIXELFORMATDESCRIPTOR. I don't know
304
// So this may not work right on other platforms or all video cards.
307
for (i = 0; i < dWinds; i++)
313
void hack_reshape (xstuff_t * XStuff)
315
// Window initialization
316
glViewport (0, 0, XStuff->windowWidth, XStuff->windowHeight);
318
glMatrixMode (GL_PROJECTION);
320
gluPerspective (90.0, float (XStuff->windowWidth) / float (XStuff->windowHeight), 1.0, 10000);
322
glTranslatef (0.0, 0.0, -15.0);
323
glMatrixMode (GL_MODELVIEW);
326
glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
327
glClear (GL_COLOR_BUFFER_BIT);
330
void hack_init (xstuff_t * XStuff)
335
hack_reshape (XStuff);
338
glBlendFunc (GL_ONE, GL_ONE);
340
glBlendFunc (GL_SRC_ALPHA, GL_ONE); // Necessary for point and line smoothing (I don't know why)
344
if (!dGeometry) { // Init lights
345
for (i = 0; i < LIGHTSIZE; i++) {
346
for (j = 0; j < LIGHTSIZE; j++) {
347
x = float (i - LIGHTSIZE / 2) / float (LIGHTSIZE / 2);
348
y = float (j - LIGHTSIZE / 2) / float (LIGHTSIZE / 2);
349
temp = 1.0f - float (sqrt ((x * x) + (y * y)));
355
lightTexture[i][j] = char (255.0f * temp);
358
glEnable (GL_TEXTURE_2D);
359
glBindTexture (GL_TEXTURE_2D, 1);
360
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
361
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
362
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
363
glTexImage2D (GL_TEXTURE_2D, 0, 1, LIGHTSIZE, LIGHTSIZE, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, lightTexture);
364
temp = 0.02f * float (dSize);
366
glNewList (1, GL_COMPILE);
367
glBindTexture (GL_TEXTURE_2D, 1);
368
glBegin (GL_TRIANGLE_STRIP);
369
glTexCoord2f (0.0f, 0.0f);
370
glVertex3f (-temp, -temp, 0.0f);
371
glTexCoord2f (1.0f, 0.0f);
372
glVertex3f (temp, -temp, 0.0f);
373
glTexCoord2f (0.0f, 1.0f);
374
glVertex3f (-temp, temp, 0.0f);
375
glTexCoord2f (1.0f, 1.0f);
376
glVertex3f (temp, temp, 0.0f);
381
if (dGeometry == 1) { // init point smoothing
382
glEnable (GL_POINT_SMOOTH);
383
glHint (GL_POINT_SMOOTH_HINT, GL_NICEST);
386
if (dGeometry == 2) { // init line smoothing
387
glEnable (GL_LINE_SMOOTH);
388
glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
390
// Initialize surfaces
391
winds = new wind[dWinds];
396
void hack_cleanup (xstuff_t * XStuff)
398
glDeleteLists (1, 1);
401
void setDefaults (int which)
404
case DEFAULTS1: // Regular
415
case DEFAULTS2: // Cosmic Strings
426
case DEFAULTS3: // Cold Pricklies
437
case DEFAULTS4: // Space Fur
448
case DEFAULTS5: // Jiggly
459
case DEFAULTS6: // Undertow
467
dParticlespeed = 100;
472
void hack_handle_opts (int argc, char **argv)
476
setDefaults (DEFAULTS1);
482
static struct option long_options[] = {
485
{"preset", 1, 0, 'R'},
486
{"regular", 0, 0, 10},
487
{"cosmicstrings", 0, 0, 11},
488
{"coldpricklies", 0, 0, 12},
489
{"spacefur", 0, 0, 13},
491
{"undertow", 0, 0, 15},
492
{"winds", 1, 0, 'w'},
493
{"emitters", 1, 0, 'e'},
494
{"particles", 1, 0, 'p'},
495
{"geometry", 1, 0, 'g'},
496
{"lights", 0, 0, 20},
497
{"points", 0, 0, 21},
500
{"windspeed", 1, 0, 'W'},
501
{"emitterspeed", 1, 0, 'E'},
502
{"particlespeed", 1, 0, 'P'},
507
c = getopt_long (argc, argv, DRIVER_OPTIONS_SHORT "hR:w:e:p:s:g:W:E:P:b:", long_options, NULL);
509
c = getopt (argc, argv, DRIVER_OPTIONS_SHORT "hR:w:e:p:s:g:W:E:P:b:");
515
DRIVER_OPTIONS_CASES case 'h':
517
#ifndef HAVE_GETOPT_H
518
" Not built with GNU getopt.h, long options *NOT* enabled."
520
"\n" DRIVER_OPTIONS_HELP
521
"\t--preset/-R <arg>\n"
523
"\t--cosmicstrings\n"
524
"\t--coldpricklies\n"
528
"\t--winds/-w <arg>\n" "\t--emitters/-e <arg>\n" "\t--particles/-p <arg>\n"
529
"\t--geometry/-g <arg>\n" "\t--lights\n" "\t--points\n" "\t--lines\n"
530
"\t--size/-s <arg>\n"
531
"\t--windspeed/-W <arg>\n" "\t--emitterspeed/-E <arg>\n" "\t--particlespeed/-P <arg>\n"
532
"\t--blur/-b <arg>\n", argv[0]);
536
setDefaults (strtol_minmaxdef(optarg, 10, 1, 6, 0, 1, "--preset: "));
549
dWinds = strtol_minmaxdef(optarg, 10, 1, 10, 1, 1, "--winds: ");
553
dEmitters = strtol_minmaxdef(optarg, 10, 1, 1000, 1, 30, "--emitters: ");
557
dParticles = strtol_minmaxdef(optarg, 10, 0, 10000, 1, 2000, "--particles: ");
561
dSize = strtol_minmaxdef(optarg, 10, 0, 100, 1, 50, "--size: ");
565
dGeometry = strtol_minmaxdef(optarg, 10, 0, 2, 0, 0, "--geometry: ");
575
dWindspeed = strtol_minmaxdef(optarg, 10, 1, 100, 1, 20, "--windspeed: ");
579
dEmitterspeed = strtol_minmaxdef(optarg, 10, 1, 100, 1, 15, "--emitterspeed: ");
583
dParticlespeed = strtol_minmaxdef(optarg, 10, 1, 100, 1, 10, "--particlespeed: ");
587
dBlur = strtol_minmaxdef(optarg, 10, 0, 100, 1, 40, "--blur: ");
593
setDefaults (rsRandi (6) + 1);