blob: d43c662234e475444e842364b99223d798c3e90a [file] [log] [blame]
Brian Paul5b0a7f32000-06-27 16:52:38 +00001/*
2 * This program is under the GNU GPL.
3 * Use at your own risk.
4 *
5 * written by David Bucciarelli (tech.hmw@plus.it)
6 * Humanware s.r.l.
7 */
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <math.h>
12#include <time.h>
13
Karl Schultz164ce122002-01-16 00:48:43 +000014#if defined (WIN32)|| defined(_WIN32)
Brian Paul5b0a7f32000-06-27 16:52:38 +000015#include <windows.h>
16#include <mmsystem.h>
17#endif
18
19#include <GL/glut.h>
20
pescod1ff1f62000-12-24 22:53:54 +000021#include "readtex.c"
Brian Paul5b0a7f32000-06-27 16:52:38 +000022
23#ifdef XMESA
24#include "GL/xmesa.h"
25static int fullscreen = 1;
26#endif
27
28static int WIDTH = 640;
29static int HEIGHT = 480;
30
Brian Pauld49b34a2000-09-12 18:44:45 +000031static GLint T0;
32static GLint Frames;
33
Brian Paul5b0a7f32000-06-27 16:52:38 +000034#define MAX_LOD 9
35
36#define TEX_SKY_WIDTH 256
37#define TEX_SKY_HEIGHT TEX_SKY_WIDTH
38
39#ifndef M_PI
40#define M_PI 3.1415926535
41#endif
42
43#define FROM_NONE 0
44#define FROM_DOWN 1
45#define FROM_UP 2
46#define FROM_LEFT 3
47#define FROM_RIGHT 4
48#define FROM_FRONT 5
49#define FROM_BACK 6
50
51static int win = 0;
52
53static float obs[3] = { 3.8, 0.0, 0.0 };
54static float dir[3];
55static float v = 0.0;
56static float alpha = -90.0;
57static float beta = 90.0;
58
59static int fog = 1;
60static int bfcull = 1;
61static int usetex = 1;
62static int help = 1;
63static int poutline = 0;
64static int normext = 1;
65static int joyavailable = 0;
66static int joyactive = 0;
67static int LODbias = 3;
68static int maxdepth = MAX_LOD;
69
70static unsigned int totpoly = 0;
71
72static GLuint t1id, t2id;
73static GLuint skydlist, LODdlist[MAX_LOD], LODnumpoly[MAX_LOD];
74
75static void
76initlight(void)
77{
78 GLfloat lspec[4] = { 1.0, 1.0, 1.0, 1.0 };
79 static GLfloat lightpos[4] = { 30, 15.0, 30.0, 1.0 };
80
81 glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
82 glLightfv(GL_LIGHT0, GL_SPECULAR, lspec);
83
84 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 32.0);
85 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, lspec);
86}
87
88static void
89initdlists(void)
90{
Brian Paul02e8a032000-06-27 17:04:43 +000091 static int slicetable[MAX_LOD][2] = {
Brian Paul5b0a7f32000-06-27 16:52:38 +000092 {21, 10},
93 {18, 9},
94 {15, 8},
95 {12, 7},
96 {9, 6},
97 {7, 5},
98 {5, 4},
99 {4, 3},
100 {3, 2}
101 };
102 GLUquadricObj *obj;
103 int i, xslices, yslices;
104
105 obj = gluNewQuadric();
106
107 skydlist = glGenLists(1);
108 glNewList(skydlist, GL_COMPILE);
109 glBindTexture(GL_TEXTURE_2D, t2id);
110 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
111 glColor3f(1.0f, 1.0f, 1.0f);
112
113 gluQuadricDrawStyle(obj, GLU_FILL);
114 gluQuadricNormals(obj, GLU_NONE);
115 gluQuadricTexture(obj, GL_TRUE);
116 gluQuadricOrientation(obj, GLU_INSIDE);
117 gluSphere(obj, 40.0f, 18, 9);
118
119 glEndList();
120
121 for (i = 0; i < MAX_LOD; i++) {
122 LODdlist[i] = glGenLists(1);
123 glNewList(LODdlist[i], GL_COMPILE);
124
125 gluQuadricDrawStyle(obj, GLU_FILL);
126 gluQuadricNormals(obj, GLU_SMOOTH);
127 gluQuadricTexture(obj, GL_TRUE);
128 gluQuadricOrientation(obj, GLU_OUTSIDE);
129 xslices = slicetable[i][0];
130 yslices = slicetable[i][1];
131 gluSphere(obj, 1.0f, xslices, yslices);
132 LODnumpoly[i] = xslices * (yslices - 2) + 2 * (xslices - 1);
133
134 glEndList();
135 }
136}
137
138static void
139inittextures(void)
140{
141 GLubyte tsky[TEX_SKY_HEIGHT][TEX_SKY_WIDTH][3];
142 GLuint x, y;
143 GLfloat fact;
144 GLenum gluerr;
145
146 /* Brick */
147
148 glGenTextures(1, &t1id);
149 glBindTexture(GL_TEXTURE_2D, t1id);
150
151 if (!LoadRGBMipmaps("../images/bw.rgb", 3)) {
152 fprintf(stderr, "Error reading a texture.\n");
153 exit(-1);
154 }
155
156 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
157 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
158
159 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
160 GL_LINEAR_MIPMAP_LINEAR);
161 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
162
163 /* Sky */
164
165 glGenTextures(1, &t2id);
166 glBindTexture(GL_TEXTURE_2D, t2id);
167
168 for (y = 0; y < TEX_SKY_HEIGHT; y++)
169 for (x = 0; x < TEX_SKY_WIDTH; x++)
170 if (y < TEX_SKY_HEIGHT / 2) {
171 fact = y / (GLfloat) (TEX_SKY_HEIGHT / 2);
172 tsky[y][x][0] =
173 (GLubyte) (255.0f * (0.1f * fact + 0.3f * (1.0f - fact)));
174 tsky[y][x][1] =
175 (GLubyte) (255.0f * (0.2f * fact + 1.0f * (1.0f - fact)));
176 tsky[y][x][2] = 255;
177 }
178 else {
179 tsky[y][x][0] = tsky[TEX_SKY_HEIGHT - y - 1][x][0];
180 tsky[y][x][1] = tsky[TEX_SKY_HEIGHT - y - 1][x][1];
181 tsky[y][x][2] = 255;
182 }
183
184 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
185 if (
186 (gluerr =
187 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TEX_SKY_WIDTH, TEX_SKY_HEIGHT,
188 GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *) (tsky)))) {
Brian Paul1972ac62002-08-08 17:12:38 +0000189 fprintf(stderr, "GLULib%s\n", (char *) gluErrorString(gluerr));
Brian Paul5b0a7f32000-06-27 16:52:38 +0000190 exit(-1);
191 }
192
193 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
194 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
195
196 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
197 GL_LINEAR_MIPMAP_LINEAR);
198 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
199}
200
Brian Paul5b0a7f32000-06-27 16:52:38 +0000201static void
202calcposobs(void)
203{
204 dir[0] = sin(alpha * M_PI / 180.0);
205 dir[1] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0);
206 dir[2] = cos(beta * M_PI / 180.0);
207
Brian Paula41edc32001-05-09 20:02:28 +0000208 if (dir[0] < 1.0e-5 && dir[0] > -1.0e-5)
209 dir[0] = 0;
210 if (dir[1] < 1.0e-5 && dir[1] > -1.0e-5)
211 dir[1] = 0;
212 if (dir[2] < 1.0e-5 && dir[2] > -1.0e-5)
213 dir[2] = 0;
214
Brian Paul5b0a7f32000-06-27 16:52:38 +0000215 obs[0] += v * dir[0];
216 obs[1] += v * dir[1];
217 obs[2] += v * dir[2];
218}
219
220static void
221special(int k, int x, int y)
222{
223 switch (k) {
224 case GLUT_KEY_LEFT:
225 alpha -= 2.0;
226 break;
227 case GLUT_KEY_RIGHT:
228 alpha += 2.0;
229 break;
230 case GLUT_KEY_DOWN:
231 beta -= 2.0;
232 break;
233 case GLUT_KEY_UP:
234 beta += 2.0;
235 break;
236 }
237}
238
239static void
240key(unsigned char k, int x, int y)
241{
242 switch (k) {
243 case 27:
244 exit(0);
245 break;
246
247 case 'a':
248 v += 0.01;
249 break;
250 case 'z':
251 v -= 0.01;
252 break;
253
254#ifdef XMESA
255 case ' ':
256 fullscreen = (!fullscreen);
257 XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
258 break;
259#endif
260
261 case '+':
262 LODbias--;
263 break;
264 case '-':
265 LODbias++;
266 break;
267 case 'j':
268 joyactive = (!joyactive);
269 break;
270 case 'h':
271 help = (!help);
272 break;
273 case 'f':
274 fog = (!fog);
275 break;
276 case 't':
277 usetex = (!usetex);
278 break;
279 case 'n':
280 normext = (!normext);
281 break;
282 case 'b':
283 if (bfcull) {
284 glDisable(GL_CULL_FACE);
285 bfcull = 0;
286 }
287 else {
288 glEnable(GL_CULL_FACE);
289 bfcull = 1;
290 }
291 break;
292 case 'p':
293 if (poutline) {
294 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
295 poutline = 0;
296 usetex = 1;
297 }
298 else {
299 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
300 poutline = 1;
301 usetex = 0;
302 }
303 break;
304 }
305}
306
307static void
308reshape(int w, int h)
309{
310 WIDTH = w;
311 HEIGHT = h;
312 glMatrixMode(GL_PROJECTION);
313 glLoadIdentity();
314 gluPerspective(90.0, w / (float) h, 0.8, 100.0);
315 glMatrixMode(GL_MODELVIEW);
316 glLoadIdentity();
317 glViewport(0, 0, w, h);
318}
319
320static void
321printstring(void *font, char *string)
322{
323 int len, i;
324
325 len = (int) strlen(string);
326 for (i = 0; i < len; i++)
327 glutBitmapCharacter(font, string[i]);
328}
329
330static void
331printhelp(void)
332{
333 glEnable(GL_BLEND);
334 glColor4f(0.5, 0.5, 0.5, 0.5);
335 glRecti(40, 40, 600, 440);
336 glDisable(GL_BLEND);
337
338 glColor3f(1.0, 0.0, 0.0);
339 glRasterPos2i(300, 420);
340 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help");
341
342 glRasterPos2i(60, 390);
343 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Toggle Help");
344 glRasterPos2i(60, 360);
345 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Toggle Textures");
346 glRasterPos2i(60, 330);
347 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Toggle Fog");
348 glRasterPos2i(60, 300);
349 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "b - Toggle Back face culling");
350 glRasterPos2i(60, 270);
351 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate");
352 glRasterPos2i(60, 240);
353 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity");
354 glRasterPos2i(60, 210);
355 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity");
356 glRasterPos2i(60, 180);
357 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "p - Toggle Wire frame");
358 glRasterPos2i(60, 150);
359 printstring(GLUT_BITMAP_TIMES_ROMAN_24,
Roland Scheidegger7225a722004-05-21 14:51:33 +0000360 "n - Toggle GL_EXT_rescale_normal extension");
Brian Paul5b0a7f32000-06-27 16:52:38 +0000361 glRasterPos2i(60, 120);
362 printstring(GLUT_BITMAP_TIMES_ROMAN_24,
363 "+/- - Increase/decrease the Object maximum LOD");
364
365 glRasterPos2i(60, 90);
366 if (joyavailable)
367 printstring(GLUT_BITMAP_TIMES_ROMAN_24,
368 "j - Toggle jostick control (Joystick control available)");
369 else
370 printstring(GLUT_BITMAP_TIMES_ROMAN_24,
371 "(No Joystick control available)");
372}
373
374static void
375dojoy(void)
376{
377#ifdef _WIN32
378 static UINT max[2] = { 0, 0 };
379 static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2];
380 MMRESULT res;
381 JOYINFO joy;
382
383 res = joyGetPos(JOYSTICKID1, &joy);
384
385 if (res == JOYERR_NOERROR) {
386 joyavailable = 1;
387
388 if (max[0] < joy.wXpos)
389 max[0] = joy.wXpos;
390 if (min[0] > joy.wXpos)
391 min[0] = joy.wXpos;
392 center[0] = (max[0] + min[0]) / 2;
393
394 if (max[1] < joy.wYpos)
395 max[1] = joy.wYpos;
396 if (min[1] > joy.wYpos)
397 min[1] = joy.wYpos;
398 center[1] = (max[1] + min[1]) / 2;
399
400 if (joyactive) {
401 if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0]))
402 alpha -=
403 2.0 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]);
404 if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1]))
405 beta += 2.0 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]);
406
407 if (joy.wButtons & JOY_BUTTON1)
408 v += 0.01;
409 if (joy.wButtons & JOY_BUTTON2)
410 v -= 0.01;
411 }
412 }
413 else
414 joyavailable = 0;
415#endif
416}
417
418static void
419drawipers(int depth, int from)
420{
421 int lod;
422
423 if (depth == maxdepth)
424 return;
425
426 lod = depth + LODbias;
427 if (lod < 0)
428 lod = 0;
429 if (lod >= MAX_LOD)
430 return;
431
432 switch (from) {
433 case FROM_NONE:
434 glCallList(LODdlist[lod]);
435
436 depth++;
437 drawipers(depth, FROM_DOWN);
438 drawipers(depth, FROM_UP);
439 drawipers(depth, FROM_FRONT);
440 drawipers(depth, FROM_BACK);
441 drawipers(depth, FROM_LEFT);
442 drawipers(depth, FROM_RIGHT);
443 break;
444 case FROM_FRONT:
445 glPushMatrix();
446 glTranslatef(0.0f, -1.5f, 0.0f);
447 glScalef(0.5f, 0.5f, 0.5f);
448
449 glCallList(LODdlist[lod]);
450
451 depth++;
452 drawipers(depth, FROM_DOWN);
453 drawipers(depth, FROM_UP);
454 drawipers(depth, FROM_FRONT);
455 drawipers(depth, FROM_LEFT);
456 drawipers(depth, FROM_RIGHT);
457 glPopMatrix();
458 break;
459 case FROM_BACK:
460 glPushMatrix();
461 glTranslatef(0.0f, 1.5f, 0.0f);
462 glScalef(0.5f, 0.5f, 0.5f);
463
464 glCallList(LODdlist[lod]);
465
466 depth++;
467 drawipers(depth, FROM_DOWN);
468 drawipers(depth, FROM_UP);
469 drawipers(depth, FROM_BACK);
470 drawipers(depth, FROM_LEFT);
471 drawipers(depth, FROM_RIGHT);
472 glPopMatrix();
473 break;
474 case FROM_LEFT:
475 glPushMatrix();
476 glTranslatef(-1.5f, 0.0f, 0.0f);
477 glScalef(0.5f, 0.5f, 0.5f);
478
479 glCallList(LODdlist[lod]);
480
481 depth++;
482 drawipers(depth, FROM_DOWN);
483 drawipers(depth, FROM_UP);
484 drawipers(depth, FROM_FRONT);
485 drawipers(depth, FROM_BACK);
486 drawipers(depth, FROM_LEFT);
487 glPopMatrix();
488 break;
489 case FROM_RIGHT:
490 glPushMatrix();
491 glTranslatef(1.5f, 0.0f, 0.0f);
492 glScalef(0.5f, 0.5f, 0.5f);
493
494 glCallList(LODdlist[lod]);
495
496 depth++;
497 drawipers(depth, FROM_DOWN);
498 drawipers(depth, FROM_UP);
499 drawipers(depth, FROM_FRONT);
500 drawipers(depth, FROM_BACK);
501 drawipers(depth, FROM_RIGHT);
502 glPopMatrix();
503 break;
504 case FROM_DOWN:
505 glPushMatrix();
506 glTranslatef(0.0f, 0.0f, 1.5f);
507 glScalef(0.5f, 0.5f, 0.5f);
508
509 glCallList(LODdlist[lod]);
510
511 depth++;
512 drawipers(depth, FROM_DOWN);
513 drawipers(depth, FROM_FRONT);
514 drawipers(depth, FROM_BACK);
515 drawipers(depth, FROM_LEFT);
516 drawipers(depth, FROM_RIGHT);
517 glPopMatrix();
518 break;
519 case FROM_UP:
520 glPushMatrix();
521 glTranslatef(0.0f, 0.0f, -1.5f);
522 glScalef(0.5f, 0.5f, 0.5f);
523
524 glCallList(LODdlist[lod]);
525
526 depth++;
527 drawipers(depth, FROM_UP);
528 drawipers(depth, FROM_FRONT);
529 drawipers(depth, FROM_BACK);
530 drawipers(depth, FROM_LEFT);
531 drawipers(depth, FROM_RIGHT);
532 glPopMatrix();
533 break;
534 }
535
536 totpoly += LODnumpoly[lod];
537}
538
539static void
540draw(void)
541{
Brian Pauld49b34a2000-09-12 18:44:45 +0000542 static char frbuf[80] = "";
Brian Paul5b0a7f32000-06-27 16:52:38 +0000543 static GLfloat alpha = 0.0f;
544 static GLfloat beta = 0.0f;
Brian Pauld49b34a2000-09-12 18:44:45 +0000545 static float fr = 0.0;
Brian Paul5b0a7f32000-06-27 16:52:38 +0000546
547 dojoy();
548
549 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
550
551 if (usetex)
552 glEnable(GL_TEXTURE_2D);
553 else
554 glDisable(GL_TEXTURE_2D);
555
556 if (fog)
557 glEnable(GL_FOG);
558 else
559 glDisable(GL_FOG);
560
561 glPushMatrix();
562 calcposobs();
563 gluLookAt(obs[0], obs[1], obs[2],
564 obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2],
565 0.0, 0.0, 1.0);
566
567 /* Scene */
568 glEnable(GL_DEPTH_TEST);
569
570 glShadeModel(GL_SMOOTH);
571 glBindTexture(GL_TEXTURE_2D, t1id);
572 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
573 glColor3f(1.0f, 1.0f, 1.0f);
574 glEnable(GL_LIGHT0);
575 glEnable(GL_LIGHTING);
576
577 if (normext)
578 glEnable(GL_RESCALE_NORMAL_EXT);
579 else
580 glEnable(GL_NORMALIZE);
581
582 glPushMatrix();
583 glRotatef(alpha, 0.0f, 0.0f, 1.0f);
584 glRotatef(beta, 1.0f, 0.0f, 0.0f);
585 totpoly = 0;
586 drawipers(0, FROM_NONE);
587 glPopMatrix();
588
589 alpha += 0.5f;
590 beta += 0.3f;
591
592 glDisable(GL_LIGHTING);
593 glDisable(GL_LIGHT0);
594 glShadeModel(GL_FLAT);
595
596 if (normext)
597 glDisable(GL_RESCALE_NORMAL_EXT);
598 else
599 glDisable(GL_NORMALIZE);
600
601 glCallList(skydlist);
602
603 glPopMatrix();
604
605 /* Help Screen */
606
Brian Paul5b0a7f32000-06-27 16:52:38 +0000607 sprintf(frbuf,
608 "Frame rate: %0.2f LOD: %d Tot. poly.: %d Poly/sec: %.1f",
Brian Pauld49b34a2000-09-12 18:44:45 +0000609 fr, LODbias, totpoly, totpoly * fr);
Brian Paul5b0a7f32000-06-27 16:52:38 +0000610
611 glDisable(GL_TEXTURE_2D);
612 glDisable(GL_FOG);
613 glShadeModel(GL_FLAT);
614 glDisable(GL_DEPTH_TEST);
615
616 glMatrixMode(GL_PROJECTION);
617 glPushMatrix();
618 glLoadIdentity();
619 glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0);
620
621 glMatrixMode(GL_MODELVIEW);
622 glLoadIdentity();
623
624 glColor3f(1.0, 0.0, 0.0);
625 glRasterPos2i(10, 10);
626 printstring(GLUT_BITMAP_HELVETICA_18, frbuf);
627 glRasterPos2i(350, 470);
628 printstring(GLUT_BITMAP_HELVETICA_10,
629 "IperS V1.0 Written by David Bucciarelli (tech.hmw@plus.it)");
630
631 if (help)
632 printhelp();
633
634 glMatrixMode(GL_PROJECTION);
635 glPopMatrix();
636 glMatrixMode(GL_MODELVIEW);
637
638 glutSwapBuffers();
639
Brian Pauld49b34a2000-09-12 18:44:45 +0000640 Frames++;
641 {
642 GLint t = glutGet(GLUT_ELAPSED_TIME);
643 if (t - T0 >= 2000) {
644 GLfloat seconds = (t - T0) / 1000.0;
645 fr = Frames / seconds;
646 T0 = t;
647 Frames = 0;
648 }
649 }
Brian Paul5b0a7f32000-06-27 16:52:38 +0000650}
651
652int
653main(int ac, char **av)
654{
655 float fogcolor[4] = { 0.7, 0.7, 0.7, 1.0 };
656
657 fprintf(stderr,
658 "IperS V1.0\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
659
660 glutInitWindowPosition(0, 0);
661 glutInitWindowSize(WIDTH, HEIGHT);
662 glutInit(&ac, av);
663
664 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
665
666 if (!(win = glutCreateWindow("IperS"))) {
667 fprintf(stderr, "Error, couldn't open window\n");
668 exit(-1);
669 }
670
671 reshape(WIDTH, HEIGHT);
672
673 glShadeModel(GL_SMOOTH);
674 glEnable(GL_DEPTH_TEST);
675 glEnable(GL_CULL_FACE);
676 glEnable(GL_TEXTURE_2D);
677
678 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
679
680 glEnable(GL_FOG);
681 glFogi(GL_FOG_MODE, GL_EXP2);
682 glFogfv(GL_FOG_COLOR, fogcolor);
683
684 glFogf(GL_FOG_DENSITY, 0.006);
685
686 glHint(GL_FOG_HINT, GL_NICEST);
687
688 inittextures();
689 initdlists();
690 initlight();
691
692 glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]);
693 glClear(GL_COLOR_BUFFER_BIT);
694
695 calcposobs();
696
697 glutReshapeFunc(reshape);
698 glutDisplayFunc(draw);
699 glutKeyboardFunc(key);
700 glutSpecialFunc(special);
701 glutIdleFunc(draw);
702
703 glutMainLoop();
704
705 return 0;
706}