home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 2000 April & May / AMIGA_2000_04.iso / patches / mesa3.1 / samples.tk / sphere.c < prev    next >
C/C++ Source or Header  |  1998-10-23  |  19KB  |  1,060 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. /*
  26.  * BEP: renamed "nearest" as "nnearest" to avoid math.h collision on AIX 
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <math.h>
  32. #include <stdlib.h>
  33. #include "gltk.h"
  34.  
  35. #define FALSE 0
  36. #define TRUE  1
  37. #ifndef PI
  38. #define PI    3.14159265358979323846
  39. #endif
  40.  
  41. GLenum doubleBuffer, directRender;
  42. int W = 400, H = 400;
  43.  
  44. char *imageFileName = 0;
  45. TK_RGBImageRec *image;
  46.  
  47. int numComponents;
  48.  
  49. float *minFilter, *magFilter, *sWrapMode, *tWrapMode;
  50. float decal[] =
  51. {GL_DECAL};
  52. float modulate[] =
  53. {GL_MODULATE};
  54. float repeat[] =
  55. {GL_REPEAT};
  56. float clamp[] =
  57. {GL_CLAMP};
  58. float nnearest[] =
  59. {GL_NEAREST};
  60. float linear[] =
  61. {GL_LINEAR};
  62. float nearest_mipmap_nearest[] =
  63. {GL_NEAREST_MIPMAP_NEAREST};
  64. float nearest_mipmap_linear[] =
  65. {GL_NEAREST_MIPMAP_LINEAR};
  66. float linear_mipmap_nearest[] =
  67. {GL_LINEAR_MIPMAP_NEAREST};
  68. float linear_mipmap_linear[] =
  69. {GL_LINEAR_MIPMAP_LINEAR};
  70. GLint sphereMap[] =
  71. {GL_SPHERE_MAP};
  72.  
  73. float xRotation = 0.0, yRotation = 0.0;
  74. float zTranslate = -4.0;
  75. GLenum autoRotate = TRUE;
  76. GLenum deepestColor = TK_GREEN;
  77. GLenum isLit = TRUE;
  78. GLenum isFogged = FALSE;
  79. float *textureEnvironment = modulate;
  80.  
  81. struct MipMap {
  82.   int width, height;
  83.   unsigned char *data;
  84. };
  85.  
  86. int cube, cage, cylinder, torus, genericObject;
  87.  
  88. float c[6][4][4][3] =
  89. {
  90.   {
  91.     {
  92.       {
  93.     1.0, 1.0, -1.0
  94.       },
  95.       {
  96.     0.0, 1.0, -1.0
  97.       },
  98.       {
  99.     0.0, 0.0, -1.0
  100.       },
  101.       {
  102.     1.0, 0.0, -1.0
  103.       },
  104.     },
  105.     {
  106.       {
  107.     0.0, 1.0, -1.0
  108.       },
  109.       {
  110.     -1.0, 1.0, -1.0
  111.       },
  112.       {
  113.     -1.0, 0.0, -1.0
  114.       },
  115.       {
  116.     0.0, 0.0, -1.0
  117.       },
  118.     },
  119.     {
  120.       {
  121.     0.0, 0.0, -1.0
  122.       },
  123.       {
  124.     -1.0, 0.0, -1.0
  125.       },
  126.       {
  127.     -1.0, -1.0, -1.0
  128.       },
  129.       {
  130.     0.0, -1.0, -1.0
  131.       },
  132.     },
  133.     {
  134.       {
  135.     1.0, 0.0, -1.0
  136.       },
  137.       {
  138.     0.0, 0.0, -1.0
  139.       },
  140.       {
  141.     0.0, -1.0, -1.0
  142.       },
  143.       {
  144.     1.0, -1.0, -1.0
  145.       },
  146.     },
  147.   },
  148.   {
  149.     {
  150.       {
  151.     1.0, 1.0, 1.0
  152.       },
  153.       {
  154.     1.0, 1.0, 0.0
  155.       },
  156.       {
  157.     1.0, 0.0, 0.0
  158.       },
  159.       {
  160.     1.0, 0.0, 1.0
  161.       },
  162.     },
  163.     {
  164.       {
  165.     1.0, 1.0, 0.0
  166.       },
  167.       {
  168.     1.0, 1.0, -1.0
  169.       },
  170.       {
  171.     1.0, 0.0, -1.0
  172.       },
  173.       {
  174.     1.0, 0.0, 0.0
  175.       },
  176.     },
  177.     {
  178.       {
  179.     1.0, 0.0, -1.0
  180.       },
  181.       {
  182.     1.0, -1.0, -1.0
  183.       },
  184.       {
  185.     1.0, -1.0, 0.0
  186.       },
  187.       {
  188.     1.0, 0.0, 0.0
  189.       },
  190.     },
  191.     {
  192.       {
  193.     1.0, 0.0, 0.0
  194.       },
  195.       {
  196.     1.0, -1.0, 0.0
  197.       },
  198.       {
  199.     1.0, -1.0, 1.0
  200.       },
  201.       {
  202.     1.0, 0.0, 1.0
  203.       },
  204.     },
  205.   },
  206.   {
  207.     {
  208.       {
  209.     -1.0, 1.0, 1.0
  210.       },
  211.       {
  212.     0.0, 1.0, 1.0
  213.       },
  214.       {
  215.     0.0, 0.0, 1.0
  216.       },
  217.       {
  218.     -1.0, 0.0, 1.0
  219.       },
  220.     },
  221.     {
  222.       {
  223.     0.0, 1.0, 1.0
  224.       },
  225.       {
  226.     1.0, 1.0, 1.0
  227.       },
  228.       {
  229.     1.0, 0.0, 1.0
  230.       },
  231.       {
  232.     0.0, 0.0, 1.0
  233.       },
  234.     },
  235.     {
  236.       {
  237.     1.0, 0.0, 1.0
  238.       },
  239.       {
  240.     1.0, -1.0, 1.0
  241.       },
  242.       {
  243.     0.0, -1.0, 1.0
  244.       },
  245.       {
  246.     0.0, 0.0, 1.0
  247.       },
  248.     },
  249.     {
  250.       {
  251.     0.0, -1.0, 1.0
  252.       },
  253.       {
  254.     -1.0, -1.0, 1.0
  255.       },
  256.       {
  257.     -1.0, 0.0, 1.0
  258.       },
  259.       {
  260.     0.0, 0.0, 1.0
  261.       },
  262.     },
  263.   },
  264.   {
  265.     {
  266.       {
  267.     -1.0, 1.0, -1.0
  268.       },
  269.       {
  270.     -1.0, 1.0, 0.0
  271.       },
  272.       {
  273.     -1.0, 0.0, 0.0
  274.       },
  275.       {
  276.     -1.0, 0.0, -1.0
  277.       },
  278.     },
  279.     {
  280.       {
  281.     -1.0, 1.0, 0.0
  282.       },
  283.       {
  284.     -1.0, 1.0, 1.0
  285.       },
  286.       {
  287.     -1.0, 0.0, 1.0
  288.       },
  289.       {
  290.     -1.0, 0.0, 0.0
  291.       },
  292.     },
  293.     {
  294.       {
  295.     -1.0, 0.0, 1.0
  296.       },
  297.       {
  298.     -1.0, -1.0, 1.0
  299.       },
  300.       {
  301.     -1.0, -1.0, 0.0
  302.       },
  303.       {
  304.     -1.0, 0.0, 0.0
  305.       },
  306.     },
  307.     {
  308.       {
  309.     -1.0, -1.0, 0.0
  310.       },
  311.       {
  312.     -1.0, -1.0, -1.0
  313.       },
  314.       {
  315.     -1.0, 0.0, -1.0
  316.       },
  317.       {
  318.     -1.0, 0.0, 0.0
  319.       },
  320.     },
  321.   },
  322.   {
  323.     {
  324.       {
  325.     -1.0, 1.0, 1.0
  326.       },
  327.       {
  328.     -1.0, 1.0, 0.0
  329.       },
  330.       {
  331.     0.0, 1.0, 0.0
  332.       },
  333.       {
  334.     0.0, 1.0, 1.0
  335.       },
  336.     },
  337.     {
  338.       {
  339.     -1.0, 1.0, 0.0
  340.       },
  341.       {
  342.     -1.0, 1.0, -1.0
  343.       },
  344.       {
  345.     0.0, 1.0, -1.0
  346.       },
  347.       {
  348.     0.0, 1.0, 0.0
  349.       },
  350.     },
  351.     {
  352.       {
  353.     0.0, 1.0, -1.0
  354.       },
  355.       {
  356.     1.0, 1.0, -1.0
  357.       },
  358.       {
  359.     1.0, 1.0, 0.0
  360.       },
  361.       {
  362.     0.0, 1.0, 0.0
  363.       },
  364.     },
  365.     {
  366.       {
  367.     1.0, 1.0, 0.0
  368.       },
  369.       {
  370.     1.0, 1.0, 1.0
  371.       },
  372.       {
  373.     0.0, 1.0, 1.0
  374.       },
  375.       {
  376.     0.0, 1.0, 0.0
  377.       },
  378.     },
  379.   },
  380.   {
  381.     {
  382.       {
  383.     -1.0, -1.0, -1.0
  384.       },
  385.       {
  386.     -1.0, -1.0, 0.0
  387.       },
  388.       {
  389.     0.0, -1.0, 0.0
  390.       },
  391.       {
  392.     0.0, -1.0, -1.0
  393.       },
  394.     },
  395.     {
  396.       {
  397.     -1.0, -1.0, 0.0
  398.       },
  399.       {
  400.     -1.0, -1.0, 1.0
  401.       },
  402.       {
  403.     0.0, -1.0, 1.0
  404.       },
  405.       {
  406.     0.0, -1.0, 0.0
  407.       },
  408.     },
  409.     {
  410.       {
  411.     0.0, -1.0, 1.0
  412.       },
  413.       {
  414.     1.0, -1.0, 1.0
  415.       },
  416.       {
  417.     1.0, -1.0, 0.0
  418.       },
  419.       {
  420.     0.0, -1.0, 0.0
  421.       },
  422.     },
  423.     {
  424.       {
  425.     1.0, -1.0, 0.0
  426.       },
  427.       {
  428.     1.0, -1.0, -1.0
  429.       },
  430.       {
  431.     0.0, -1.0, -1.0
  432.       },
  433.       {
  434.     0.0, -1.0, 0.0
  435.       },
  436.     },
  437.   }
  438. };
  439.  
  440. float n[6][3] =
  441. {
  442.   {
  443.     0.0, 0.0, -1.0
  444.   },
  445.   {
  446.     1.0, 0.0, 0.0
  447.   },
  448.   {
  449.     0.0, 0.0, 1.0
  450.   },
  451.   {
  452.     -1.0, 0.0, 0.0
  453.   },
  454.   {
  455.     0.0, 1.0, 0.0
  456.   },
  457.   {
  458.     0.0, -1.0, 0.0
  459.   }
  460. };
  461.  
  462. GLfloat identity[16] =
  463. {
  464.   1, 0, 0, 0,
  465.   0, 1, 0, 0,
  466.   0, 0, 1, 0,
  467.   0, 0, 0, 1,
  468. };
  469.  
  470. void BuildCylinder(int numEdges)
  471. {
  472.   int i, top = 1.0, bottom = -1.0;
  473.   float x[100], y[100], angle;
  474.  
  475.   for (i = 0; i <= numEdges; i++) {
  476.     angle = i * 2.0 * PI / numEdges;
  477.     x[i] = cos(angle);                                   /*
  478.                                             * was cosf() 
  479.                                             */
  480.     y[i] = sin(angle);                                   /*
  481.                                             * was sinf() 
  482.                                             */
  483.   }
  484.  
  485.   glNewList(cylinder, GL_COMPILE);
  486.   glBegin(GL_TRIANGLE_STRIP);
  487.   for (i = 0; i <= numEdges; i++) {
  488.     glNormal3f(x[i], y[i], 0.0);
  489.     glVertex3f(x[i], y[i], bottom);
  490.     glVertex3f(x[i], y[i], top);
  491.   }
  492.   glEnd();
  493.   glBegin(GL_TRIANGLE_FAN);
  494.   glNormal3f(0.0, 0.0, 1.0);
  495.   glVertex3f(0.0, 0.0, top);
  496.   for (i = 0; i <= numEdges; i++) {
  497.     glVertex3f(x[i], -y[i], top);
  498.   }
  499.   glEnd();
  500.   glBegin(GL_TRIANGLE_FAN);
  501.   glNormal3f(0.0, 0.0, -1.0);
  502.   glVertex3f(0.0, 0.0, bottom);
  503.   for (i = 0; i <= numEdges; i++) {
  504.     glVertex3f(x[i], y[i], bottom);
  505.   }
  506.   glEnd();
  507.   glEndList();
  508. }
  509.  
  510. void BuildTorus(float rc, int numc, float rt, int numt)
  511. {
  512.   int i, j, k;
  513.   double s, t;
  514.   double x, y, z;
  515.   double pi, twopi;
  516.  
  517.   pi = 3.14159265358979323846;
  518.   twopi = 2.0 * pi;
  519.  
  520.   glNewList(torus, GL_COMPILE);
  521.   for (i = 0; i < numc; i++) {
  522.     glBegin(GL_QUAD_STRIP);
  523.     for (j = 0; j <= numt; j++) {
  524.       for (k = 0; k <= 1; k++) {
  525.     s = (i + k) % numc + 0.5;
  526.     t = j % numt;
  527.  
  528.     x = cos(t * twopi / numt) * cos(s * twopi / numc);
  529.     y = sin(t * twopi / numt) * cos(s * twopi / numc);
  530.     z = sin(s * twopi / numc);
  531.     glNormal3f(x, y, z);
  532.  
  533.     x = (rt + rc * cos(s * twopi / numc)) * cos(t * twopi / numt);
  534.     y = (rt + rc * cos(s * twopi / numc)) * sin(t * twopi / numt);
  535.     z = rc * sin(s * twopi / numc);
  536.     glVertex3f(x, y, z);
  537.       }
  538.     }
  539.     glEnd();
  540.   }
  541.   glEndList();
  542. }
  543.  
  544. void BuildCage(void)
  545. {
  546.   int i;
  547.   float inc;
  548.   float right, left, top, bottom, front, back;
  549.  
  550.   front = 0.0;
  551.   back = -8.0;
  552.  
  553.   left = -4.0;
  554.   bottom = -4.0;
  555.   right = 4.0;
  556.   top = 4.0;
  557.  
  558.   inc = 2.0 * 4.0 * 0.1;
  559.  
  560.   glNewList(cage, GL_COMPILE);
  561.   for (i = 0; i < 10; i++) {
  562.  
  563.     /*
  564.      * ** Back
  565.      */
  566.     glBegin(GL_LINES);
  567.     glVertex3f(left + i * inc, top, back);
  568.     glVertex3f(left + i * inc, bottom, back);
  569.     glEnd();
  570.     glBegin(GL_LINES);
  571.     glVertex3f(right, bottom + i * inc, back);
  572.     glVertex3f(left, bottom + i * inc, back);
  573.     glEnd();
  574.  
  575.     /*
  576.      * ** Front
  577.      */
  578.     glBegin(GL_LINES);
  579.     glVertex3f(left + i * inc, top, front);
  580.     glVertex3f(left + i * inc, bottom, front);
  581.     glEnd();
  582.     glBegin(GL_LINES);
  583.     glVertex3f(right, bottom + i * inc, front);
  584.     glVertex3f(left, bottom + i * inc, front);
  585.     glEnd();
  586.  
  587.     /*
  588.      * ** Left
  589.      */
  590.     glBegin(GL_LINES);
  591.     glVertex3f(left, bottom + i * inc, front);
  592.     glVertex3f(left, bottom + i * inc, back);
  593.     glEnd();
  594.     glBegin(GL_LINES);
  595.     glVertex3f(left, top, back + i * inc);
  596.     glVertex3f(left, bottom, back + i * inc);
  597.     glEnd();
  598.  
  599.     /*
  600.      * ** Right
  601.      */
  602.     glBegin(GL_LINES);
  603.     glVertex3f(right, top - i * inc, front);
  604.     glVertex3f(right, top - i * inc, back);
  605.     glEnd();
  606.     glBegin(GL_LINES);
  607.     glVertex3f(right, top, back + i * inc);
  608.     glVertex3f(right, bottom, back + i * inc);
  609.     glEnd();
  610.  
  611.     /*
  612.      * ** Top
  613.      */
  614.     glBegin(GL_LINES);
  615.     glVertex3f(left + i * inc, top, front);
  616.     glVertex3f(left + i * inc, top, back);
  617.     glEnd();
  618.     glBegin(GL_LINES);
  619.     glVertex3f(right, top, back + i * inc);
  620.     glVertex3f(left, top, back + i * inc);
  621.     glEnd();
  622.  
  623.     /*
  624.      * ** Bottom
  625.      */
  626.     glBegin(GL_LINES);
  627.     glVertex3f(right - i * inc, bottom, front);
  628.     glVertex3f(right - i * inc, bottom, back);
  629.     glEnd();
  630.     glBegin(GL_LINES);
  631.     glVertex3f(right, bottom, back + i * inc);
  632.     glVertex3f(left, bottom, back + i * inc);
  633.     glEnd();
  634.   }
  635.   glEndList();
  636. }
  637.  
  638. void BuildCube(void)
  639. {
  640.   int i, j;
  641.  
  642.   glNewList(cube, GL_COMPILE);
  643.   for (i = 0; i < 6; i++) {
  644.     for (j = 0; j < 4; j++) {
  645.       glNormal3fv(n[i]);
  646.       glBegin(GL_POLYGON);
  647.       glVertex3fv(c[i][j][0]);
  648.       glVertex3fv(c[i][j][1]);
  649.       glVertex3fv(c[i][j][2]);
  650.       glVertex3fv(c[i][j][3]);
  651.       glEnd();
  652.     }
  653.   }
  654.   glEndList();
  655. }
  656.  
  657. void BuildLists(void)
  658. {
  659.  
  660.   cube = glGenLists(1);
  661.   BuildCube();
  662.  
  663.   cage = glGenLists(2);
  664.   BuildCage();
  665.  
  666.   cylinder = glGenLists(3);
  667.   BuildCylinder(60);
  668.  
  669.   torus = glGenLists(4);
  670.   BuildTorus(0.65, 20, .85, 65);
  671.  
  672.   genericObject = torus;
  673. }
  674.  
  675. void SetDeepestColor(void)
  676. {
  677.   GLint redBits, greenBits, blueBits;
  678.  
  679.   glGetIntegerv(GL_RED_BITS, &redBits);
  680.   glGetIntegerv(GL_GREEN_BITS, &greenBits);
  681.   glGetIntegerv(GL_BLUE_BITS, &blueBits);
  682.  
  683.   deepestColor = (redBits >= greenBits) ? TK_RED : TK_GREEN;
  684.   deepestColor = (deepestColor >= blueBits) ? deepestColor : TK_BLUE;
  685. }
  686.  
  687. void SetDefaultSettings(void)
  688. {
  689.  
  690.   magFilter = nnearest;
  691.   minFilter = nnearest;
  692.   sWrapMode = repeat;
  693.   tWrapMode = repeat;
  694.   textureEnvironment = modulate;
  695.   autoRotate = TRUE;
  696. }
  697.  
  698. unsigned char *AlphaPadImage(int bufSize, unsigned char *inData, int alpha)
  699. {
  700.   unsigned char *outData, *out_ptr, *in_ptr;
  701.   int i;
  702.  
  703.   outData = (unsigned char *)malloc(bufSize * 4);
  704.   out_ptr = outData;
  705.   in_ptr = inData;
  706.  
  707.   for (i = 0; i < bufSize; i++) {
  708.     *out_ptr++ = *in_ptr++;
  709.     *out_ptr++ = *in_ptr++;
  710.     *out_ptr++ = *in_ptr++;
  711.     *out_ptr++ = alpha;
  712.   }
  713.  
  714.   free(inData);
  715.   return outData;
  716. }
  717.  
  718. void Init(void)
  719. {
  720.   float ambient[] =
  721.   {0.0, 0.0, 0.0, 1.0};
  722.   float diffuse[] =
  723.   {0.0, 1.0, 0.0, 1.0};
  724.   float specular[] =
  725.   {1.0, 1.0, 1.0, 1.0};
  726.   float position[] =
  727.   {2.0, 2.0, 0.0, 1.0};
  728.   float fog_color[] =
  729.   {0.0, 0.0, 0.0, 1.0};
  730.   float mat_ambient[] =
  731.   {0.0, 0.0, 0.0, 1.0};
  732.   float mat_shininess[] =
  733.   {90.0};
  734.   float mat_specular[] =
  735.   {1.0, 1.0, 1.0, 1.0};
  736.   float mat_diffuse[] =
  737.   {1.0, 1.0, 1.0, 1.0};
  738.   float lmodel_ambient[] =
  739.   {0.0, 0.0, 0.0, 1.0};
  740.   float lmodel_twoside[] =
  741.   {GL_TRUE};
  742.  
  743.   SetDeepestColor();
  744.   SetDefaultSettings();
  745.  
  746.   if (numComponents == 4) {
  747.     image = tkRGBImageLoad(imageFileName);
  748.     image->data = AlphaPadImage(image->sizeX * image->sizeY,
  749.                 image->data, 128);
  750.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  751.     gluBuild2DMipmaps(GL_TEXTURE_2D, numComponents,
  752.               image->sizeX, image->sizeY,
  753.               GL_RGBA, GL_UNSIGNED_BYTE, image->data);
  754.   }
  755.   else {
  756.     image = tkRGBImageLoad(imageFileName);
  757.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  758.     gluBuild2DMipmaps(GL_TEXTURE_2D, numComponents,
  759.               image->sizeX, image->sizeY,
  760.               GL_RGB, GL_UNSIGNED_BYTE, image->data);
  761.   }
  762.  
  763.   glFogf(GL_FOG_DENSITY, 0.125);
  764.   glFogi(GL_FOG_MODE, GL_LINEAR);
  765.   glFogf(GL_FOG_START, 4.0);
  766.   glFogf(GL_FOG_END, 9.0);
  767.   glFogfv(GL_FOG_COLOR, fog_color);
  768.  
  769.   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  770.   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  771.   glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
  772.   glLightfv(GL_LIGHT0, GL_POSITION, position);
  773.  
  774.   glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
  775.   glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
  776.   glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
  777.   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
  778.  
  779.   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  780.   glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
  781.   glShadeModel(GL_SMOOTH);
  782.  
  783.   glEnable(GL_LIGHTING);
  784.   glEnable(GL_LIGHT0);
  785.  
  786.   glClearColor(0.0, 0.0, 0.0, 0.0);
  787.   glViewport(0, 0, W, H);
  788.   glEnable(GL_DEPTH_TEST);
  789.  
  790.   glFrontFace(GL_CW);
  791.   glEnable(GL_CULL_FACE);
  792.   glCullFace(GL_BACK);
  793.  
  794.   glEnable(GL_TEXTURE_2D);
  795.   glTexGeniv(GL_S, GL_TEXTURE_GEN_MODE, sphereMap);
  796.   glTexGeniv(GL_T, GL_TEXTURE_GEN_MODE, sphereMap);
  797.   glEnable(GL_TEXTURE_GEN_S);
  798.   glEnable(GL_TEXTURE_GEN_T);
  799.  
  800.   glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
  801.   glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
  802.   glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, sWrapMode);
  803.   glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tWrapMode);
  804.  
  805.   glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, textureEnvironment);
  806.  
  807.   BuildLists();
  808. }
  809.  
  810. void ReInit(void)
  811. {
  812.  
  813.   if (genericObject == torus) {
  814.     glEnable(GL_DEPTH_TEST);
  815.   }
  816.   else {
  817.     glDisable(GL_DEPTH_TEST);
  818.   }
  819.   if (isFogged) {
  820.     textureEnvironment = modulate;
  821.   }
  822.  
  823.   glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
  824.   glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
  825.   glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, textureEnvironment);
  826. }
  827.  
  828. void Draw(void)
  829. {
  830.  
  831.   glMatrixMode(GL_PROJECTION);
  832.   glLoadIdentity();
  833.   glFrustum(-0.2, 0.2, -0.2, 0.2, 0.15, 9.0);
  834.   glMatrixMode(GL_MODELVIEW);
  835.  
  836.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  837.   if (isFogged) {
  838.     glEnable(GL_FOG);
  839.     glColor3fv(tkRGBMap[deepestColor]);
  840.   }
  841.   else {
  842.     glColor3fv(tkRGBMap[TK_WHITE]);
  843.   }
  844.   glDisable(GL_LIGHTING);
  845.   glDisable(GL_LIGHT0);
  846.   glDisable(GL_TEXTURE_2D);
  847.   glCallList(cage);
  848.  
  849.   glPushMatrix();
  850.   glTranslatef(0.0, 0.0, zTranslate);
  851.   glRotatef(xRotation, 1, 0, 0);
  852.   glRotatef(yRotation, 0, 1, 0);
  853.  
  854.   if (isLit == TRUE) {
  855.     glEnable(GL_LIGHTING);
  856.     glEnable(GL_LIGHT0);
  857.   }
  858.  
  859.   glEnable(GL_TEXTURE_2D);
  860.   if (isFogged) {
  861.     glDisable(GL_FOG);
  862.   }
  863.   glPolygonMode(GL_FRONT, GL_FILL);
  864.   glColor3fv(tkRGBMap[deepestColor]);
  865.   glCallList(genericObject);
  866.  
  867.   glPopMatrix();
  868.   glFlush();
  869.  
  870.   if (autoRotate) {
  871.     xRotation += .75;
  872.     yRotation += .375;
  873.   }
  874.   tkSwapBuffers();
  875. }
  876.  
  877. void Reshape(int width, int height)
  878. {
  879.  
  880.   W = width;
  881.   H = height;
  882.   ReInit();
  883.   glViewport(0, 0, width, height);                           /*
  884.                                             * new
  885.                                             */
  886. }
  887.  
  888. GLenum Key(int key, GLenum mask)
  889. {
  890.  
  891.   switch (key) {
  892.     case TK_ESCAPE:
  893.       free(image->data);
  894.       tkQuit();
  895.  
  896.     case TK_LEFT:
  897.       yRotation -= 0.5;
  898.       autoRotate = FALSE;
  899.       ReInit();
  900.       break;
  901.     case TK_RIGHT:
  902.       yRotation += 0.5;
  903.       autoRotate = FALSE;
  904.       ReInit();
  905.       break;
  906.     case TK_UP:
  907.       xRotation -= 0.5;
  908.       autoRotate = FALSE;
  909.       ReInit();
  910.       break;
  911.     case TK_DOWN:
  912.       xRotation += 0.5;
  913.       autoRotate = FALSE;
  914.       ReInit();
  915.       break;
  916.     case TK_a:
  917.       autoRotate = !autoRotate;
  918.       ReInit();
  919.       break;
  920.     case TK_c:
  921.       genericObject = (genericObject == cube) ? cylinder : cube;
  922.       ReInit();
  923.       break;
  924.     case TK_d:
  925.       textureEnvironment = decal;
  926.       ReInit();
  927.       break;
  928.     case TK_m:
  929.       textureEnvironment = modulate;
  930.       ReInit();
  931.       break;
  932.     case TK_l:
  933.       isLit = !isLit;
  934.       ReInit();
  935.       break;
  936.     case TK_f:
  937.       isFogged = !isFogged;
  938.       ReInit();
  939.       break;
  940.     case TK_t:
  941.       genericObject = torus;
  942.       ReInit();
  943.       break;
  944.     case TK_0:
  945.       magFilter = nnearest;
  946.       ReInit();
  947.       break;
  948.     case TK_1:
  949.       magFilter = linear;
  950.       ReInit();
  951.       break;
  952.     case TK_2:
  953.       minFilter = nnearest;
  954.       ReInit();
  955.       break;
  956.     case TK_3:
  957.       minFilter = linear;
  958.       ReInit();
  959.       break;
  960.     case TK_4:
  961.       minFilter = nearest_mipmap_nearest;
  962.       ReInit();
  963.       break;
  964.     case TK_5:
  965.       minFilter = nearest_mipmap_linear;
  966.       ReInit();
  967.       break;
  968.     case TK_6:
  969.       minFilter = linear_mipmap_nearest;
  970.       ReInit();
  971.       break;
  972.     case TK_7:
  973.       minFilter = linear_mipmap_linear;
  974.       ReInit();
  975.       break;
  976.  
  977.     default:
  978.       return GL_FALSE;
  979.   }
  980.   return GL_TRUE;
  981. }
  982.  
  983. GLenum Args(int argc, char **argv)
  984. {
  985.   GLint i;
  986.  
  987.   doubleBuffer = GL_FALSE;
  988.   directRender = GL_TRUE;
  989.   numComponents = 4;
  990.  
  991.   for (i = 1; i < argc; i++) {
  992.     if (strcmp(argv[i], "-sb") == 0) {
  993.       doubleBuffer = GL_FALSE;
  994.     }
  995.     else if (strcmp(argv[i], "-db") == 0) {
  996.       doubleBuffer = GL_TRUE;
  997.     }
  998.     else if (strcmp(argv[i], "-dr") == 0) {
  999.       directRender = GL_TRUE;
  1000.     }
  1001.     else if (strcmp(argv[i], "-ir") == 0) {
  1002.       directRender = GL_FALSE;
  1003.     }
  1004.     else if (strcmp(argv[i], "-f") == 0) {
  1005.       if (i + 1 >= argc || argv[i + 1][0] == '-') {
  1006.     printf("-f (No file name).\n");
  1007.     return GL_FALSE;
  1008.       }
  1009.       else {
  1010.     imageFileName = argv[++i];
  1011.       }
  1012.     }
  1013.     else if (strcmp(argv[i], "-4") == 0) {
  1014.       numComponents = 4;
  1015.     }
  1016.     else if (strcmp(argv[i], "-3") == 0) {
  1017.       numComponents = 3;
  1018.     }
  1019.     else {
  1020.       printf("%s (Bad option).\n", argv[i]);
  1021.       return GL_FALSE;
  1022.     }
  1023.   }
  1024.   return GL_TRUE;
  1025. }
  1026.  
  1027. void main(int argc, char **argv)
  1028. {
  1029.   GLenum type;
  1030.  
  1031.   if (Args(argc, argv) == GL_FALSE) {
  1032.     tkQuit();
  1033.   }
  1034.  
  1035.   if (imageFileName == 0) {
  1036.     printf("No image file.\n");
  1037.     tkQuit();
  1038.   }
  1039.  
  1040.   tkInitPosition(0, 0, W, H);
  1041.  
  1042.   type = TK_RGB | TK_DEPTH;
  1043.   type |= (doubleBuffer) ? TK_DOUBLE : TK_SINGLE;
  1044.   type |= (directRender) ? TK_DIRECT : TK_INDIRECT;
  1045.   tkInitDisplayMode(type);
  1046.  
  1047.   if (tkInitWindow("Texture Test") == GL_FALSE) {
  1048.     tkQuit();
  1049.   }
  1050.  
  1051.   Init();
  1052.  
  1053.   tkExposeFunc(Reshape);
  1054.   tkReshapeFunc(Reshape);
  1055.   tkKeyDownFunc(Key);
  1056.   tkIdleFunc(Draw);
  1057.  
  1058.   tkExec();
  1059. }
  1060.