1 /*
2 * Copyright (C) 2002 <hk@dgmr.nl>
3 * Ported to Linux by Tugrul Galatali <tugrul@galatali.com>
4 *
5 * BioF 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 * BioF 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 // BioF screen saver
20
21 #include <math.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <GL/gl.h>
25 #include <GL/glu.h>
26
27 #include "driver.h"
28 #include "rsRand.h"
29
30 const char *hack_name = "BioF";
31
32 #define TRIANGLES 1
33 #define SPHERES 2
34 #define BIGSPHERES 3
35 #define POINTS 4
36 #define LIGHTMAP 5
37
38 int NRPOINTS, NRLINES;
39 int dGeometry;
40 int dOffAngle;
41
42 GLUquadricObj *shapes;
43
Horn(int ribs,double bend,double stack,double twist,double twisttrans,double grow)44 void Horn (int ribs, double bend, double stack, double twist, double twisttrans, double grow)
45 {
46 int i;
47
48 for (i = 0; i < ribs; i++) {
49 glPushMatrix ();
50 glRotated (i * bend / ribs, 1, 0, 0);
51 glTranslated (0, 0, i * stack / ribs);
52 glTranslated (twisttrans, 0, 0);
53 glRotated (i * twist / ribs, 0, 0, 1);
54 glTranslated (-twisttrans, 0, 0);
55
56 switch (dGeometry) {
57 case TRIANGLES:
58 glBegin (GL_TRIANGLES);
59 glColor4d (0.9, 0.8, 0.5, 1);
60 glVertex3d (2, 2, 0);
61 glColor4d (0.9, 0.8, 0.5, 0.0);
62 glVertex3d (0, 2, 0);
63 glVertex3d (2, 0, 0);
64 glEnd ();
65
66 break;
67
68 case BIGSPHERES:
69 gluQuadricDrawStyle (shapes, GLU_FILL);
70 gluQuadricNormals (shapes, GLU_SMOOTH);
71 gluSphere (shapes, 7 * exp (i / ribs * log (grow)), 20, 10);
72
73 break;
74
75 case SPHERES:
76 gluQuadricDrawStyle (shapes, GLU_FILL);
77 gluQuadricNormals (shapes, GLU_SMOOTH);
78 //gluSphere(shapes, power(grow,i/ribs), 5, 5);
79 gluSphere (shapes, exp (i / ribs * log (grow)), 6, 4);
80
81 break;
82
83 case LIGHTMAP:
84 case POINTS:
85 glBegin (GL_POINTS);
86 glVertex3d (0, 0, 0);
87 glEnd ();
88
89 break;
90 }
91
92 glPopMatrix ();
93 }
94 }
95
hack_reshape(xstuff_t * XStuff)96 void hack_reshape (xstuff_t * XStuff)
97 {
98 glViewport (0, 0, (GLsizei) XStuff->windowWidth, (GLsizei) XStuff->windowHeight);
99 glMatrixMode (GL_PROJECTION);
100 glLoadIdentity ();
101 gluPerspective (30, (float)XStuff->windowWidth / (float)XStuff->windowHeight, 100, 300);
102 }
103
hack_init(xstuff_t * XStuff)104 void hack_init (xstuff_t * XStuff) // Called right after the window is created, and OpenGL is initialized.
105 {
106 float glfLightPosition[4] = { 100.0, 100.0, 100.0, 0.0 };
107 float glfFog[4] = { 0.0, 0.0, 0.3, 1.0 };
108 float DiffuseLightColor[4] = { 1, 0.8, 0.4, 1.0 };
109 int i, j;
110 double x, y, r, d;
111 unsigned char texbuf[64][64];
112
113 glEnable (GL_DEPTH_TEST);
114
115 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
116 glEnable (GL_BLEND);
117
118 if ((dGeometry == SPHERES) || (dGeometry == BIGSPHERES)) {
119 glEnable (GL_CULL_FACE);
120 glCullFace (GL_BACK);
121
122 glLightfv (GL_LIGHT0, GL_POSITION, glfLightPosition);
123 glEnable (GL_LIGHTING);
124 glEnable (GL_LIGHT0);
125
126 glLightfv (GL_LIGHT0, GL_DIFFUSE, DiffuseLightColor);
127
128 shapes = gluNewQuadric ();
129 } else if (dGeometry == POINTS) {
130 glHint (GL_POINT_SMOOTH_HINT, GL_NICEST);
131 glPointSize (3);
132 glEnable (GL_POINT_SMOOTH);
133
134 glFogi (GL_FOG_MODE, GL_LINEAR);
135 glHint (GL_FOG_HINT, GL_NICEST);
136 glFogfv (GL_FOG_COLOR, glfFog);
137 glFogf (GL_FOG_START, 150);
138 glFogf (GL_FOG_END, 250);
139 glEnable (GL_FOG);
140 } else if (dGeometry == LIGHTMAP) {
141 r = 32;
142
143 memset ((void *)&texbuf, 0, 4096);
144
145 for (i = 0; i < 64; i++) {
146 for (j = 0; j < 64; j++) {
147 x = abs (i - 32);
148 y = abs (j - 32);
149 d = sqrt (x * x + y * y);
150
151 if (d < r) {
152 d = 1 - (d / r);
153 texbuf[i][j] = (char)(255.0f * d * d);
154 }
155 }
156 }
157
158 gluBuild2DMipmaps (GL_TEXTURE_2D, 1, 64, 64, GL_LUMINANCE, GL_UNSIGNED_BYTE, texbuf);
159
160 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
161 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
162 }
163
164 hack_reshape (XStuff);
165 }
166
hack_cleanup(xstuff_t * XStuff)167 void hack_cleanup (xstuff_t * XStuff)
168 {
169 if ((dGeometry == SPHERES) || (dGeometry == BIGSPHERES))
170 gluDeleteQuadric(shapes);
171 }
172
hack_draw(xstuff_t * XStuff,double currentTime,float lastFrameDuration)173 void hack_draw (xstuff_t * XStuff, double currentTime, float lastFrameDuration)
174 {
175 if (dGeometry == LIGHTMAP) {
176 int i, j, offset;
177 float fb_buffer[NRPOINTS * NRLINES * 3];
178 double x, y, w;
179
180 glDisable (GL_DEPTH_TEST);
181 glFeedbackBuffer (NRPOINTS * NRLINES * 3, GL_2D, fb_buffer);
182 glRenderMode (GL_FEEDBACK);
183
184 glMatrixMode (GL_MODELVIEW);
185 glPushMatrix ();
186 glLoadIdentity ();
187
188 gluLookAt (200, 0, 0, 0, 0, 0, 0, 0, 1);
189
190 glRotated (90, 0, 1, 0);
191 glRotated (10 * currentTime, 0, 0, 1);
192
193 glNewList (1, GL_COMPILE);
194 Horn (NRPOINTS, 315 * sin (currentTime * 0.237), 45 /* + 20 * sin(currentTime * 0.133) */ , 1500 * sin (currentTime * 0.213), 7.5 + 2.5 * sin (currentTime * 0.173), 1);
195 glEndList ();
196
197 if (dOffAngle)
198 glRotated (45, 1, 1, 0);
199
200 for (i = 0; i < NRLINES; i++) {
201 glPushMatrix ();
202
203 glRotated (360 * i / NRLINES, 0, 0, 1);
204 glRotated (45, 1, 0, 0);
205 glTranslated (0, 0, 2);
206
207 glCallList (1);
208
209 glPopMatrix ();
210 }
211
212 glPopMatrix ();
213
214 glRenderMode (GL_RENDER);
215
216 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
217
218 glMatrixMode (GL_PROJECTION);
219 glPushMatrix ();
220 glLoadIdentity ();
221
222 glMatrixMode (GL_MODELVIEW);
223 glPushMatrix ();
224 glLoadIdentity ();
225
226 glScalef (2.0 / XStuff->windowWidth, 2.0 / XStuff->windowHeight, 1.0);
227 glTranslatef (-0.5 * XStuff->windowWidth, -0.5 * XStuff->windowHeight, 0.0);
228
229 glClear (GL_COLOR_BUFFER_BIT);
230
231 glEnable (GL_TEXTURE_2D);
232 glBlendFunc (GL_ONE, GL_ONE);
233 glEnable (GL_BLEND);
234
235 glBegin (GL_QUADS);
236
237 w = XStuff->windowWidth >> 7;
238
239 for (j = 0; j < NRPOINTS; j++) {
240 glColor3f (0.25 - 0.15 * j / NRPOINTS, 0.15 + 0.10 * j / NRPOINTS, 0.06 + 0.14 * j / NRPOINTS);
241 for (i = 0; i < NRLINES; i++) {
242 offset = 3 * (i * NRPOINTS + j);
243 x = fb_buffer[offset + 1];
244 y = fb_buffer[offset + 2];
245
246 glTexCoord2f (0.0, 0.0);
247 glVertex2f (x - w, y - w);
248
249 glTexCoord2f (1.0, 0.0);
250 glVertex2f (x + w, y - w);
251
252 glTexCoord2f (1.0, 1.0);
253 glVertex2f (x + w, y + w);
254
255 glTexCoord2f (0.0, 1.0);
256 glVertex2f (x - w, y + w);
257 }
258 }
259
260 glEnd ();
261
262 glMatrixMode (GL_MODELVIEW);
263 glPopMatrix ();
264 glMatrixMode (GL_PROJECTION);
265 glPopMatrix ();
266 } else {
267 int i;
268
269 glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
270
271 glMatrixMode (GL_MODELVIEW);
272 glLoadIdentity ();
273 gluLookAt (200, 0, 0, 0, 0, 0, 0, 0, 1);
274
275 glPushMatrix ();
276 glRotated (90, 0, 1, 0);
277 glRotated (10 * currentTime, 0, 0, 1);
278
279 glColor3d (0.9, 0.7, 0.5);
280
281 glNewList (1, GL_COMPILE);
282 Horn (NRPOINTS, 315 * sin (currentTime * 0.237), 50 + 20 * sin (currentTime * 0.133), 1500 * sin (currentTime * 0.213), 7.5 + 2.5 * sin (currentTime * 0.173), 0.6 + 0.1 * sin (currentTime * 0.317));
283 glEndList ();
284
285 if (dOffAngle)
286 glRotated (45, 1, 1, 0);
287
288 for (i = 0; i < NRLINES; i++) {
289 glPushMatrix ();
290 glRotated (360 * i / NRLINES, 0, 0, 1);
291 glRotated (45, 1, 0, 0);
292 glTranslated (0, 0, 2);
293 glCallList (1);
294 glPopMatrix ();
295 }
296
297 glPopMatrix ();
298 }
299 }
300
setDefaults(int preset)301 void setDefaults (int preset)
302 {
303 dGeometry = preset;
304
305 switch (preset) {
306 case TRIANGLES:
307 NRPOINTS = 80;
308 NRLINES = 32;
309
310 break;
311 case SPHERES:
312 NRPOINTS = 80;
313 NRLINES = 30;
314
315 break;
316 case BIGSPHERES:
317 NRPOINTS = 20;
318 NRLINES = 5;
319
320 break;
321 case POINTS:
322 NRPOINTS = 250;
323 NRLINES = 30;
324
325 break;
326 case LIGHTMAP:
327 NRPOINTS = 150;
328 NRLINES = 20;
329
330 break;
331 }
332 }
333
hack_handle_opts(int argc,char ** argv)334 void hack_handle_opts (int argc, char **argv)
335 {
336 int change_flag = 0;
337
338 setDefaults(LIGHTMAP);
339 dOffAngle = 0;
340
341 while (1) {
342 int c;
343
344 #ifdef HAVE_GETOPT_H
345 static struct option long_options[] = {
346 {"help", 0, 0, 'h'},
347 DRIVER_OPTIONS_LONG {"preset", 1, 0, 'P'},
348 {"triangles", 0, 0, 0},
349 {"spheres", 0, 0, 1},
350 {"bigspheres", 0, 0, 2},
351 {"points", 0, 0, 3},
352 {"lightmap", 0, 0, 4},
353 {"lines", 1, 0, 'l'},
354 {"points", 1, 0, 'p'},
355 {"offangle", 0, 0, 'o'},
356 {0, 0, 0, 0}
357 };
358
359 c = getopt_long (argc, argv, DRIVER_OPTIONS_SHORT "hP:l:p:o", long_options, NULL);
360 #else
361 c = getopt (argc, argv, DRIVER_OPTIONS_SHORT "hP:l:p:o");
362 #endif
363 if (c == -1)
364 break;
365
366 switch (c) {
367 DRIVER_OPTIONS_CASES case 'h':printf ("%s:"
368 #ifndef HAVE_GETOPT_H
369 " Not built with GNU getopt.h, long options *NOT* enabled."
370 #endif
371 "\n" DRIVER_OPTIONS_HELP "\t--preset/-P <arg>\n" "\t--triangles\n"
372 "\t--spheres\n" "\t--bigspheres\n" "\t--points\n" "\t--lightmap\n"
373 "\t--lines/-l <arg>\n" "\t--points/-p <arg>\n" "\t--offangle\n", argv[0]);
374 exit (1);
375 case 'P':
376 change_flag = 1;
377 setDefaults (strtol_minmaxdef (optarg, 10, 1, 5, 0, 1, "--preset: "));
378 break;
379 case 0:
380 case 1:
381 case 2:
382 case 3:
383 case 4:
384 change_flag = 1;
385 setDefaults (c + 1);
386 break;
387 case 'l':
388 change_flag = 1;
389 NRLINES = strtol_minmaxdef (optarg, 10, 1, 1024, 0, 1, "--lines: ");
390 break;
391 case 'p':
392 change_flag = 1;
393 NRPOINTS = strtol_minmaxdef (optarg, 10, 1, 4096, 0, 1, "--points: ");
394 break;
395 case 'o':
396 change_flag = 1;
397 dOffAngle = 1;
398 }
399 }
400
401 if (!change_flag) {
402 dGeometry = rsRandi (5) + 1;
403 dOffAngle = rsRandi (2);
404
405 switch (dGeometry) {
406 case TRIANGLES:
407 case SPHERES:
408 NRLINES = rsRandi (7) + 2;
409 NRPOINTS = rsRandi (96) + 32;
410 break;
411
412 case BIGSPHERES:
413 NRLINES = rsRandi (7) + 4;
414 NRPOINTS = rsRandi (32) + 4;
415 break;
416
417 case POINTS:
418 case LIGHTMAP:
419 NRLINES = rsRandi (32) + 4;
420 NRPOINTS = rsRandi (64) + 64;
421 }
422 }
423 }
424
425