home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 2000 April & May / AMIGA_2000_04.iso / patches / mesa3.1 / samples.tk / wave.c < prev   
C/C++ Source or Header  |  1998-10-23  |  15KB  |  644 lines

  1. /*
  2.  * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name of
  8.  * Silicon Graphics may not be used in any advertising or
  9.  * publicity relating to the software without the specific, prior written
  10.  * permission of Silicon Graphics.
  11.  *
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
  13.  * ANY KIND,
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
  18.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <math.h>
  29. #include "gltk.h"
  30.  
  31. #ifndef PI
  32. #define PI 3.14159265358979323846
  33. #endif
  34.  
  35. #define GETCOORD(frame, x, y) (&(theMesh.coords[frame*theMesh.numCoords+(x)+(y)*(theMesh.widthX+1)]))
  36. #define GETFACET(frame, x, y) (&(theMesh.facets[frame*theMesh.numFacets+(x)+(y)*theMesh.widthX]))
  37.  
  38. GLenum rgb, doubleBuffer, directRender;
  39.  
  40. GLint colorIndexes1[3];
  41. GLint colorIndexes2[3];
  42. GLenum clearMask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
  43.  
  44. GLenum smooth = GL_FALSE;
  45. GLenum lighting = GL_TRUE;
  46. GLenum depth = GL_TRUE;
  47. GLenum stepMode = GL_FALSE;
  48. GLenum spinMode = GL_FALSE;
  49. GLint contouring = 0;
  50.  
  51. GLint widthX, widthY;
  52. GLint checkerSize;
  53. float height;
  54.  
  55. GLint frames, curFrame = 0, nextFrame = 0;
  56.  
  57. struct facet {
  58.   float color[3];
  59.   float normal[3];
  60. };
  61. struct coord {
  62.   float vertex[3];
  63.   float normal[3];
  64. };
  65. struct mesh {
  66.   GLint widthX, widthY;
  67.   GLint numFacets;
  68.   GLint numCoords;
  69.   GLint frames;
  70.   struct coord *coords;
  71.   struct facet *facets;
  72. } theMesh;
  73.  
  74. GLubyte contourTexture1[] =
  75. {
  76.   255, 255, 255, 255,
  77.   255, 255, 255, 255,
  78.   255, 255, 255, 255,
  79.   127, 127, 127, 127,
  80. };
  81. GLubyte contourTexture2[] =
  82. {
  83.   255, 255, 255, 255,
  84.   255, 127, 127, 127,
  85.   255, 127, 127, 127,
  86.   255, 127, 127, 127,
  87. };
  88.  
  89. static void Animate(void)
  90. {
  91.   struct coord *coord;
  92.   struct facet *facet;
  93.   float *lastColor;
  94.   float *thisColor;
  95.   GLint i, j;
  96.  
  97.   glClear(clearMask);
  98.  
  99.   if (nextFrame || !stepMode) {
  100.     curFrame++;
  101.   }
  102.   if (curFrame >= theMesh.frames) {
  103.     curFrame = 0;
  104.   }
  105.  
  106.   if ((nextFrame || !stepMode) && spinMode) {
  107.     glRotatef(5.0, 0.0, 0.0, 1.0);
  108.   }
  109.   nextFrame = 0;
  110.  
  111.   for (i = 0; i < theMesh.widthX; i++) {
  112.     glBegin(GL_QUAD_STRIP);
  113.     lastColor = NULL;
  114.     for (j = 0; j < theMesh.widthY; j++) {
  115.       facet = GETFACET(curFrame, i, j);
  116.       if (!smooth && lighting) {
  117.     glNormal3fv(facet->normal);
  118.       }
  119.       if (lighting) {
  120.     if (rgb) {
  121.       thisColor = facet->color;
  122.       glColor3fv(facet->color);
  123.     }
  124.     else {
  125.       thisColor = facet->color;
  126.       glMaterialfv(GL_FRONT_AND_BACK, GL_COLOR_INDEXES,
  127.                facet->color);
  128.     }
  129.       }
  130.       else {
  131.     if (rgb) {
  132.       thisColor = facet->color;
  133.       glColor3fv(facet->color);
  134.     }
  135.     else {
  136.       thisColor = facet->color;
  137.       glIndexf(facet->color[1]);
  138.     }
  139.       }
  140.  
  141.       if (!lastColor || (thisColor[0] != lastColor[0] && smooth)) {
  142.     if (lastColor) {
  143.       glEnd();
  144.       glBegin(GL_QUAD_STRIP);
  145.     }
  146.     coord = GETCOORD(curFrame, i, j);
  147.     if (smooth && lighting) {
  148.       glNormal3fv(coord->normal);
  149.     }
  150.     glVertex3fv(coord->vertex);
  151.  
  152.     coord = GETCOORD(curFrame, i + 1, j);
  153.     if (smooth && lighting) {
  154.       glNormal3fv(coord->normal);
  155.     }
  156.     glVertex3fv(coord->vertex);
  157.       }
  158.  
  159.       coord = GETCOORD(curFrame, i, j + 1);
  160.       if (smooth && lighting) {
  161.     glNormal3fv(coord->normal);
  162.       }
  163.       glVertex3fv(coord->vertex);
  164.  
  165.       coord = GETCOORD(curFrame, i + 1, j + 1);
  166.       if (smooth && lighting) {
  167.     glNormal3fv(coord->normal);
  168.       }
  169.       glVertex3fv(coord->vertex);
  170.  
  171.       lastColor = thisColor;
  172.     }
  173.     glEnd();
  174.   }
  175.  
  176.   glFlush();
  177.   if (doubleBuffer) {
  178.     tkSwapBuffers();
  179.   }
  180. }
  181.  
  182. static void SetColorMap(void)
  183. {
  184.   static float green[3] =
  185.   {0.2, 1.0, 0.2};
  186.   static float red[3] =
  187.   {1.0, 0.2, 0.2};
  188.   float *color, percent;
  189.   GLint *indexes, entries, i, j;
  190.  
  191.   entries = tkGetColorMapSize();
  192.  
  193.   colorIndexes1[0] = 1;
  194.   colorIndexes1[1] = 1 + (GLint) ((entries - 1) * 0.3);
  195.   colorIndexes1[2] = (GLint) ((entries - 1) * 0.5);
  196.   colorIndexes2[0] = 1 + (GLint) ((entries - 1) * 0.5);
  197.   colorIndexes2[1] = 1 + (GLint) ((entries - 1) * 0.8);
  198.   colorIndexes2[2] = entries - 1;
  199.  
  200.   for (i = 0; i < 2; i++) {
  201.     switch (i) {
  202.       case 0:
  203.     color = green;
  204.     indexes = colorIndexes1;
  205.     break;
  206.       case 1:
  207.     color = red;
  208.     indexes = colorIndexes2;
  209.     break;
  210.     }
  211.  
  212.     for (j = indexes[0]; j < indexes[1]; j++) {
  213.       percent = 0.2 + 0.8 * (j - indexes[0]) /
  214.     (float)(indexes[1] - indexes[0]);
  215.       tkSetOneColor(j, percent * color[0], percent * color[1],
  216.             percent * color[2]);
  217.     }
  218.     for (j = indexes[1]; j <= indexes[2]; j++) {
  219.       percent = (j - indexes[1]) / (float)(indexes[2] - indexes[1]);
  220.       tkSetOneColor(j, percent * (1 - color[0]) + color[0],
  221.             percent * (1 - color[1]) + color[1],
  222.             percent * (1 - color[2]) + color[2]);
  223.     }
  224.   }
  225. }
  226.  
  227. static void InitMesh(void)
  228. {
  229.   struct coord *coord;
  230.   struct facet *facet;
  231.   float dp1[3], dp2[3];
  232.   float *pt1, *pt2, *pt3;
  233.   float angle, d, x, y;
  234.   GLint numFacets, numCoords, frameNum, i, j;
  235.  
  236.   theMesh.widthX = widthX;
  237.   theMesh.widthY = widthY;
  238.   theMesh.frames = frames;
  239.  
  240.   numFacets = widthX * widthY;
  241.   numCoords = (widthX + 1) * (widthY + 1);
  242.  
  243.   theMesh.numCoords = numCoords;
  244.   theMesh.numFacets = numFacets;
  245.  
  246.   theMesh.coords = (struct coord *)malloc(frames * numCoords *
  247.                       sizeof(struct coord));
  248.  
  249.   theMesh.facets = (struct facet *)malloc(frames * numFacets *
  250.                       sizeof(struct facet));
  251.  
  252.   if (theMesh.coords == NULL || theMesh.facets == NULL) {
  253.     printf("Out of memory.\n");
  254.     tkQuit();
  255.   }
  256.  
  257.   for (frameNum = 0; frameNum < frames; frameNum++) {
  258.     for (i = 0; i <= widthX; i++) {
  259.       x = i / (float)widthX;
  260.       for (j = 0; j <= widthY; j++) {
  261.     y = j / (float)widthY;
  262.  
  263.     d = sqrt(x * x + y * y);
  264.     if (d == 0.0) {
  265.       d = 0.0001;
  266.     }
  267.     angle = 2 * PI * d + (2 * PI / frames * frameNum);
  268.  
  269.     coord = GETCOORD(frameNum, i, j);
  270.  
  271.     coord->vertex[0] = x - 0.5;
  272.     coord->vertex[1] = y - 0.5;
  273.     coord->vertex[2] = (height - height * d) * cos(angle);
  274.  
  275.     coord->normal[0] = -(height / d) * x * ((1 - d) * 2 * PI *
  276.                         sin(angle) + cos(angle));
  277.     coord->normal[1] = -(height / d) * y * ((1 - d) * 2 * PI *
  278.                         sin(angle) + cos(angle));
  279.     coord->normal[2] = -1;
  280.  
  281.     d = 1.0 / sqrt(coord->normal[0] * coord->normal[0] +
  282.                coord->normal[1] * coord->normal[1] + 1);
  283.     coord->normal[0] *= d;
  284.     coord->normal[1] *= d;
  285.     coord->normal[2] *= d;
  286.       }
  287.     }
  288.     for (i = 0; i < widthX; i++) {
  289.       for (j = 0; j < widthY; j++) {
  290.     facet = GETFACET(frameNum, i, j);
  291.     if (((i / checkerSize) % 2) ^ (j / checkerSize) % 2) {
  292.       if (rgb) {
  293.         facet->color[0] = 1.0;
  294.         facet->color[1] = 0.2;
  295.         facet->color[2] = 0.2;
  296.       }
  297.       else {
  298.         facet->color[0] = colorIndexes1[0];
  299.         facet->color[1] = colorIndexes1[1];
  300.         facet->color[2] = colorIndexes1[2];
  301.       }
  302.     }
  303.     else {
  304.       if (rgb) {
  305.         facet->color[0] = 0.2;
  306.         facet->color[1] = 1.0;
  307.         facet->color[2] = 0.2;
  308.       }
  309.       else {
  310.         facet->color[0] = colorIndexes2[0];
  311.         facet->color[1] = colorIndexes2[1];
  312.         facet->color[2] = colorIndexes2[2];
  313.       }
  314.     }
  315.     pt1 = GETCOORD(frameNum, i, j)->vertex;
  316.     pt2 = GETCOORD(frameNum, i, j + 1)->vertex;
  317.     pt3 = GETCOORD(frameNum, i + 1, j + 1)->vertex;
  318.  
  319.     dp1[0] = pt2[0] - pt1[0];
  320.     dp1[1] = pt2[1] - pt1[1];
  321.     dp1[2] = pt2[2] - pt1[2];
  322.  
  323.     dp2[0] = pt3[0] - pt2[0];
  324.     dp2[1] = pt3[1] - pt2[1];
  325.     dp2[2] = pt3[2] - pt2[2];
  326.  
  327.     facet->normal[0] = dp1[1] * dp2[2] - dp1[2] * dp2[1];
  328.     facet->normal[1] = dp1[2] * dp2[0] - dp1[0] * dp2[2];
  329.     facet->normal[2] = dp1[0] * dp2[1] - dp1[1] * dp2[0];
  330.  
  331.     d = 1.0 / sqrt(facet->normal[0] * facet->normal[0] +
  332.                facet->normal[1] * facet->normal[1] +
  333.                facet->normal[2] * facet->normal[2]);
  334.  
  335.     facet->normal[0] *= d;
  336.     facet->normal[1] *= d;
  337.     facet->normal[2] *= d;
  338.       }
  339.     }
  340.   }
  341. }
  342.  
  343. static void InitMaterials(void)
  344. {
  345.   static float ambient[] =
  346.   {0.1, 0.1, 0.1, 1.0};
  347.   static float diffuse[] =
  348.   {0.5, 1.0, 1.0, 1.0};
  349.   static float position[] =
  350.   {90.0, 90.0, 150.0, 0.0};
  351.   static float front_mat_shininess[] =
  352.   {60.0};
  353.   static float front_mat_specular[] =
  354.   {0.2, 0.2, 0.2, 1.0};
  355.   static float front_mat_diffuse[] =
  356.   {0.5, 0.28, 0.38, 1.0};
  357.   static float back_mat_shininess[] =
  358.   {60.0};
  359.   static float back_mat_specular[] =
  360.   {0.5, 0.5, 0.2, 1.0};
  361.   static float back_mat_diffuse[] =
  362.   {1.0, 1.0, 0.2, 1.0};
  363.   static float lmodel_ambient[] =
  364.   {1.0, 1.0, 1.0, 1.0};
  365.   static float lmodel_twoside[] =
  366.   {GL_TRUE};
  367.  
  368.   glMatrixMode(GL_PROJECTION);
  369.   gluPerspective(90.0, 1.0, 0.5, 10.0);
  370.  
  371.   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  372.   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  373.   glLightfv(GL_LIGHT0, GL_POSITION, position);
  374.   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  375.   glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
  376.   glEnable(GL_LIGHTING);
  377.   glEnable(GL_LIGHT0);
  378.  
  379.   glMaterialfv(GL_FRONT, GL_SHININESS, front_mat_shininess);
  380.   glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular);
  381.   glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
  382.   glMaterialfv(GL_BACK, GL_SHININESS, back_mat_shininess);
  383.   glMaterialfv(GL_BACK, GL_SPECULAR, back_mat_specular);
  384.   glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
  385.   if (rgb) {
  386.     glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
  387.   }
  388.  
  389.   if (rgb) {
  390.     glEnable(GL_COLOR_MATERIAL);
  391.   }
  392.   else {
  393.     SetColorMap();
  394.   }
  395. }
  396.  
  397. static void InitTexture(void)
  398. {
  399.  
  400.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  401.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  402.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  403.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  404.   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  405. }
  406.  
  407. static void Init(void)
  408. {
  409.  
  410.   glClearColor(0.0, 0.0, 0.0, 0.0);
  411.  
  412.   glShadeModel(GL_FLAT);
  413.  
  414.   glFrontFace(GL_CW);
  415.  
  416.   glEnable(GL_DEPTH_TEST);
  417.  
  418.   InitMaterials();
  419.   InitTexture();
  420.   InitMesh();
  421.  
  422.   glMatrixMode(GL_MODELVIEW);
  423.   glTranslatef(0.0, 0.4, -1.8);
  424.   glScalef(2.0, 2.0, 2.0);
  425.   glRotatef(-35.0, 1.0, 0.0, 0.0);
  426.   glRotatef(35.0, 0.0, 0.0, 1.0);
  427. }
  428.  
  429. static void Reshape(int width, int height)
  430. {
  431.  
  432.   glViewport(0, 0, (GLint) width, (GLint) height);
  433. }
  434.  
  435. static GLenum Key(int key, GLenum mask)
  436. {
  437.  
  438.   switch (key) {
  439.     case TK_ESCAPE:
  440.       tkQuit();
  441.     case TK_c:
  442.       contouring++;
  443.       if (contouring == 1) {
  444.     static GLfloat map[4] =
  445.     {0, 0, 20, 0};
  446.  
  447.     glTexImage2D(GL_TEXTURE_2D, 0, 3, 4, 4, 0, GL_LUMINANCE,
  448.              GL_UNSIGNED_BYTE, (GLvoid *) contourTexture1);
  449.     glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  450.     glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  451.     glTexGenfv(GL_S, GL_OBJECT_PLANE, map);
  452.     glTexGenfv(GL_T, GL_OBJECT_PLANE, map);
  453.     glEnable(GL_TEXTURE_2D);
  454.     glEnable(GL_TEXTURE_GEN_S);
  455.     glEnable(GL_TEXTURE_GEN_T);
  456.       }
  457.       else if (contouring == 2) {
  458.     static GLfloat map[4] =
  459.     {0, 0, 20, 0};
  460.  
  461.     glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  462.     glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  463.     glPushMatrix();
  464.     glMatrixMode(GL_MODELVIEW);
  465.     glLoadIdentity();
  466.     glTexGenfv(GL_S, GL_EYE_PLANE, map);
  467.     glTexGenfv(GL_T, GL_EYE_PLANE, map);
  468.     glPopMatrix();
  469.       }
  470.       else {
  471.     contouring = 0;
  472.     glDisable(GL_TEXTURE_GEN_S);
  473.     glDisable(GL_TEXTURE_GEN_T);
  474.     glDisable(GL_TEXTURE_2D);
  475.       }
  476.       break;
  477.     case TK_s:
  478.       smooth = !smooth;
  479.       if (smooth) {
  480.     glShadeModel(GL_SMOOTH);
  481.       }
  482.       else {
  483.     glShadeModel(GL_FLAT);
  484.       }
  485.       break;
  486.     case TK_l:
  487.       lighting = !lighting;
  488.       if (lighting) {
  489.     glEnable(GL_LIGHTING);
  490.     glEnable(GL_LIGHT0);
  491.     if (rgb) {
  492.       glEnable(GL_COLOR_MATERIAL);
  493.     }
  494.       }
  495.       else {
  496.     glDisable(GL_LIGHTING);
  497.     glDisable(GL_LIGHT0);
  498.     if (rgb) {
  499.       glDisable(GL_COLOR_MATERIAL);
  500.     }
  501.       }
  502.       break;
  503.     case TK_d:
  504.       depth = !depth;
  505.       if (depth) {
  506.     glEnable(GL_DEPTH_TEST);
  507.     clearMask |= GL_DEPTH_BUFFER_BIT;
  508.       }
  509.       else {
  510.     glDisable(GL_DEPTH_TEST);
  511.     clearMask &= ~GL_DEPTH_BUFFER_BIT;
  512.       }
  513.       break;
  514.     case TK_SPACE:
  515.       stepMode = !stepMode;
  516.       if (stepMode) {
  517.     tkIdleFunc(0);
  518.     tkDisplayFunc(Animate);
  519.       }
  520.       else {
  521.     tkIdleFunc(Animate);
  522.     tkDisplayFunc(0);
  523.       }
  524.       break;
  525.     case TK_n:
  526.       if (stepMode) {
  527.     nextFrame = 1;
  528.       }
  529.       break;
  530.     case TK_a:
  531.       spinMode = !spinMode;
  532.       break;
  533.     default:
  534.       return GL_FALSE;
  535.   }
  536.   return GL_TRUE;
  537. }
  538.  
  539. static GLenum Args(int argc, char **argv)
  540. {
  541.   GLint i;
  542.  
  543.   rgb = GL_TRUE;
  544.   doubleBuffer = GL_FALSE;
  545.   directRender = GL_TRUE;
  546.   frames = 10;
  547.   widthX = 10;
  548.   widthY = 10;
  549.   checkerSize = 2;
  550.   height = 0.2;
  551.  
  552.   for (i = 1; i < argc; i++) {
  553.     if (strcmp(argv[i], "-ci") == 0) {
  554.       rgb = GL_FALSE;
  555.     }
  556.     else if (strcmp(argv[i], "-rgb") == 0) {
  557.       rgb = GL_TRUE;
  558.     }
  559.     else if (strcmp(argv[i], "-sb") == 0) {
  560.       doubleBuffer = GL_FALSE;
  561.     }
  562.     else if (strcmp(argv[i], "-db") == 0) {
  563.       doubleBuffer = GL_TRUE;
  564.     }
  565.     else if (strcmp(argv[i], "-dr") == 0) {
  566.       directRender = GL_TRUE;
  567.     }
  568.     else if (strcmp(argv[i], "-ir") == 0) {
  569.       directRender = GL_FALSE;
  570.     }
  571.     else if (strcmp(argv[i], "-grid") == 0) {
  572.       if (i + 2 >= argc || argv[i + 1][0] == '-' || argv[i + 2][0] == '-') {
  573.     printf("-grid (No numbers).\n");
  574.     return GL_FALSE;
  575.       }
  576.       else {
  577.     widthX = atoi(argv[++i]);
  578.     widthY = atoi(argv[++i]);
  579.       }
  580.     }
  581.     else if (strcmp(argv[i], "-size") == 0) {
  582.       if (i + 1 >= argc || argv[i + 1][0] == '-') {
  583.     printf("-checker (No number).\n");
  584.     return GL_FALSE;
  585.       }
  586.       else {
  587.     checkerSize = atoi(argv[++i]);
  588.       }
  589.     }
  590.     else if (strcmp(argv[i], "-wave") == 0) {
  591.       if (i + 1 >= argc || argv[i + 1][0] == '-') {
  592.     printf("-wave (No number).\n");
  593.     return GL_FALSE;
  594.       }
  595.       else {
  596.     height = atof(argv[++i]);
  597.       }
  598.     }
  599.     else if (strcmp(argv[i], "-frames") == 0) {
  600.       if (i + 1 >= argc || argv[i + 1][0] == '-') {
  601.     printf("-frames (No number).\n");
  602.     return GL_FALSE;
  603.       }
  604.       else {
  605.     frames = atoi(argv[++i]);
  606.       }
  607.     }
  608.     else {
  609.       printf("%s (Bad option).\n", argv[i]);
  610.       return GL_FALSE;
  611.     }
  612.   }
  613.   return GL_TRUE;
  614. }
  615.  
  616. void main(int argc, char **argv)
  617. {
  618.   GLenum type;
  619.  
  620.   if (Args(argc, argv) == GL_FALSE) {
  621.     tkQuit();
  622.   }
  623.  
  624.   tkInitPosition(0, 0, 300, 300);
  625.  
  626.   type = TK_DEPTH;
  627.   type |= (rgb) ? TK_RGB : TK_INDEX;
  628.   type |= (doubleBuffer) ? TK_DOUBLE : TK_SINGLE;
  629.   type |= (directRender) ? TK_DIRECT : TK_INDIRECT;
  630.   tkInitDisplayMode(type);
  631.  
  632.   if (tkInitWindow("Wave Demo") == GL_FALSE) {
  633.     tkQuit();
  634.   }
  635.  
  636.   Init();
  637.  
  638.   tkExposeFunc(Reshape);
  639.   tkReshapeFunc(Reshape);
  640.   tkKeyDownFunc(Key);
  641.   tkIdleFunc(Animate);
  642.   tkExec();
  643. }
  644.