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