blob: d495b31b4f67183518bf3e8fe49b01d0dad512be [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
14#ifdef WIN32
15#include <windows.h>
16#endif
17
18#include <GL/glut.h>
pescod1ff1f62000-12-24 22:53:54 +000019#include "readtex.c"
Brian Paul0a355dc2001-03-27 17:30:51 +000020#include "tunneldat.h"
Brian Paul5b0a7f32000-06-27 16:52:38 +000021
22#ifdef XMESA
23#include "GL/xmesa.h"
24static int fullscreen = 1;
25#endif
26
27static int WIDTH = 640;
28static int HEIGHT = 480;
29
Brian Paul4df1f7c2000-09-12 17:38:22 +000030static GLint T0 = 0;
31static GLint Frames = 0;
Brian Paul0a355dc2001-03-27 17:30:51 +000032static GLint NiceFog = 1;
Brian Paul5b0a7f32000-06-27 16:52:38 +000033
34#define NUMBLOC 5
35
36#ifndef M_PI
37#define M_PI 3.1415926535
38#endif
39
Brian Paul0a355dc2001-03-27 17:30:51 +000040/*
Brian Paul5b0a7f32000-06-27 16:52:38 +000041extern int striplength_skin_13[];
42extern float stripdata_skin_13[];
43
44extern int striplength_skin_12[];
45extern float stripdata_skin_12[];
46
47extern int striplength_skin_11[];
48extern float stripdata_skin_11[];
49
50extern int striplength_skin_9[];
51extern float stripdata_skin_9[];
Brian Paul0a355dc2001-03-27 17:30:51 +000052*/
Brian Paul5b0a7f32000-06-27 16:52:38 +000053
54static int win = 0;
55
56static float obs[3] = { 1000.0, 0.0, 2.0 };
57static float dir[3];
58static float v = 0.5;
59static float alpha = 90.0;
60static float beta = 90.0;
61
Brian Paul04484882000-10-23 20:06:36 +000062static int fog = 1;
Brian Paul5b0a7f32000-06-27 16:52:38 +000063static int bfcull = 1;
64static int usetex = 1;
65static int cstrip = 0;
66static int help = 1;
67static int joyavailable = 0;
68static int joyactive = 0;
69
70static GLuint t1id, t2id;
71
72static void
73inittextures(void)
74{
Brian Paul5b0a7f32000-06-27 16:52:38 +000075 glGenTextures(1, &t1id);
76 glBindTexture(GL_TEXTURE_2D, t1id);
77
78 if (!LoadRGBMipmaps("../images/tile.rgb", GL_RGB)) {
79 fprintf(stderr, "Error reading a texture.\n");
80 exit(-1);
81 }
82
83 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
84 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
85
86 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
87 GL_LINEAR_MIPMAP_LINEAR);
88 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
89
90 glGenTextures(1, &t2id);
91 glBindTexture(GL_TEXTURE_2D, t2id);
92
93 if (!LoadRGBMipmaps("../images/bw.rgb", GL_RGB)) {
94 fprintf(stderr, "Error reading a texture.\n");
95 exit(-1);
96 }
97
98 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
99 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
100
101 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
102 GL_LINEAR_MIPMAP_LINEAR);
103 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
104
105 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
106}
107
108static void
Brian Paul0a355dc2001-03-27 17:30:51 +0000109drawobjs(const int *l, const float *f)
Brian Paul5b0a7f32000-06-27 16:52:38 +0000110{
111 int mend, j;
112
113 if (cstrip) {
114 float r = 0.33, g = 0.33, b = 0.33;
115
116 for (; (*l) != 0;) {
117 mend = *l++;
118
119 r += 0.33;
120 if (r > 1.0) {
121 r = 0.33;
122 g += 0.33;
123 if (g > 1.0) {
124 g = 0.33;
125 b += 0.33;
126 if (b > 1.0)
127 b = 0.33;
128 }
129 }
130
131 glColor3f(r, g, b);
132 glBegin(GL_TRIANGLE_STRIP);
133 for (j = 0; j < mend; j++) {
134 f += 4;
135 glTexCoord2fv(f);
136 f += 2;
137 glVertex3fv(f);
138 f += 3;
139 }
140 glEnd();
141 }
142 }
143 else
144 for (; (*l) != 0;) {
145 mend = *l++;
146
147 glBegin(GL_TRIANGLE_STRIP);
148 for (j = 0; j < mend; j++) {
149 glColor4fv(f);
150 f += 4;
151 glTexCoord2fv(f);
152 f += 2;
153 glVertex3fv(f);
154 f += 3;
155 }
156 glEnd();
157 }
158}
159
Brian Paul5b0a7f32000-06-27 16:52:38 +0000160static void
161calcposobs(void)
162{
163 dir[0] = sin(alpha * M_PI / 180.0);
164 dir[1] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0);
165 dir[2] = cos(beta * M_PI / 180.0);
166
167 obs[0] += v * dir[0];
168 obs[1] += v * dir[1];
169 obs[2] += v * dir[2];
170}
171
172static void
173special(int k, int x, int y)
174{
175 switch (k) {
176 case GLUT_KEY_LEFT:
177 alpha -= 2.0;
178 break;
179 case GLUT_KEY_RIGHT:
180 alpha += 2.0;
181 break;
182 case GLUT_KEY_DOWN:
183 beta -= 2.0;
184 break;
185 case GLUT_KEY_UP:
186 beta += 2.0;
187 break;
188 }
189}
190
191static void
192key(unsigned char k, int x, int y)
193{
194 switch (k) {
195 case 27:
196 exit(0);
197 break;
198
199 case 'a':
200 v += 0.01;
201 break;
202 case 'z':
203 v -= 0.01;
204 break;
205
206#ifdef XMESA
207 case ' ':
208 fullscreen = (!fullscreen);
209 XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
210 break;
211#endif
Brian Paul5b0a7f32000-06-27 16:52:38 +0000212 case 'j':
213 joyactive = (!joyactive);
214 break;
215 case 'h':
216 help = (!help);
217 break;
218 case 'f':
219 fog = (!fog);
220 break;
221 case 't':
222 usetex = (!usetex);
223 break;
224 case 'b':
225 if (bfcull) {
226 glDisable(GL_CULL_FACE);
227 bfcull = 0;
228 }
229 else {
230 glEnable(GL_CULL_FACE);
231 bfcull = 1;
232 }
233 break;
234 case 'm':
235 cstrip = (!cstrip);
236 break;
237
238 case 'd':
239 fprintf(stderr, "Deleting textures...\n");
240 glDeleteTextures(1, &t1id);
241 glDeleteTextures(1, &t2id);
242 fprintf(stderr, "Loading textures...\n");
243 inittextures();
244 fprintf(stderr, "Done.\n");
245 break;
Brian Paul0a355dc2001-03-27 17:30:51 +0000246 case 'n':
247 NiceFog = !NiceFog;
248 printf("NiceFog %d\n", NiceFog);
249 break;
Brian Paul5b0a7f32000-06-27 16:52:38 +0000250 }
Brian Paul04484882000-10-23 20:06:36 +0000251 glutPostRedisplay();
Brian Paul5b0a7f32000-06-27 16:52:38 +0000252}
253
254static void
255reshape(int w, int h)
256{
257 WIDTH = w;
258 HEIGHT = h;
259 glMatrixMode(GL_PROJECTION);
260 glLoadIdentity();
261 gluPerspective(80.0, w / (float) h, 1.0, 50.0);
262 glMatrixMode(GL_MODELVIEW);
263 glLoadIdentity();
264 glViewport(0, 0, w, h);
265}
266
267static void
268printstring(void *font, char *string)
269{
270 int len, i;
271
272 len = (int) strlen(string);
273 for (i = 0; i < len; i++)
274 glutBitmapCharacter(font, string[i]);
275}
276
277static void
278printhelp(void)
279{
280 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
281 glColor4f(0.0, 0.0, 0.0, 0.5);
282 glRecti(40, 40, 600, 440);
283
284 glColor3f(1.0, 0.0, 0.0);
285 glRasterPos2i(300, 420);
286 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help");
287
288 glRasterPos2i(60, 390);
289 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Togle Help");
290 glRasterPos2i(60, 360);
291 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Togle Textures");
292 glRasterPos2i(60, 330);
293 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Togle Fog");
294 glRasterPos2i(60, 300);
295 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "m - Togle strips");
296 glRasterPos2i(60, 270);
297 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "b - Togle Back face culling");
298 glRasterPos2i(60, 240);
299 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate");
300 glRasterPos2i(60, 210);
301 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity");
302 glRasterPos2i(60, 180);
303 printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity");
304
305 glRasterPos2i(60, 150);
306 if (joyavailable)
307 printstring(GLUT_BITMAP_TIMES_ROMAN_24,
308 "j - Togle jostick control (Joystick control available)");
309 else
310 printstring(GLUT_BITMAP_TIMES_ROMAN_24,
311 "(No Joystick control available)");
312}
313
314static void
315dojoy(void)
316{
317#ifdef WIN32
318 static UINT max[2] = { 0, 0 };
319 static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2];
320 MMRESULT res;
321 JOYINFO joy;
322
323 res = joyGetPos(JOYSTICKID1, &joy);
324
325 if (res == JOYERR_NOERROR) {
326 joyavailable = 1;
327
328 if (max[0] < joy.wXpos)
329 max[0] = joy.wXpos;
330 if (min[0] > joy.wXpos)
331 min[0] = joy.wXpos;
332 center[0] = (max[0] + min[0]) / 2;
333
334 if (max[1] < joy.wYpos)
335 max[1] = joy.wYpos;
336 if (min[1] > joy.wYpos)
337 min[1] = joy.wYpos;
338 center[1] = (max[1] + min[1]) / 2;
339
340 if (joyactive) {
341 if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0]))
342 alpha -=
343 2.0 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]);
344 if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1]))
345 beta += 2.0 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]);
346
347 if (joy.wButtons & JOY_BUTTON1)
348 v += 0.01;
349 if (joy.wButtons & JOY_BUTTON2)
350 v -= 0.01;
351 }
352 }
353 else
354 joyavailable = 0;
355#endif
356}
357
358static void
359draw(void)
360{
Brian Paul4df1f7c2000-09-12 17:38:22 +0000361 static char frbuf[80] = "";
Brian Paul5b0a7f32000-06-27 16:52:38 +0000362 int i;
Brian Pauld49b34a2000-09-12 18:44:45 +0000363 float base, offset;
Brian Paul5b0a7f32000-06-27 16:52:38 +0000364
Brian Paul0a355dc2001-03-27 17:30:51 +0000365 if (NiceFog)
366 glHint(GL_FOG_HINT, GL_NICEST);
367 else
368 glHint(GL_FOG_HINT, GL_DONT_CARE);
369
Brian Paul5b0a7f32000-06-27 16:52:38 +0000370 dojoy();
371
372 glClear(GL_COLOR_BUFFER_BIT);
373
374 if (usetex)
375 glEnable(GL_TEXTURE_2D);
376 else
377 glDisable(GL_TEXTURE_2D);
378
379 if (fog)
380 glEnable(GL_FOG);
381 else
382 glDisable(GL_FOG);
383
384 glShadeModel(GL_SMOOTH);
385
386 glPushMatrix();
387 calcposobs();
388 gluLookAt(obs[0], obs[1], obs[2],
389 obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2],
390 0.0, 0.0, 1.0);
391
392 if (dir[0] > 0) {
393 offset = 8.0;
394 base = obs[0] - fmod(obs[0], 8.0);
395 }
396 else {
397 offset = -8.0;
398 base = obs[0] + (8.0 - fmod(obs[0], 8.0));
399 }
400
401 glPushMatrix();
402 glTranslatef(base - offset / 2.0, 0.0, 0.0);
403 for (i = 0; i < NUMBLOC; i++) {
404 glTranslatef(offset, 0.0, 0.0);
405 glBindTexture(GL_TEXTURE_2D, t1id);
406 drawobjs(striplength_skin_11, stripdata_skin_11);
407 glBindTexture(GL_TEXTURE_2D, t2id);
408 drawobjs(striplength_skin_12, stripdata_skin_12);
409 drawobjs(striplength_skin_9, stripdata_skin_9);
410 drawobjs(striplength_skin_13, stripdata_skin_13);
411 }
412 glPopMatrix();
413 glPopMatrix();
414
Brian Paul5b0a7f32000-06-27 16:52:38 +0000415 glDisable(GL_TEXTURE_2D);
416 glDisable(GL_FOG);
417 glShadeModel(GL_FLAT);
418
419 glMatrixMode(GL_PROJECTION);
420 glPushMatrix();
421 glLoadIdentity();
422 glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0);
423
424 glMatrixMode(GL_MODELVIEW);
425 glLoadIdentity();
426
427 glColor3f(1.0, 0.0, 0.0);
428 glRasterPos2i(10, 10);
429 printstring(GLUT_BITMAP_HELVETICA_18, frbuf);
430 glRasterPos2i(350, 470);
431 printstring(GLUT_BITMAP_HELVETICA_10,
432 "Tunnel V1.5 Written by David Bucciarelli (tech.hmw@plus.it)");
433
434 if (help)
435 printhelp();
436
437 glMatrixMode(GL_PROJECTION);
438 glPopMatrix();
439 glMatrixMode(GL_MODELVIEW);
440
441 glutSwapBuffers();
442
Brian Paul4df1f7c2000-09-12 17:38:22 +0000443 Frames++;
Brian Paul4df1f7c2000-09-12 17:38:22 +0000444 {
445 GLint t = glutGet(GLUT_ELAPSED_TIME);
446 if (t - T0 >= 2000) {
447 GLfloat seconds = (t - T0) / 1000.0;
448 GLfloat fps = Frames / seconds;
449 sprintf(frbuf, "Frame rate: %f", fps);
450 T0 = t;
451 Frames = 0;
452 }
453 }
Brian Paul5b0a7f32000-06-27 16:52:38 +0000454}
455
Brian Paul04484882000-10-23 20:06:36 +0000456static void
457idle(void)
458{
459 glutPostRedisplay();
460}
461
462
463
Brian Paul5b0a7f32000-06-27 16:52:38 +0000464int
465main(int ac, char **av)
466{
467 float fogcolor[4] = { 0.7, 0.7, 0.7, 1.0 };
468
469 fprintf(stderr,
470 "Tunnel V1.5\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
471
472 glutInitWindowPosition(0, 0);
473 glutInitWindowSize(WIDTH, HEIGHT);
474 glutInit(&ac, av);
475
476 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
477
478 if (!(win = glutCreateWindow("Tunnel"))) {
479 fprintf(stderr, "Error, couldn't open window\n");
480 return -1;
481 }
482
483 glMatrixMode(GL_PROJECTION);
484 glLoadIdentity();
485 gluPerspective(80.0, WIDTH / (float) HEIGHT, 1.0, 50.0);
486
487 glMatrixMode(GL_MODELVIEW);
488
489 glShadeModel(GL_SMOOTH);
490 glDisable(GL_DEPTH_TEST);
491 glEnable(GL_CULL_FACE);
492 glEnable(GL_TEXTURE_2D);
493
494 glEnable(GL_FOG);
495 glFogi(GL_FOG_MODE, GL_EXP2);
496 glFogfv(GL_FOG_COLOR, fogcolor);
497
498 glFogf(GL_FOG_DENSITY, 0.06);
499 glHint(GL_FOG_HINT, GL_NICEST);
500
501 inittextures();
502
503 glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]);
504 glClear(GL_COLOR_BUFFER_BIT);
505
506 calcposobs();
507
508 glutReshapeFunc(reshape);
509 glutDisplayFunc(draw);
510 glutKeyboardFunc(key);
511 glutSpecialFunc(special);
Brian Paul04484882000-10-23 20:06:36 +0000512 glutIdleFunc(idle);
Brian Paul5b0a7f32000-06-27 16:52:38 +0000513
514 glEnable(GL_BLEND);
515 /*glBlendFunc(GL_SRC_ALPHA_SATURATE,GL_ONE); */
516 /*glEnable(GL_POLYGON_SMOOTH); */
517
518 glutMainLoop();
519
520 return 0;
521}