home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl2 / examples / porting / solar_irisgl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  7.5 KB  |  307 lines

  1. /*                solar_irisgl.c
  2.  *    solar displays a planet with a moon orbiting a sun using
  3.  *    pure IRIG GL.
  4.  * 
  5.  *    Copyright 1991, Silicon Graphics, Inc.  All Rights Reserved.
  6.  *    See ~/copyright for complete rights and liability information.
  7.  *    Author:   Technical Education Course Developers
  8.  */
  9.  
  10. #include <gl/gl.h>
  11. #include <gl/device.h>
  12. #include <gl/get.h>
  13. #include <stdio.h>
  14. #include <math.h>
  15.  
  16. /* function prototypes */
  17.  
  18. void main( int, char ** );
  19. void initialize( char * );
  20. void drawscene(short angle);
  21. void setbeachball(int stripes);
  22. void beachball(unsigned long color1, unsigned long color2);
  23.  
  24. /*         main
  25.  *    main calls initialize, then goes into a loop.  Within the loop
  26.  *    drawscene is called and passed an angle, the angle is 
  27.  *    incremented and events in the event queue are processed 
  28.  *    until user exits. 
  29.  *
  30.  *    The user can exit by pressing ESCAPE or through 
  31.  *    the window manager. 
  32.  *
  33.  *    If the LEFTMOUSE button is pressed mouse x/y input is 
  34.  *    read from the queue until the button is released.  
  35.  *    The mouse x/y input is passed to drawscene. 
  36.  */
  37.  
  38. void
  39. main( int argc, char *argv[] )
  40. {
  41.     Boolean exitflag = FALSE;
  42.     short value;
  43.     long dev;
  44.     short angle = 0;
  45.     short attached = 0; /* attached flags changes to input focus */
  46.  
  47.     if (getgdesc(GD_BITS_NORM_ZBUFFER) == 0) {
  48.         fprintf(stderr, "This machine does not have a zbuffer\n");
  49.         exit(0);
  50.     }
  51.     initialize( argv[0] );
  52.  
  53.     while (exitflag == FALSE) {
  54.         drawscene(angle);
  55.  
  56.         /* increment angle each time scene is drawn */
  57.         if (angle < 3600)
  58.             angle = angle + 10;
  59.         else
  60.             angle = 0;
  61.  
  62.         while ( (exitflag == FALSE) && (qtest() || !attached) ) {
  63.             /* if not attached, block until there is a 
  64.              * queue entry */
  65.             dev = qread (&value);
  66.             if (dev == ESCKEY) {
  67.                 /* if the device is ESCKEY, exit program 
  68.                  * on key up */
  69.                 if (value == 0)
  70.                     exitflag = TRUE;
  71.             }
  72.             else if (dev == REDRAW) {
  73.                 /* if window needs to be redrawn, 
  74.                  * tell the system that the shape 
  75.                  * of the window may have changed,
  76.                  * then re-draw the scene */
  77.                 reshapeviewport();
  78.                 drawscene(angle);
  79.             }
  80.             else if (dev == INPUTCHANGE)
  81.                 attached = value;
  82.                 /* if cursor moves into window, value = gid
  83.                  * if cursor moves out of window, value = 0 */
  84.         }   /*  end while exitflag FALSE and (qtest or not attached) */
  85.     }   /*  end while exitflag FALSE */
  86.     exit(0);
  87. }    /*   end main()   */
  88.  
  89. /*        initialize     
  90.  *    Positions the window and specifies its future constraints.  
  91.  *    Graphics configuration is set and event queue is initialized. 
  92.  */
  93. void 
  94. initialize( char *progname )
  95. {
  96.     long gid1, xmax, ymax;
  97.     float aspect;
  98.  
  99.     xmax = getgdesc(GD_XPMAX);
  100.     ymax = getgdesc(GD_YPMAX);
  101.  
  102.     prefposition(xmax/4, xmax*3/4, ymax/4, ymax*3/4);
  103.     gid1 = winopen( progname );
  104.     minsize(xmax/10, ymax/10);
  105.     keepaspect(xmax, ymax);
  106.     winconstraints();
  107.  
  108.     doublebuffer();
  109.     RGBmode();
  110.     gconfig();
  111.  
  112.     zbuffer(TRUE);
  113.     shademodel(FLAT);
  114.  
  115.     qdevice(LEFTMOUSE);
  116.     qdevice(MIDDLEMOUSE);
  117.     qdevice(ESCKEY);
  118.     tie(LEFTMOUSE, MOUSEX, MOUSEY);
  119.  
  120.     /* separtae ModelView and Projection matrix stacks;
  121.      * both are initialized with an identity matrix.
  122.      */
  123.     mmode(MVIEWING);
  124.     aspect = (float) xmax / (float) ymax;
  125.  
  126.     /* projection commands replace projection matrix */
  127.     perspective(450, aspect, 1.0, 25.0);
  128.  
  129.     /* viewing commands premultiply the ModelView matrix */
  130.     polarview(12.0, 0, -100, 0);
  131. }    /*   end initialize()   */
  132.  
  133. /*        drawscene
  134.  *    drawscene calculates angles relative to the yearangle, 
  135.  *    and then draws sun, planet, and moon.
  136.  */
  137.  
  138. void
  139. drawscene(short yearangle)
  140. {
  141.     static long blackcol[] = { 0, 0, 0 };
  142.     static long bluecol[] = { 0, 0, 255 };
  143.     static long whitecol[] = { 255, 255, 255 };
  144.     short sunangle, dayangle, monthangle;
  145.     /* actual 1.5e8 kM * 3.0e-9 fudgefactor */
  146.     float earthdist = 4.5, earthscale = 0.5;
  147.     float moondist = 0.9, moonscale = 0.2;
  148.  
  149.     c3i(blackcol);
  150.     /* clear color & z buffers */
  151.     czclear(getgdesc(GD_ZMIN),getgdesc(GD_ZMAX)); 
  152.     pushmatrix();
  153.     sunangle = (yearangle*365/25) % 3600;
  154.     /* sun rotates on axis every 25 days */
  155.     rotate(sunangle, 'y');
  156.     beachball(0x20C0FF, 0x200FFFF); /* colors in cpack format */
  157.     popmatrix();
  158.     pushmatrix();
  159.     rotate(yearangle, 'y');
  160.     translate(earthdist, 0.0, 0.0);
  161.     pushmatrix();
  162.     dayangle = (yearangle*50) % 3600; /* fudged so rotation shows  */
  163.     rotate(dayangle, 'y');
  164.     scale(earthscale, earthscale, earthscale);
  165.     c3i(bluecol);
  166.     beachball(0xFF0000, 0xC02000); /* earth */
  167.     popmatrix();
  168.     monthangle = (yearangle*365/28) % 3600;
  169.     rotate(monthangle, 'y');
  170.     translate (moondist, 0.0, 0.0);
  171.     scale(moonscale, moonscale, moonscale);
  172.     c3i(whitecol);
  173.     beachball(0xFFFFFF, 0xC0C0C0); /* moon */
  174.     popmatrix();
  175.  
  176.     swapbuffers();
  177. }   /*  end drawscene()  */
  178.  
  179.  
  180. /* BEACHBALL */
  181.  
  182. /* three dimensional vector */
  183. typedef float vector[3];
  184.  
  185. static vector front  = { 0.0,  0.0,  1.0 };
  186. static vector back   = { 0.0,  0.0, -1.0 };
  187. static vector top    = { 0.0,  1.0,  0.0 };
  188. static vector bottom = { 0.0, -1.0,  0.0 };
  189. static vector right  = { 1.0,  0.0,  0.0 };
  190. static vector left   = { -1.0,  0.0,  0.0 };
  191. static vector center = { 0.0,  0.0,  0.0 };
  192.  
  193. /* Number of colored stripes. Should be even to look right */
  194. #define BEACHBALL_STRIPES 12
  195.  
  196. /* Default number of polygons  making up a stripe. Should be even */
  197. #define BEACHBALL_POLYS 16
  198.  
  199. /* array of vertices making up a stripe */
  200. static vector stripe_point[BEACHBALL_POLYS + 3];
  201.  
  202. /* has the beachball been initialized */
  203. static Boolean beachball_initialized = FALSE;
  204.  
  205. /* Number of polygons making up a stripe */
  206. static int beachball_stripes;
  207.  
  208. /* Number of vertices making up a stripe */
  209. static int stripe_vertices;
  210.  
  211. /* Initialize beachball_point array to be a stripe 
  212.  * of unit radius.
  213.  */
  214. void setbeachball(int stripes)
  215. {
  216.     int i,j;
  217.     float x,y,z;             /* vertex points */
  218.     float theta,delta_theta;    /* angle from top pole to bottom pole */
  219.     float offset;         /* offset from center of stripe to vertex */
  220.     float cross_radius; /* radius of cross section at current latitude */
  221.     float cross_theta;  /* angle occupied by a stripe  */
  222.  
  223.     beachball_stripes = stripes;
  224.  
  225.     /* polys distributed by even angles from top to bottom */
  226.     delta_theta = M_PI/((float)BEACHBALL_POLYS/2.0);
  227.     theta = delta_theta;
  228.  
  229.     cross_theta = 2.0*M_PI/(float)beachball_stripes;
  230.  
  231.     j = 0;
  232.  
  233.     stripe_point[j][0] = top[0];
  234.     stripe_point[j][1] = top[1];
  235.     stripe_point[j][2] = top[2];
  236.     j++;
  237.  
  238.     for (i = 0; i < BEACHBALL_POLYS; i += 2) {
  239.         cross_radius = fsin(theta);
  240.         offset = cross_radius * ftan(cross_theta/2.0);
  241.  
  242.         stripe_point[j][0] = - offset;
  243.         stripe_point[j][1] = fcos(theta);
  244.         stripe_point[j][2] = cross_radius;
  245.         j++;
  246.  
  247.         stripe_point[j][0] = offset;
  248.         stripe_point[j][1] = stripe_point[j-1][1];
  249.         stripe_point[j][2] = stripe_point[j-1][2];
  250.         j++;
  251.  
  252.         theta += delta_theta;
  253.     }
  254.  
  255.     stripe_point[j][0] = bottom[0];
  256.     stripe_point[j][1] = bottom[1];
  257.     stripe_point[j][2] = bottom[2];
  258.  
  259.     stripe_vertices = j + 1;
  260.  
  261.     beachball_initialized = TRUE;
  262. }
  263.  
  264. /*
  265.  *    Draws a canonical beachball.  The colors are cpack values 
  266.  *    when in RGBmode, colormap indices when in colormap mode.
  267.  */
  268. void beachball(unsigned long c1, unsigned long c2)
  269. {
  270.     long mode;
  271.     float angle, delta_angle;
  272.     int i,j;
  273.  
  274.     if (! beachball_initialized)
  275.         setbeachball(BEACHBALL_STRIPES);
  276.  
  277.     mode = getdisplaymode();
  278.  
  279.     angle = 0.0;
  280.     delta_angle = 360.0/(float)beachball_stripes;
  281.  
  282.     for (i = 0; i < beachball_stripes; i++) {
  283.         switch(mode) {
  284.         case DMSINGLE: case DMDOUBLE:
  285.             if ( i%2 == 0)
  286.                 color(c1);
  287.             else color(c2);
  288.             break;
  289.         case DMRGB: case DMRGBDOUBLE:
  290.             if ( i%2 == 0)
  291.                 cpack(c1);
  292.             else cpack(c2);
  293.             break;
  294.         }
  295.  
  296.         pushmatrix();
  297.         rot(angle, 'y');
  298.         angle += delta_angle;
  299.  
  300.         bgntmesh();
  301.             for (j = 0; j < stripe_vertices; j++)
  302.                 v3f(stripe_point[j]);
  303.         endtmesh();
  304.         popmatrix();
  305.     }
  306. }
  307.