1 /*
2 * Copyright (C) 2002 Terence M. Welsh
3 * Ported to Linux by Tugrul Galatali <tugrul@galatali.com>
4 *
5 * Euphoria 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.
8 *
9 * Euphoria 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.
13 *
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
17 */
18
19 /*
20 * Euphoria screensaver
21 */
22
23 const char *hack_name = "euphoria";
24
25 #include <stdio.h>
26 #include <GL/gl.h>
27 #include <GL/glu.h>
28
29 #include "driver.h"
30 #include "euphoria_textures.h"
31 #include "loadTexture.h"
32 #include "rgbhsl.h"
33 #include "rsDefines.h"
34 #include "rsRand.h"
35 #include <rsMath/rsVec.h>
36
37 #define PRESET_REGULAR 1
38 #define PRESET_GRID 2
39 #define PRESET_CUBISM 3
40 #define PRESET_BADMATH 4
41 #define PRESET_MTHEORY 5
42 #define PRESET_UHFTEM 6
43 #define PRESET_NOWHERE 7
44 #define PRESET_ECHO 8
45 #define PRESET_KALEIDOSCOPE 9
46
47 #define NUMCONSTS 9
48 #define TEXSIZE 256
49
50 typedef struct {
51 float ***vertices;
52 float c[NUMCONSTS]; /* constants */
53 float cr[NUMCONSTS]; /* constants radial position */
54 float cv[NUMCONSTS]; /* constants change velocities */
55 float hsl[3];
56 float rgb[3];
57 float hueSpeed;
58 float saturationSpeed;
59 } wisp;
60
61 wisp *backwisps;
62 wisp *wisps;
63 unsigned int tex;
64 float aspectRatio;
65 int viewport[4];
66 float elapsedTime;
67
68 /*
69 * Parameters edited in the dialog box
70 */
71 int dWisps;
72 int dBgWisps;
73 int dDensity;
74 int dVisibility;
75 int dSpeed;
76 int dFeedback;
77 int dFeedbackspeed;
78 int dFeedbacksize;
79 int dWireframe;
80 int dTexture;
81 int dPriority;
82
83 /*
84 * feedback texture object
85 */
86 unsigned int feedbacktex;
87 unsigned int feedbacktexsize;
88
89 /*
90 * feedback variables
91 */
92 float fr[4];
93 float fv[4];
94 float f[4];
95
96 /*
97 * feedback limiters
98 */
99 float lr[3];
100 float lv[3];
101 float l[3];
102
setDefaults(int which)103 void setDefaults (int which)
104 {
105 switch (which) {
106 case PRESET_REGULAR: /* Regular */
107 dWisps = 5;
108 dBgWisps = 0;
109 dDensity = 35;
110 dVisibility = 35;
111 dSpeed = 15;
112 dFeedback = 0;
113 dFeedbackspeed = 1;
114 dFeedbacksize = 10;
115 dWireframe = 0;
116 dTexture = 2;
117 break;
118 case PRESET_GRID: /* Grid */
119 dWisps = 4;
120 dBgWisps = 1;
121 dDensity = 30;
122 dVisibility = 70;
123 dSpeed = 15;
124 dFeedback = 0;
125 dFeedbackspeed = 1;
126 dFeedbacksize = 10;
127 dWireframe = 1;
128 dTexture = 0;
129 break;
130 case PRESET_CUBISM: /* Cubism */
131 dWisps = 15;
132 dBgWisps = 0;
133 dDensity = 4;
134 dVisibility = 15;
135 dSpeed = 10;
136 dFeedback = 0;
137 dFeedbackspeed = 1;
138 dFeedbacksize = 10;
139 dWireframe = 0;
140 dTexture = 0;
141 break;
142 case PRESET_BADMATH: /* Bad math */
143 dWisps = 2;
144 dBgWisps = 2;
145 dDensity = 20;
146 dVisibility = 40;
147 dSpeed = 30;
148 dFeedback = 40;
149 dFeedbackspeed = 5;
150 dFeedbacksize = 10;
151 dWireframe = 1;
152 dTexture = 2;
153 break;
154 case PRESET_MTHEORY: /* M-Theory */
155 dWisps = 3;
156 dBgWisps = 0;
157 dDensity = 35;
158 dVisibility = 15;
159 dSpeed = 20;
160 dFeedback = 40;
161 dFeedbackspeed = 20;
162 dFeedbacksize = 10;
163 dWireframe = 0;
164 dTexture = 0;
165 break;
166 case PRESET_UHFTEM: /* ultra high frequency tunneling electron microscope */
167 dWisps = 0;
168 dBgWisps = 3;
169 dDensity = 35;
170 dVisibility = 5;
171 dSpeed = 50;
172 dFeedback = 0;
173 dFeedbackspeed = 1;
174 dFeedbacksize = 10;
175 dWireframe = 0;
176 dTexture = 0;
177 break;
178 case PRESET_NOWHERE: /* Nowhere */
179 dWisps = 0;
180 dBgWisps = 3;
181 dDensity = 30;
182 dVisibility = 40;
183 dSpeed = 20;
184 dFeedback = 80;
185 dFeedbackspeed = 10;
186 dFeedbacksize = 10;
187 dWireframe = 1;
188 dTexture = 3;
189 break;
190 case PRESET_ECHO: /* Echo */
191 dWisps = 3;
192 dBgWisps = 0;
193 dDensity = 35;
194 dVisibility = 30;
195 dSpeed = 20;
196 dFeedback = 85;
197 dFeedbackspeed = 30;
198 dFeedbacksize = 10;
199 dWireframe = 0;
200 dTexture = 1;
201 break;
202 case PRESET_KALEIDOSCOPE: /* Kaleidoscope */
203 dWisps = 3;
204 dBgWisps = 0;
205 dDensity = 35;
206 dVisibility = 40;
207 dSpeed = 15;
208 dFeedback = 90;
209 dFeedbackspeed = 3;
210 dFeedbacksize = 10;
211 dWireframe = 0;
212 dTexture = 0;
213 break;
214 }
215 }
216
wisp_new(wisp * w)217 void wisp_new (wisp * w)
218 {
219 int i, j;
220 float recHalfDens = 1.0f / (dDensity * 0.5f);
221
222 w->vertices = (float ***)malloc (sizeof (float **) * (dDensity + 1));
223 for (i = 0; i <= dDensity; i++) {
224 w->vertices[i] = (float **)malloc (sizeof (float *) * (dDensity + 1));
225 for (j = 0; j <= dDensity; j++) {
226 w->vertices[i][j] = (float *)malloc (sizeof (float) * 7);
227 w->vertices[i][j][3] = i * recHalfDens - 1.0f; /* x position on grid */
228 w->vertices[i][j][4] = j * recHalfDens - 1.0f; /* y position on grid */
229
230 /*
231 * distance squared from the center
232 */
233 w->vertices[i][j][5] = w->vertices[i][j][3] * w->vertices[i][j][3] + w->vertices[i][j][4] * w->vertices[i][j][4];
234
235 w->vertices[i][j][6] = 0.0f; /* intensity */
236 }
237 }
238
239 /*
240 * initialize constants
241 */
242 for (i = 0; i < NUMCONSTS; i++) {
243 w->c[i] = rsRandf (2.0f) - 1.0f;
244 w->cr[i] = rsRandf (PIx2);
245 w->cv[i] = rsRandf (dSpeed * 0.03f) + (dSpeed * 0.001f);
246 }
247
248 /*
249 * pick color
250 */
251 w->hsl[0] = rsRandf (1.0f);
252 w->hsl[1] = 0.1f + rsRandf (0.9f);
253 w->hsl[2] = 1.0f;
254 w->hueSpeed = rsRandf (0.1f) - 0.05f;
255 w->saturationSpeed = rsRandf (0.04f) + 0.001f;
256 }
257
delete_wisp(wisp * w)258 void delete_wisp (wisp * w)
259 {
260 int i, j;
261
262 for (i = 0; i <= dDensity; i++) {
263 for (j = 0; j <= dDensity; j++) {
264 free (w->vertices[i][j]);
265 }
266 free (w->vertices[i]);
267 }
268 free (w->vertices);
269 }
270
wisp_update(wisp * w)271 void wisp_update (wisp * w)
272 {
273 int i, j;
274 rsVec up, right, crossvec;
275
276 /*
277 * visibility constants
278 */
279 const float viscon1 = dVisibility * 0.01f;
280 const float viscon2 = 1.0f / viscon1;
281
282 /*
283 * update constants
284 */
285 for (i = 0; i < NUMCONSTS; i++) {
286 w->cr[i] += w->cv[i] * elapsedTime;
287 if (w->cr[i] > PIx2)
288 w->cr[i] -= PIx2;
289 w->c[i] = cos (w->cr[i]);
290 }
291
292 /*
293 * update vertex positions
294 */
295 for (i = 0; i <= dDensity; i++) {
296 for (j = 0; j <= dDensity; j++) {
297 w->vertices[i][j][0] = w->vertices[i][j][3] * w->vertices[i][j][3] * w->vertices[i][j][4] * w->c[0] + w->vertices[i][j][5] * w->c[1] + 0.5f * w->c[2];
298 w->vertices[i][j][1] = w->vertices[i][j][4] * w->vertices[i][j][4] * w->vertices[i][j][5] * w->c[3] + w->vertices[i][j][3] * w->c[4] + 0.5f * w->c[5];
299 w->vertices[i][j][2] = w->vertices[i][j][5] * w->vertices[i][j][5] * w->vertices[i][j][3] * w->c[6] + w->vertices[i][j][4] * w->c[7] + w->c[8];
300 }
301 }
302
303 /*
304 * update vertex normals for most of mesh
305 */
306 for (i = 1; i < dDensity; i++) {
307 for (j = 1; j < dDensity; j++) {
308 up[0] = w->vertices[i][j + 1][0] - w->vertices[i][j - 1][0];
309 up[1] = w->vertices[i][j + 1][1] - w->vertices[i][j - 1][1];
310 up[2] = w->vertices[i][j + 1][2] - w->vertices[i][j - 1][2];
311
312 right[0] = w->vertices[i + 1][j][0] - w->vertices[i - 1][j][0];
313 right[1] = w->vertices[i + 1][j][1] - w->vertices[i - 1][j][1];
314 right[2] = w->vertices[i + 1][j][2] - w->vertices[i - 1][j][2];
315
316 up.normalize();
317 right.normalize();
318 crossvec.cross(right, up);
319
320 /*
321 * Use depth component of normal to compute intensity
322 */
323 /*
324 * This way only edges of wisp are bright
325 */
326 if (crossvec[2] < 0.0f)
327 crossvec[2] *= -1.0f;
328 w->vertices[i][j][6] = viscon2 * (viscon1 - crossvec[2]);
329 if (w->vertices[i][j][6] > 1.0f)
330 w->vertices[i][j][6] = 1.0f;
331 if (w->vertices[i][j][6] < 0.0f)
332 w->vertices[i][j][6] = 0.0f;
333 }
334 }
335
336 /*
337 * update color
338 */
339 w->hsl[0] += w->hueSpeed * elapsedTime;
340 if (w->hsl[0] < 0.0f)
341 w->hsl[0] += 1.0f;
342 if (w->hsl[0] > 1.0f)
343 w->hsl[0] -= 1.0f;
344 w->hsl[1] += w->saturationSpeed * elapsedTime;
345 if (w->hsl[1] <= 0.1f) {
346 w->hsl[1] = 0.1f;
347 w->saturationSpeed = -w->saturationSpeed;
348 }
349 if (w->hsl[1] >= 1.0f) {
350 w->hsl[1] = 1.0f;
351 w->saturationSpeed = -w->saturationSpeed;
352 }
353 hsl2rgb (w->hsl[0], w->hsl[1], w->hsl[2], w->rgb[0], w->rgb[1], w->rgb[2]);
354 }
355
wisp_draw(wisp * w)356 void wisp_draw (wisp * w)
357 {
358 int i, j;
359
360 glPushMatrix ();
361
362 if (dWireframe) {
363 for (i = 1; i <= dDensity; i++) {
364 glBegin (GL_LINE_STRIP);
365 for (j = 0; j <= dDensity; j++) {
366 glColor3f (w->rgb[0] + w->vertices[i][j][6] - 1.0f, w->rgb[1] + w->vertices[i][j][6] - 1.0f, w->rgb[2] + w->vertices[i][j][6] - 1.0f);
367 glTexCoord2d (w->vertices[i][j][3] - w->vertices[i][j][0], w->vertices[i][j][4] - w->vertices[i][j][1]);
368 glVertex3fv (w->vertices[i][j]);
369 }
370 glEnd ();
371 }
372 for (j = 1; j <= dDensity; j++) {
373 glBegin (GL_LINE_STRIP);
374 for (i = 0; i <= dDensity; i++) {
375 glColor3f (w->rgb[0] + w->vertices[i][j][6] - 1.0f, w->rgb[1] + w->vertices[i][j][6] - 1.0f, w->rgb[2] + w->vertices[i][j][6] - 1.0f);
376 glTexCoord2d (w->vertices[i][j][3] - w->vertices[i][j][0], w->vertices[i][j][4] - w->vertices[i][j][1]);
377 glVertex3fv (w->vertices[i][j]);
378 }
379 glEnd ();
380 }
381 } else {
382 for (i = 0; i < dDensity; i++) {
383 glBegin (GL_TRIANGLE_STRIP);
384 for (j = 0; j <= dDensity; j++) {
385 glColor3f (w->rgb[0] + w->vertices[i + 1][j][6] - 1.0f, w->rgb[1] + w->vertices[i + 1][j][6] - 1.0f, w->rgb[2] + w->vertices[i + 1][j][6] - 1.0f);
386 glTexCoord2d (w->vertices[i + 1][j][3] - w->vertices[i + 1][j][0], w->vertices[i + 1][j][4] - w->vertices[i + 1][j][1]);
387 glVertex3fv (w->vertices[i + 1][j]);
388 glColor3f (w->rgb[0] + w->vertices[i][j][6] - 1.0f, w->rgb[1] + w->vertices[i][j][6] - 1.0f, w->rgb[2] + w->vertices[i][j][6] - 1.0f);
389 glTexCoord2d (w->vertices[i][j][3] - w->vertices[i][j][0], w->vertices[i][j][4] - w->vertices[i][j][1]);
390 glVertex3fv (w->vertices[i][j]);
391 }
392 glEnd ();
393 }
394 }
395
396 glPopMatrix ();
397 }
398
wisp_drawAsBackground(wisp * w)399 void wisp_drawAsBackground (wisp * w)
400 {
401 int i, j;
402
403 glPushMatrix ();
404 glTranslatef (w->c[0] * 0.2f, w->c[1] * 0.2f, 1.6f);
405
406 if (dWireframe) {
407 for (i = 0; i <= dDensity; i++) {
408 glBegin (GL_LINE_STRIP);
409 for (j = 0; j <= dDensity; j++) {
410 glColor3f (w->rgb[0] + w->vertices[i][j][6] - 1.0f, w->rgb[1] + w->vertices[i][j][6] - 1.0f, w->rgb[2] + w->vertices[i][j][6] - 1.0f);
411 glTexCoord2d (w->vertices[i][j][3] - w->vertices[i][j][0], w->vertices[i][j][4] - w->vertices[i][j][1]);
412 glVertex3f (w->vertices[i][j][3], w->vertices[i][j][4], w->vertices[i][j][6]);
413 }
414 glEnd ();
415 }
416 for (j = 0; j <= dDensity; j++) {
417 glBegin (GL_LINE_STRIP);
418 for (i = 0; i <= dDensity; i++) {
419 glColor3f (w->rgb[0] + w->vertices[i][j][6] - 1.0f, w->rgb[1] + w->vertices[i][j][6] - 1.0f, w->rgb[2] + w->vertices[i][j][6] - 1.0f);
420 glTexCoord2d (w->vertices[i][j][3] - w->vertices[i][j][0], w->vertices[i][j][4] - w->vertices[i][j][1]);
421 glVertex3f (w->vertices[i][j][3], w->vertices[i][j][4], w->vertices[i][j][6]);
422 }
423 glEnd ();
424 }
425 } else {
426 for (i = 0; i < dDensity; i++) {
427 glBegin (GL_TRIANGLE_STRIP);
428 for (j = 0; j <= dDensity; j++) {
429 glColor3f (w->rgb[0] + w->vertices[i + 1][j][6] - 1.0f, w->rgb[1] + w->vertices[i + 1][j][6] - 1.0f, w->rgb[2] + w->vertices[i + 1][j][6] - 1.0f);
430 glTexCoord2d (w->vertices[i + 1][j][3] - w->vertices[i + 1][j][0], w->vertices[i + 1][j][4] - w->vertices[i + 1][j][1]);
431 glVertex3f (w->vertices[i + 1][j][3], w->vertices[i + 1][j][4], w->vertices[i + 1][j][6]);
432 glColor3f (w->rgb[0] + w->vertices[i][j][6] - 1.0f, w->rgb[1] + w->vertices[i][j][6] - 1.0f, w->rgb[2] + w->vertices[i][j][6] - 1.0f);
433 glTexCoord2d (w->vertices[i][j][3] - w->vertices[i][j][0], w->vertices[i][j][4] - w->vertices[i][j][1]);
434 glVertex3f (w->vertices[i][j][3], w->vertices[i][j][4], w->vertices[i][j][6]);
435 }
436 glEnd ();
437 }
438 }
439
440 glPopMatrix ();
441 }
442
hack_draw(xstuff_t * XStuff,double currentTime,float frameTime)443 void hack_draw (xstuff_t * XStuff, double currentTime, float frameTime)
444 {
445 int i;
446 #ifdef BENCHMARK
447 static int a = 1;
448 #endif
449
450 if (frameTime > 0)
451 elapsedTime = frameTime;
452
453 #ifdef BENCHMARK
454 elapsedTime = 0.001;
455 #endif
456
457 /*
458 * Update wisps
459 */
460 for (i = 0; i < dWisps; i++)
461 wisp_update (&wisps[i]);
462 for (i = 0; i < dBgWisps; i++)
463 wisp_update (&backwisps[i]);
464
465 if (dFeedback) {
466 float feedbackIntensity = dFeedback / 101.0f;
467
468 /*
469 * update feedback variables
470 */
471 for (i = 0; i < 4; i++) {
472 fr[i] += elapsedTime * fv[i];
473 if (fr[i] > PIx2)
474 fr[i] -= PIx2;
475 }
476 f[0] = 30.0f * cos (fr[0]);
477 f[1] = 0.2f * cos (fr[1]);
478 f[2] = 0.2f * cos (fr[2]);
479 f[3] = 0.8f * cos (fr[3]);
480 for (i = 0; i < 3; i++) {
481 lr[i] += elapsedTime * lv[i];
482 if (lr[i] > PIx2)
483 lr[i] -= PIx2;
484 l[i] = cos (lr[i]);
485 l[i] = l[i] * l[i];
486 }
487
488 /*
489 * Create drawing area for feedback texture
490 */
491 glViewport (0, 0, feedbacktexsize, feedbacktexsize);
492 glMatrixMode (GL_PROJECTION);
493 glLoadIdentity ();
494 gluPerspective (30.0, aspectRatio, 0.01f, 20.0f);
495 glMatrixMode (GL_MODELVIEW);
496
497 /*
498 * Draw
499 */
500 glClear (GL_COLOR_BUFFER_BIT);
501 glColor3f (feedbackIntensity, feedbackIntensity, feedbackIntensity);
502 glBindTexture (GL_TEXTURE_2D, feedbacktex);
503 glPushMatrix ();
504 glTranslatef (f[1] * l[1], f[2] * l[1], f[3] * l[2]);
505 glRotatef (f[0] * l[0], 0, 0, 1);
506 glBegin (GL_TRIANGLE_STRIP);
507 glTexCoord2f (-0.5f, -0.5f);
508 glVertex3f (-aspectRatio * 2.0f, -2.0f, 1.25f);
509 glTexCoord2f (1.5f, -0.5f);
510 glVertex3f (aspectRatio * 2.0f, -2.0f, 1.25f);
511 glTexCoord2f (-0.5f, 1.5f);
512 glVertex3f (-aspectRatio * 2.0f, 2.0f, 1.25f);
513 glTexCoord2f (1.5f, 1.5f);
514 glVertex3f (aspectRatio * 2.0f, 2.0f, 1.25f);
515 glEnd ();
516 glPopMatrix ();
517 glBindTexture (GL_TEXTURE_2D, tex);
518 for (i = 0; i < dBgWisps; i++)
519 wisp_drawAsBackground (&backwisps[i]);
520 for (i = 0; i < dWisps; i++)
521 wisp_draw (&wisps[i]);
522
523 /*
524 * readback feedback texture
525 */
526 glReadBuffer (GL_BACK);
527 glPixelStorei (GL_UNPACK_ROW_LENGTH, feedbacktexsize);
528 glBindTexture (GL_TEXTURE_2D, feedbacktex);
529 glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, 0, 0, feedbacktexsize, feedbacktexsize);
530
531 /*
532 * create regular drawing area
533 */
534 glViewport (0, 0, XStuff->windowWidth, XStuff->windowHeight);
535 glMatrixMode (GL_PROJECTION);
536 glLoadIdentity ();
537 gluPerspective (20.0, aspectRatio, 0.01f, 20.0f);
538 glMatrixMode (GL_MODELVIEW);
539
540 /*
541 * Draw again
542 */
543 glClear (GL_COLOR_BUFFER_BIT);
544 glColor3f (feedbackIntensity, feedbackIntensity, feedbackIntensity);
545 glPushMatrix ();
546 glTranslatef (f[1] * l[1], f[2] * l[1], f[3] * l[2]);
547 glRotatef (f[0] * l[0], 0, 0, 1);
548 glBegin (GL_TRIANGLE_STRIP);
549 glTexCoord2f (-0.5f, -0.5f);
550 glVertex3f (-aspectRatio * 2.0f, -2.0f, 1.25f);
551 glTexCoord2f (1.5f, -0.5f);
552 glVertex3f (aspectRatio * 2.0f, -2.0f, 1.25f);
553 glTexCoord2f (-0.5f, 1.5f);
554 glVertex3f (-aspectRatio * 2.0f, 2.0f, 1.25f);
555 glTexCoord2f (1.5f, 1.5f);
556 glVertex3f (aspectRatio * 2.0f, 2.0f, 1.25f);
557 glEnd ();
558 glPopMatrix ();
559
560 glBindTexture (GL_TEXTURE_2D, tex);
561 } else
562 glClear (GL_COLOR_BUFFER_BIT);
563
564 for (i = 0; i < dBgWisps; i++)
565 wisp_drawAsBackground (&backwisps[i]);
566 for (i = 0; i < dWisps; i++)
567 wisp_draw (&wisps[i]);
568
569 glFlush ();
570
571 #ifdef BENCHMARK
572 if (a++ == 10000)
573 exit(0);
574 #endif
575 }
576
hack_reshape(xstuff_t * XStuff)577 void hack_reshape (xstuff_t * XStuff)
578 {
579 aspectRatio = (GLfloat) XStuff->windowWidth / (GLfloat) XStuff->windowHeight;
580
581 glViewport (0, 0, (GLint) XStuff->windowWidth, (GLint) XStuff->windowHeight);
582
583 /*
584 * setup regular drawing area just in case feedback isnt used
585 */
586 glMatrixMode (GL_PROJECTION);
587 glLoadIdentity ();
588 gluPerspective (20.0, aspectRatio, 0.01, 20);
589 glMatrixMode (GL_MODELVIEW);
590 glLoadIdentity ();
591 glTranslatef (0.0, 0.0, -5.0);
592
593 glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
594 glClear (GL_COLOR_BUFFER_BIT);
595 glEnable (GL_BLEND);
596 glBlendFunc (GL_ONE, GL_ONE);
597 glLineWidth (2.0f);
598
599 /*
600 * Commented out because smooth lines and textures dont mix on my TNT.
601 * Its like it rendering in software mode
602 */
603
604 /*
605 * glEnable(GL_LINE_SMOOTH); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
606 */
607 }
608
hack_init(xstuff_t * XStuff)609 void hack_init (xstuff_t * XStuff)
610 {
611 int i;
612
613 hack_reshape (XStuff);
614
615 if (dTexture) {
616 int whichtex = dTexture;
617 unsigned char *l_tex = NULL;
618
619 if (whichtex == 4) /* random texture */
620 whichtex = rsRandi (3) + 1;
621 glEnable (GL_TEXTURE_2D);
622 glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
623 /*
624 * Initialize texture
625 */
626 glGenTextures (1, &tex);
627 glBindTexture (GL_TEXTURE_2D, tex);
628 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
629 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
630 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
631 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
632 switch (whichtex) {
633 case 1:
634 LOAD_TEXTURE (l_tex, plasmamap, plasmamap_compressedsize, plasmamap_size)
635 break;
636 case 2:
637 LOAD_TEXTURE (l_tex, stringymap, stringymap_compressedsize, stringymap_size)
638 break;
639 case 3:
640 LOAD_TEXTURE (l_tex, linesmap, linesmap_compressedsize, linesmap_size)
641 }
642
643 gluBuild2DMipmaps (GL_TEXTURE_2D, 1, TEXSIZE, TEXSIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, l_tex);
644 FREE_TEXTURE (l_tex)
645 }
646
647 if (dFeedback) {
648 feedbacktexsize = 1 << dFeedbacksize;
649 while (feedbacktexsize > XStuff->windowWidth || feedbacktexsize > XStuff->windowHeight) {
650 dFeedbacksize -= 1;
651 feedbacktexsize = 1 << dFeedbacksize;
652 }
653
654 /*
655 * feedback texture setup
656 */
657 glEnable (GL_TEXTURE_2D);
658 glGenTextures (1, &feedbacktex);
659 glBindTexture (GL_TEXTURE_2D, feedbacktex);
660 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
661 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
662 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
663 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
664 glTexImage2D (GL_TEXTURE_2D, 0, 3, feedbacktexsize, feedbacktexsize, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
665
666 /*
667 * feedback velocity variable setup
668 */
669 fv[0] = (float)dFeedbackspeed * (rsRandf (0.025f) + 0.025f);
670 fv[1] = (float)dFeedbackspeed * (rsRandf (0.05f) + 0.05f);
671 fv[2] = (float)dFeedbackspeed * (rsRandf (0.05f) + 0.05f);
672 fv[3] = (float)dFeedbackspeed * (rsRandf (0.1f) + 0.1f);
673 lv[0] = (float)dFeedbackspeed * (rsRandf (0.0025f) + 0.0025f);
674 lv[1] = (float)dFeedbackspeed * (rsRandf (0.0025f) + 0.0025f);
675 lv[2] = (float)dFeedbackspeed * (rsRandf (0.0025f) + 0.0025f);
676 }
677
678 /*
679 * Initialize wisps
680 */
681 if (dWisps > 0) {
682 wisps = (wisp *) malloc (sizeof (wisp) * dWisps);
683 for (i = 0; i < dWisps; i++) {
684 wisp_new (&wisps[i]);
685 }
686 }
687
688 if (dBgWisps > 0) {
689 backwisps = (wisp *) malloc (sizeof (wisp) * dBgWisps);
690 for (i = 0; i < dBgWisps; i++) {
691 wisp_new (&backwisps[i]);
692 }
693 }
694 }
695
hack_cleanup(xstuff_t * XStuff)696 void hack_cleanup (xstuff_t * XStuff)
697 {
698 }
699
hack_handle_opts(int argc,char ** argv)700 void hack_handle_opts (int argc, char **argv)
701 {
702 int change_flag = 0;
703
704 setDefaults (PRESET_REGULAR);
705
706 while (1) {
707 int c;
708
709 #ifdef HAVE_GETOPT_H
710 static struct option long_options[] = {
711 {"help", 0, 0, 'h'},
712 DRIVER_OPTIONS_LONG
713 {"preset", 1, 0, 'p'},
714 {"regular", 0, 0, 10},
715 {"grid", 0, 0, 11},
716 {"cubism", 0, 0, 12},
717 {"badmath", 0, 0, 13},
718 {"mtheory", 0, 0, 14},
719 {"uhftem", 0, 0, 15},
720 {"nowhere", 0, 0, 16},
721 {"echo", 0, 0, 17},
722 {"kaleidoscope", 0, 0, 18},
723 {"wisps", 1, 0, 'i'},
724 {"bgwisps", 1, 0, 'b'},
725 {"density", 1, 0, 'd'},
726 {"visibility", 1, 0, 'v'},
727 {"speed", 1, 0, 's'},
728 {"feedback", 1, 0, 'f'},
729 {"feedbackspeed", 1, 0, 'e'},
730 {"feedbacksize", 1, 0, 'c'},
731 {"wireframe", 0, 0, 'w'},
732 {"no-wireframe", 0, 0, 'W'},
733 {"texture", 1, 0, 't'},
734 {"plasma", 0, 0, 1},
735 {"stringy", 0, 0, 2},
736 {"linear", 0, 0, 3},
737 {0, 0, 0, 0}
738 };
739
740 c = getopt_long (argc, argv, DRIVER_OPTIONS_SHORT "hp:i:b:d:v:s:f:e:c:wWt:", long_options, NULL);
741 #else
742 c = getopt (argc, argv, DRIVER_OPTIONS_SHORT "hp:i:b:d:v:s:f:e:c:wWt:");
743 #endif
744 if (c == -1)
745 break;
746
747 switch (c) {
748 DRIVER_OPTIONS_CASES
749 case 'h':
750 printf ("%s:"
751 #ifndef HAVE_GETOPT_H
752 " Not built with GNU getopt.h, long options *NOT* enabled."
753 #endif
754 "\n" DRIVER_OPTIONS_HELP
755 "\t--preset/-p <arg>\n" "\t--regular\n" "\t--grid\n" "\t--cubism\n" "\t--badmath\n" "\t--mtheory\n" "\t--uhftem\n" "\t--nowhere\n" "\t--echo\n" "\t--kaleidoscope\n"
756 "\t--wisps/-i <arg>\n" "\t--bgwisps/-b <arg>\n"
757 "\t--density/-d <arg>\n" "\t--visibility/-v <arg>\n" "\t--speed/-s <arg>\n"
758 "\t--feedback/-f <arg>\n" "\t--feedbackspeed/-e <arg>\n" "\t--feedbacksize/-c <arg>\n"
759 "\t--wireframe/-w\n" "\t--no-wireframe/-W\n"
760 "\t--texture/-t <arg>\n" "\t--plasma\n" "\t--stringy\n" "\t--linear\n", argv[0]);
761 exit (1);
762 case 'p':
763 change_flag = 1;
764 setDefaults (strtol_minmaxdef (optarg, 10, 1, 9, 0, 1, "--preset: "));
765 break;
766 case 10:
767 case 11:
768 case 12:
769 case 13:
770 case 14:
771 case 15:
772 case 16:
773 case 17:
774 case 18:
775 change_flag = 1;
776 setDefaults (c - 9);
777 break;
778 case 'i':
779 change_flag = 1;
780 dWisps = strtol_minmaxdef (optarg, 10, 0, 128, 1, 1, "--wisps: ");
781 break;
782 case 'b':
783 change_flag = 1;
784 dBgWisps = strtol_minmaxdef (optarg, 10, 0, 128, 1, 1, "--bgwisps: ");
785 break;
786 case 'd':
787 change_flag = 1;
788 dDensity = strtol_minmaxdef (optarg, 10, 2, 1000, 1, 1, "--density: ");
789 break;
790 case 'v':
791 change_flag = 1;
792 dVisibility = strtol_minmaxdef (optarg, 10, 1, 100, 1, 1, "--visibility: ");
793 break;
794 case 's':
795 change_flag = 1;
796 dSpeed = strtol_minmaxdef (optarg, 10, 1, 100, 1, 1, "--speed: ");
797 break;
798 case 'f':
799 change_flag = 1;
800 dFeedback = strtol_minmaxdef (optarg, 10, 0, 100, 1, 1, "--feedback: ");
801 break;
802 case 'e':
803 change_flag = 1;
804 dFeedbackspeed = strtol_minmaxdef (optarg, 10, 1, 10, 1, 1, "--feedbackspeed: ");
805 break;
806 case 'c':
807 change_flag = 1;
808 dFeedbacksize = 1 << strtol_minmaxdef (optarg, 10, 1, 10, 1, 1, "--feedbacksize: ");
809 break;
810 case 'w':
811 change_flag = 1;
812 dWireframe = 1;
813 break;
814 case 'W':
815 change_flag = 1;
816 dWireframe = 0;
817 break;
818 case 't':
819 change_flag = 1;
820 dTexture = strtol_minmaxdef (optarg, 10, 0, 4, 0, 1, "--texture: ");
821 break;
822 case 1:
823 case 2:
824 case 3:
825 change_flag = 1;
826 dTexture = c;
827 break;
828 }
829 }
830
831 if (!change_flag) {
832 setDefaults (rsRandi (9) + 1);
833 }
834 }
835