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