132001f49Smrg/*
232001f49Smrg * This program is under the GNU GPL.
332001f49Smrg * Use at your own risk.
432001f49Smrg *
532001f49Smrg * You need TWO Voodoo Graphics boards in order to run
632001f49Smrg * this demo !
732001f49Smrg *
832001f49Smrg * written by David Bucciarelli (tech.hmw@plus.it)
932001f49Smrg *            Humanware s.r.l.
1032001f49Smrg */
1132001f49Smrg
1232001f49Smrg#include <stdio.h>
1332001f49Smrg#include <stdlib.h>
1432001f49Smrg#include <math.h>
1532001f49Smrg#include <string.h>
1632001f49Smrg
1732001f49Smrg#ifdef WIN32
1832001f49Smrg#include <windows.h>
1932001f49Smrg#endif
2032001f49Smrg
2132001f49Smrg#include "glut_wrap.h"
2232001f49Smrg#include "readtex.h"
2332001f49Smrg#include "tunneldat.h"
2432001f49Smrg
2532001f49Smrg#ifdef FX
2632001f49Smrg#endif
2732001f49Smrg
2832001f49Smrg#ifdef XMESA
2932001f49Smrg#include "GL/xmesa.h"
3032001f49Smrgstatic int fullscreen = 1;
3132001f49Smrg#endif
3232001f49Smrg
3332001f49Smrg#ifdef FX
3432001f49SmrgGLint fxMesaSelectCurrentBoard(int);
3532001f49Smrg#endif
3632001f49Smrg
3732001f49Smrgstatic int WIDTHC0 = 640;
3832001f49Smrgstatic int HEIGHTC0 = 480;
3932001f49Smrg
4032001f49Smrgstatic int WIDTHC1 = 640;
4132001f49Smrgstatic int HEIGHTC1 = 480;
4232001f49Smrg
4332001f49Smrgstatic GLint T0 = 0;
4432001f49Smrgstatic GLint Frames = 0;
4532001f49Smrg
4632001f49Smrg#define NUMBLOC 5
4732001f49Smrg
4832001f49Smrg#ifndef M_PI
4932001f49Smrg#define M_PI 3.1415926535
5032001f49Smrg#endif
5132001f49Smrg
5232001f49Smrgstatic float obs[3] = { 1000.0, 0.0, 2.0 };
5332001f49Smrgstatic float dir[3];
5432001f49Smrgstatic float v = 30.;
5532001f49Smrgstatic float alpha = 90.0;
5632001f49Smrgstatic float beta = 90.0;
5732001f49Smrg
5832001f49Smrgstatic int fog = 1;
5932001f49Smrgstatic int bfcull = 1;
6032001f49Smrgstatic int usetex = 1;
6132001f49Smrgstatic int cstrip = 0;
6232001f49Smrgstatic int help = 1;
6332001f49Smrgstatic int joyavailable = 0;
6432001f49Smrgstatic int joyactive = 0;
6532001f49Smrg
6632001f49Smrgstatic int channel[2];
6732001f49Smrg
6832001f49Smrgstatic GLuint t1id, t2id;
6932001f49Smrg
7032001f49Smrgstatic void
7132001f49Smrginittextures(void)
7232001f49Smrg{
7332001f49Smrg   glGenTextures(1, &t1id);
7432001f49Smrg   glBindTexture(GL_TEXTURE_2D, t1id);
7532001f49Smrg
7632001f49Smrg   if (!LoadRGBMipmaps(DEMOS_DATA_DIR "tile.rgb", GL_RGB)) {
7732001f49Smrg      fprintf(stderr, "Error reading a texture.\n");
7832001f49Smrg      exit(-1);
7932001f49Smrg   }
8032001f49Smrg
8132001f49Smrg   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
8232001f49Smrg   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
8332001f49Smrg
8432001f49Smrg   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
8532001f49Smrg		   GL_LINEAR_MIPMAP_NEAREST);
8632001f49Smrg   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8732001f49Smrg
8832001f49Smrg   glGenTextures(1, &t2id);
8932001f49Smrg   glBindTexture(GL_TEXTURE_2D, t2id);
9032001f49Smrg
9132001f49Smrg   if (!LoadRGBMipmaps(DEMOS_DATA_DIR "bw.rgb", GL_RGB)) {
9232001f49Smrg      fprintf(stderr, "Error reading a texture.\n");
9332001f49Smrg      exit(-1);
9432001f49Smrg   }
9532001f49Smrg
9632001f49Smrg   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
9732001f49Smrg   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
9832001f49Smrg
9932001f49Smrg   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
10032001f49Smrg		   GL_LINEAR_MIPMAP_LINEAR);
10132001f49Smrg   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
10232001f49Smrg
10332001f49Smrg   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
10432001f49Smrg}
10532001f49Smrg
10632001f49Smrgstatic void
10732001f49Smrgdrawobjs(const int *l, const float *f)
10832001f49Smrg{
10932001f49Smrg   int mend, j;
11032001f49Smrg
11132001f49Smrg   if (cstrip) {
11232001f49Smrg      float r = 0.33, g = 0.33, b = 0.33;
11332001f49Smrg
11432001f49Smrg      for (; (*l) != 0;) {
11532001f49Smrg	 mend = *l++;
11632001f49Smrg
11732001f49Smrg	 r += 0.33;
11832001f49Smrg	 if (r > 1.0) {
11932001f49Smrg	    r = 0.33;
12032001f49Smrg	    g += 0.33;
12132001f49Smrg	    if (g > 1.0) {
12232001f49Smrg	       g = 0.33;
12332001f49Smrg	       b += 0.33;
12432001f49Smrg	       if (b > 1.0)
12532001f49Smrg		  b = 0.33;
12632001f49Smrg	    }
12732001f49Smrg	 }
12832001f49Smrg
12932001f49Smrg	 glColor3f(r, g, b);
13032001f49Smrg	 glBegin(GL_TRIANGLE_STRIP);
13132001f49Smrg	 for (j = 0; j < mend; j++) {
13232001f49Smrg	    f += 4;
13332001f49Smrg	    glTexCoord2fv(f);
13432001f49Smrg	    f += 2;
13532001f49Smrg	    glVertex3fv(f);
13632001f49Smrg	    f += 3;
13732001f49Smrg	 }
13832001f49Smrg	 glEnd();
13932001f49Smrg      }
14032001f49Smrg   }
14132001f49Smrg   else
14232001f49Smrg      for (; (*l) != 0;) {
14332001f49Smrg	 mend = *l++;
14432001f49Smrg
14532001f49Smrg	 glBegin(GL_TRIANGLE_STRIP);
14632001f49Smrg	 for (j = 0; j < mend; j++) {
14732001f49Smrg	    glColor4fv(f);
14832001f49Smrg	    f += 4;
14932001f49Smrg	    glTexCoord2fv(f);
15032001f49Smrg	    f += 2;
15132001f49Smrg	    glVertex3fv(f);
15232001f49Smrg	    f += 3;
15332001f49Smrg	 }
15432001f49Smrg	 glEnd();
15532001f49Smrg      }
15632001f49Smrg}
15732001f49Smrg
15832001f49Smrgstatic void
15932001f49Smrgcalcposobs(void)
16032001f49Smrg{
16132001f49Smrg   static double t0 = -1.;
16232001f49Smrg   double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
16332001f49Smrg   if (t0 < 0.0)
16432001f49Smrg      t0 = t;
16532001f49Smrg   dt = t - t0;
16632001f49Smrg   t0 = t;
16732001f49Smrg
16832001f49Smrg   dir[0] = sin(alpha * M_PI / 180.0);
16932001f49Smrg   dir[1] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0);
17032001f49Smrg   dir[2] = cos(beta * M_PI / 180.0);
17132001f49Smrg
17232001f49Smrg   if (dir[0] < 1.0e-5 && dir[0] > -1.0e-5)
17332001f49Smrg      dir[0] = 0;
17432001f49Smrg   if (dir[1] < 1.0e-5 && dir[1] > -1.0e-5)
17532001f49Smrg      dir[1] = 0;
17632001f49Smrg   if (dir[2] < 1.0e-5 && dir[2] > -1.0e-5)
17732001f49Smrg      dir[2] = 0;
17832001f49Smrg
17932001f49Smrg   obs[0] += v * dir[0] * dt;
18032001f49Smrg   obs[1] += v * dir[1] * dt;
18132001f49Smrg   obs[2] += v * dir[2] * dt;
18232001f49Smrg}
18332001f49Smrg
18432001f49Smrgstatic void
18532001f49Smrgspecial(int k, int x, int y)
18632001f49Smrg{
18732001f49Smrg   switch (k) {
18832001f49Smrg   case GLUT_KEY_LEFT:
18932001f49Smrg      alpha -= 2.0;
19032001f49Smrg      break;
19132001f49Smrg   case GLUT_KEY_RIGHT:
19232001f49Smrg      alpha += 2.0;
19332001f49Smrg      break;
19432001f49Smrg   case GLUT_KEY_DOWN:
19532001f49Smrg      beta -= 2.0;
19632001f49Smrg      break;
19732001f49Smrg   case GLUT_KEY_UP:
19832001f49Smrg      beta += 2.0;
19932001f49Smrg      break;
20032001f49Smrg   }
20132001f49Smrg}
20232001f49Smrg
20332001f49Smrgstatic void
20432001f49Smrgcleanup(void)
20532001f49Smrg{
20632001f49Smrg   glDeleteTextures(1, &t1id);
20732001f49Smrg   glDeleteTextures(1, &t2id);
20832001f49Smrg}
20932001f49Smrg
21032001f49Smrgstatic void
21132001f49Smrgkey(unsigned char k, int x, int y)
21232001f49Smrg{
21332001f49Smrg   switch (k) {
21432001f49Smrg   case 27:
21532001f49Smrg      glutDestroyWindow(channel[0]);
21632001f49Smrg      glutDestroyWindow(channel[1]);
21732001f49Smrg      cleanup();
21832001f49Smrg      exit(0);
21932001f49Smrg      break;
22032001f49Smrg
22132001f49Smrg   case 'a':
22232001f49Smrg      v += 5.;
22332001f49Smrg      break;
22432001f49Smrg   case 'z':
22532001f49Smrg      v -= 5.;
22632001f49Smrg      break;
22732001f49Smrg
22832001f49Smrg#ifdef XMESA
22932001f49Smrg   case ' ':
23032001f49Smrg      fullscreen = (!fullscreen);
23132001f49Smrg
23232001f49Smrg      glutSetWindow(channel[0]);
23332001f49Smrg      XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
23432001f49Smrg
23532001f49Smrg      glutSetWindow(channel[1]);
23632001f49Smrg      XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
23732001f49Smrg      break;
23832001f49Smrg#endif
23932001f49Smrg
24032001f49Smrg   case 'j':
24132001f49Smrg      joyactive = (!joyactive);
24232001f49Smrg      break;
24332001f49Smrg   case 'h':
24432001f49Smrg      help = (!help);
24532001f49Smrg      break;
24632001f49Smrg   case 'f':
24732001f49Smrg      fog = (!fog);
24832001f49Smrg      break;
24932001f49Smrg   case 't':
25032001f49Smrg      usetex = (!usetex);
25132001f49Smrg      break;
25232001f49Smrg   case 'b':
25332001f49Smrg      if (bfcull) {
25432001f49Smrg	 glDisable(GL_CULL_FACE);
25532001f49Smrg	 bfcull = 0;
25632001f49Smrg      }
25732001f49Smrg      else {
25832001f49Smrg	 glEnable(GL_CULL_FACE);
25932001f49Smrg	 bfcull = 1;
26032001f49Smrg      }
26132001f49Smrg      break;
26232001f49Smrg   case 'm':
26332001f49Smrg      cstrip = (!cstrip);
26432001f49Smrg      break;
26532001f49Smrg
26632001f49Smrg   case 'd':
26732001f49Smrg      fprintf(stderr, "Deleting textures...\n");
26832001f49Smrg      glDeleteTextures(1, &t1id);
26932001f49Smrg      glDeleteTextures(1, &t2id);
27032001f49Smrg      fprintf(stderr, "Loading textures...\n");
27132001f49Smrg      inittextures();
27232001f49Smrg      fprintf(stderr, "Done.\n");
27332001f49Smrg      break;
27432001f49Smrg   }
27532001f49Smrg}
27632001f49Smrg
27732001f49Smrgstatic void
27832001f49Smrgreshapechannel0(int w, int h)
27932001f49Smrg{
28032001f49Smrg   float ratio;
28132001f49Smrg
28232001f49Smrg   WIDTHC0 = w;
28332001f49Smrg   HEIGHTC0 = h;
28432001f49Smrg   glMatrixMode(GL_PROJECTION);
28532001f49Smrg   glLoadIdentity();
28632001f49Smrg
28732001f49Smrg   ratio = 0.5f * w / (float) h;
28832001f49Smrg
28932001f49Smrg   glFrustum(-2.0, 0.0, -1.0 * ratio, 1.0 * ratio, 1.0, 60.0);
29032001f49Smrg
29132001f49Smrg   glMatrixMode(GL_MODELVIEW);
29232001f49Smrg   glLoadIdentity();
29332001f49Smrg   glViewport(0, 0, w, h);
29432001f49Smrg}
29532001f49Smrg
29632001f49Smrgstatic void
29732001f49Smrgreshapechannel1(int w, int h)
29832001f49Smrg{
29932001f49Smrg   float ratio;
30032001f49Smrg
30132001f49Smrg   WIDTHC1 = w;
30232001f49Smrg   HEIGHTC1 = h;
30332001f49Smrg   glMatrixMode(GL_PROJECTION);
30432001f49Smrg   glLoadIdentity();
30532001f49Smrg
30632001f49Smrg   ratio = 0.5f * w / (float) h;
30732001f49Smrg
30832001f49Smrg   glFrustum(0.0, 2.0, -1.0 * ratio, 1.0 * ratio, 1.0, 60.0);
30932001f49Smrg
31032001f49Smrg   glMatrixMode(GL_MODELVIEW);
31132001f49Smrg   glLoadIdentity();
31232001f49Smrg   glViewport(0, 0, w, h);
31332001f49Smrg}
31432001f49Smrg
31532001f49Smrgstatic void
31632001f49Smrgprintstring(void *font, char *string)
31732001f49Smrg{
31832001f49Smrg   int len, i;
31932001f49Smrg
32032001f49Smrg   len = (int) strlen(string);
32132001f49Smrg   for (i = 0; i < len; i++)
32232001f49Smrg      glutBitmapCharacter(font, string[i]);
32332001f49Smrg}
32432001f49Smrg
32532001f49Smrgstatic void
32632001f49Smrgprinthelp(void)
32732001f49Smrg{
32832001f49Smrg   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
32932001f49Smrg   glColor4f(0.0, 0.0, 0.0, 0.5);
33032001f49Smrg   glRecti(40, 40, 600, 440);
33132001f49Smrg
33232001f49Smrg   glColor3f(1.0, 0.0, 0.0);
33332001f49Smrg   glRasterPos2i(300, 420);
33432001f49Smrg   printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help");
33532001f49Smrg
33632001f49Smrg   glRasterPos2i(60, 390);
33732001f49Smrg   printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Toggle Help");
33832001f49Smrg   glRasterPos2i(60, 360);
33932001f49Smrg   printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Toggle Textures");
34032001f49Smrg   glRasterPos2i(60, 330);
34132001f49Smrg   printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Toggle Fog");
34232001f49Smrg   glRasterPos2i(60, 300);
34332001f49Smrg   printstring(GLUT_BITMAP_TIMES_ROMAN_24, "m - Toggle strips");
34432001f49Smrg   glRasterPos2i(60, 270);
34532001f49Smrg   printstring(GLUT_BITMAP_TIMES_ROMAN_24, "b - Toggle Back face culling");
34632001f49Smrg   glRasterPos2i(60, 240);
34732001f49Smrg   printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate");
34832001f49Smrg   glRasterPos2i(60, 210);
34932001f49Smrg   printstring(GLUT_BITMAP_TIMES_ROMAN_24, "a - Increase velocity");
35032001f49Smrg   glRasterPos2i(60, 180);
35132001f49Smrg   printstring(GLUT_BITMAP_TIMES_ROMAN_24, "z - Decrease velocity");
35232001f49Smrg
35332001f49Smrg   glRasterPos2i(60, 150);
35432001f49Smrg   if (joyavailable)
35532001f49Smrg      printstring(GLUT_BITMAP_TIMES_ROMAN_24,
35632001f49Smrg		  "j - Toggle jostick control (Joystick control available)");
35732001f49Smrg   else
35832001f49Smrg      printstring(GLUT_BITMAP_TIMES_ROMAN_24,
35932001f49Smrg		  "(No Joystick control available)");
36032001f49Smrg}
36132001f49Smrg
36232001f49Smrgstatic void
36332001f49Smrgdojoy(void)
36432001f49Smrg{
36532001f49Smrg#ifdef WIN32
36632001f49Smrg   static UINT max[2] = { 0, 0 };
36732001f49Smrg   static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2];
36832001f49Smrg   MMRESULT res;
36932001f49Smrg   JOYINFO joy;
37032001f49Smrg
37132001f49Smrg   res = joyGetPos(JOYSTICKID1, &joy);
37232001f49Smrg
37332001f49Smrg   if (res == JOYERR_NOERROR) {
37432001f49Smrg      joyavailable = 1;
37532001f49Smrg
37632001f49Smrg      if (max[0] < joy.wXpos)
37732001f49Smrg	 max[0] = joy.wXpos;
37832001f49Smrg      if (min[0] > joy.wXpos)
37932001f49Smrg	 min[0] = joy.wXpos;
38032001f49Smrg      center[0] = (max[0] + min[0]) / 2;
38132001f49Smrg
38232001f49Smrg      if (max[1] < joy.wYpos)
38332001f49Smrg	 max[1] = joy.wYpos;
38432001f49Smrg      if (min[1] > joy.wYpos)
38532001f49Smrg	 min[1] = joy.wYpos;
38632001f49Smrg      center[1] = (max[1] + min[1]) / 2;
38732001f49Smrg
38832001f49Smrg      if (joyactive) {
38932001f49Smrg	 if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0]))
39032001f49Smrg	    alpha -=
39132001f49Smrg	       2.0 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]);
39232001f49Smrg	 if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1]))
39332001f49Smrg	    beta += 2.0 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]);
39432001f49Smrg
39532001f49Smrg	 if (joy.wButtons & JOY_BUTTON1)
39632001f49Smrg	    v += 0.01;
39732001f49Smrg	 if (joy.wButtons & JOY_BUTTON2)
39832001f49Smrg	    v -= 0.01;
39932001f49Smrg      }
40032001f49Smrg   }
40132001f49Smrg   else
40232001f49Smrg      joyavailable = 0;
40332001f49Smrg#endif
40432001f49Smrg}
40532001f49Smrg
40632001f49Smrgstatic void
40732001f49Smrgdraw(void)
40832001f49Smrg{
40932001f49Smrg   static char frbuf[80] = "";
41032001f49Smrg   int i;
41132001f49Smrg   float base, offset;
41232001f49Smrg
41332001f49Smrg   dojoy();
41432001f49Smrg
41532001f49Smrg   glClear(GL_COLOR_BUFFER_BIT);
41632001f49Smrg
41732001f49Smrg   glClear(GL_COLOR_BUFFER_BIT);
41832001f49Smrg
41932001f49Smrg   if (usetex)
42032001f49Smrg      glEnable(GL_TEXTURE_2D);
42132001f49Smrg   else
42232001f49Smrg      glDisable(GL_TEXTURE_2D);
42332001f49Smrg
42432001f49Smrg   if (fog)
42532001f49Smrg      glEnable(GL_FOG);
42632001f49Smrg   else
42732001f49Smrg      glDisable(GL_FOG);
42832001f49Smrg
42932001f49Smrg   glShadeModel(GL_SMOOTH);
43032001f49Smrg
43132001f49Smrg   glPushMatrix();
43232001f49Smrg   calcposobs();
43332001f49Smrg   gluLookAt(obs[0], obs[1], obs[2],
43432001f49Smrg	     obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2],
43532001f49Smrg	     0.0, 0.0, 1.0);
43632001f49Smrg
43732001f49Smrg   if (dir[0] > 0) {
43832001f49Smrg      offset = 8.0;
43932001f49Smrg      base = obs[0] - fmod(obs[0], 8.0);
44032001f49Smrg   }
44132001f49Smrg   else {
44232001f49Smrg      offset = -8.0;
44332001f49Smrg      base = obs[0] + (8.0 - fmod(obs[0], 8.0));
44432001f49Smrg   }
44532001f49Smrg
44632001f49Smrg   glPushMatrix();
44732001f49Smrg   glTranslatef(base - offset / 2.0, 0.0, 0.0);
44832001f49Smrg   for (i = 0; i < NUMBLOC; i++) {
44932001f49Smrg      glTranslatef(offset, 0.0, 0.0);
45032001f49Smrg      glBindTexture(GL_TEXTURE_2D, t1id);
45132001f49Smrg      drawobjs(striplength_skin_11, stripdata_skin_11);
45232001f49Smrg      glBindTexture(GL_TEXTURE_2D, t2id);
45332001f49Smrg      drawobjs(striplength_skin_12, stripdata_skin_12);
45432001f49Smrg      drawobjs(striplength_skin_9, stripdata_skin_9);
45532001f49Smrg      drawobjs(striplength_skin_13, stripdata_skin_13);
45632001f49Smrg   }
45732001f49Smrg   glPopMatrix();
45832001f49Smrg   glPopMatrix();
45932001f49Smrg
46032001f49Smrg   glDisable(GL_TEXTURE_2D);
46132001f49Smrg   glDisable(GL_FOG);
46232001f49Smrg   glShadeModel(GL_FLAT);
46332001f49Smrg
46432001f49Smrg   glMatrixMode(GL_PROJECTION);
46532001f49Smrg   glPushMatrix();
46632001f49Smrg   glLoadIdentity();
46732001f49Smrg   glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0);
46832001f49Smrg
46932001f49Smrg   glMatrixMode(GL_MODELVIEW);
47032001f49Smrg   glLoadIdentity();
47132001f49Smrg
47232001f49Smrg   glColor3f(1.0, 0.0, 0.0);
47332001f49Smrg   glRasterPos2i(10, 10);
47432001f49Smrg   printstring(GLUT_BITMAP_HELVETICA_18, frbuf);
47532001f49Smrg   glRasterPos2i(350, 470);
47632001f49Smrg   printstring(GLUT_BITMAP_HELVETICA_10,
47732001f49Smrg	       "Tunnel2 V1.0 Written by David Bucciarelli (tech.hmw@plus.it)");
47832001f49Smrg
47932001f49Smrg   if (help)
48032001f49Smrg      printhelp();
48132001f49Smrg
48232001f49Smrg   glMatrixMode(GL_PROJECTION);
48332001f49Smrg   glPopMatrix();
48432001f49Smrg   glMatrixMode(GL_MODELVIEW);
48532001f49Smrg
48632001f49Smrg   Frames++;
48732001f49Smrg   {
48832001f49Smrg      GLint t = glutGet(GLUT_ELAPSED_TIME);
48932001f49Smrg      if (t - T0 >= 2000) {
49032001f49Smrg         GLfloat seconds = (t - T0) / 1000.0;
49132001f49Smrg         GLfloat fps = Frames / seconds;
49232001f49Smrg         sprintf(frbuf, "Frame rate: %f", fps);
49332001f49Smrg         printf("%s\n", frbuf);
4947ec3b29aSmrg         fflush(stdout);
49532001f49Smrg         T0 = t;
49632001f49Smrg         Frames = 0;
49732001f49Smrg      }
49832001f49Smrg   }
49932001f49Smrg}
50032001f49Smrg
50132001f49Smrgstatic void
50232001f49Smrgdrawchannel0(void)
50332001f49Smrg{
50432001f49Smrg   glutSetWindow(channel[0]);
50532001f49Smrg   draw();
50632001f49Smrg   glutSwapBuffers();
50732001f49Smrg}
50832001f49Smrg
50932001f49Smrgstatic void
51032001f49Smrgdrawchannel1(void)
51132001f49Smrg{
51232001f49Smrg   glutSetWindow(channel[1]);
51332001f49Smrg   draw();
51432001f49Smrg   glutSwapBuffers();
51532001f49Smrg}
51632001f49Smrg
51732001f49Smrgstatic void
51832001f49Smrgdrawall(void)
51932001f49Smrg{
52032001f49Smrg   glutSetWindow(channel[0]);
52132001f49Smrg   draw();
52232001f49Smrg   glutSetWindow(channel[1]);
52332001f49Smrg   draw();
52432001f49Smrg
52532001f49Smrg   glutSetWindow(channel[0]);
52632001f49Smrg   glutSwapBuffers();
52732001f49Smrg   glutSetWindow(channel[1]);
52832001f49Smrg   glutSwapBuffers();
52932001f49Smrg}
53032001f49Smrg
53132001f49Smrgstatic void
53232001f49Smrginit(void)
53332001f49Smrg{
53432001f49Smrg   float fogcolor[4] = { 0.7, 0.7, 0.7, 1.0 };
53532001f49Smrg
53632001f49Smrg   glShadeModel(GL_SMOOTH);
53732001f49Smrg   glDisable(GL_DEPTH_TEST);
53832001f49Smrg   glEnable(GL_CULL_FACE);
53932001f49Smrg   glEnable(GL_TEXTURE_2D);
54032001f49Smrg
54132001f49Smrg   glEnable(GL_FOG);
54232001f49Smrg   glFogi(GL_FOG_MODE, GL_EXP2);
54332001f49Smrg   glFogfv(GL_FOG_COLOR, fogcolor);
54432001f49Smrg
54532001f49Smrg   glFogf(GL_FOG_DENSITY, 0.06);
54632001f49Smrg   glHint(GL_FOG_HINT, GL_NICEST);
54732001f49Smrg
54832001f49Smrg   glEnable(GL_BLEND);
54932001f49Smrg   /*
55032001f49Smrg   glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE);
55132001f49Smrg   glEnable(GL_POLYGON_SMOOTH);
55232001f49Smrg   */
55332001f49Smrg
55432001f49Smrg   glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]);
55532001f49Smrg   glClear(GL_COLOR_BUFFER_BIT);
55632001f49Smrg}
55732001f49Smrg
55832001f49Smrgint
55932001f49Smrgmain(int ac, char **av)
56032001f49Smrg{
56132001f49Smrg   fprintf(stderr,
56232001f49Smrg	   "Tunnel2 V1.0\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
56332001f49Smrg
56432001f49Smrg   glutInitWindowSize(WIDTHC0, HEIGHTC0);
56532001f49Smrg   glutInit(&ac, av);
56632001f49Smrg
56732001f49Smrg   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
56832001f49Smrg
56932001f49Smrg#ifdef FX
57032001f49Smrg   if (fxMesaSelectCurrentBoard(0) < 0) {
57132001f49Smrg      fprintf(stderr, "The first Voodoo Graphics board is missing !?!?\n");
57232001f49Smrg      return -1;
57332001f49Smrg   }
57432001f49Smrg#endif
57532001f49Smrg   if (!(channel[0] = glutCreateWindow("Channel 0"))) {
57632001f49Smrg      fprintf(stderr, "Error, couldn't open window\n");
57732001f49Smrg      return -1;
57832001f49Smrg   }
57932001f49Smrg
58032001f49Smrg   reshapechannel0(WIDTHC0, HEIGHTC0);
58132001f49Smrg   init();
58232001f49Smrg   inittextures();
58332001f49Smrg   glutDisplayFunc(drawchannel0);
58432001f49Smrg   glutReshapeFunc(reshapechannel0);
58532001f49Smrg   glutKeyboardFunc(key);
58632001f49Smrg   glutSpecialFunc(special);
58732001f49Smrg
58832001f49Smrg#ifdef FX
58932001f49Smrg   if (fxMesaSelectCurrentBoard(1) < 0) {
59032001f49Smrg      fprintf(stderr, "The second Voodoo Graphics board is missing !\n");
59132001f49Smrg      exit(-1);
59232001f49Smrg   }
59332001f49Smrg#endif
59432001f49Smrg   glutInitWindowPosition(WIDTHC0, 0);
59532001f49Smrg   glutInitWindowSize(WIDTHC1, HEIGHTC1);
59632001f49Smrg   if (!(channel[1] = glutCreateWindow("Channel 1"))) {
59732001f49Smrg      fprintf(stderr, "Error, couldn't open window\n");
59832001f49Smrg      exit(-1);
59932001f49Smrg   }
60032001f49Smrg
60132001f49Smrg   reshapechannel1(WIDTHC1, HEIGHTC1);
60232001f49Smrg   init();
60332001f49Smrg   inittextures();
60432001f49Smrg   glutDisplayFunc(drawchannel1);
60532001f49Smrg   glutReshapeFunc(reshapechannel1);
60632001f49Smrg   glutKeyboardFunc(key);
60732001f49Smrg   glutSpecialFunc(special);
60832001f49Smrg
60932001f49Smrg   glutIdleFunc(drawall);
61032001f49Smrg
61132001f49Smrg   calcposobs();
61232001f49Smrg
61332001f49Smrg   glutMainLoop();
61432001f49Smrg   cleanup();
61532001f49Smrg
61632001f49Smrg   return 0;
61732001f49Smrg}
618