home *** CD-ROM | disk | FTP | other *** search
/ Freelog Special Issue 2 / Freelog_HS_3_Setp_Oct_Nov_2000_CD2.mdx / Arcade / Orbit / src / rings.c < prev    next >
C/C++ Source or Header  |  1999-09-27  |  6KB  |  296 lines

  1. /*
  2.  
  3. ORBIT, a freeware space combat simulator
  4. Copyright (C) 1999  Steve Belczyk <steve1@genesis.nred.ma.us>
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20. */
  21.  
  22. #include "orbit.h"
  23.  
  24. InitRings()
  25. /*
  26.  *  Initialize rings
  27.  */
  28. {
  29.     int r;
  30.  
  31.     /* Jupiter */
  32.     ring[0].primary = 8;
  33.     ring[0].r1 = 102000.0 / KM_TO_UNITS1;
  34.     ring[0].r2 = 129130.0 / KM_TO_UNITS1;
  35.     strcpy (ring[0].fn, "maps/jupring.ppm");
  36.  
  37.     /* Saturn */
  38.     ring[1].primary = 13;
  39.     ring[1].r1 = 74400.0 / KM_TO_UNITS1;
  40.     ring[1].r2 = 140154.0 / KM_TO_UNITS1;
  41.     strcpy (ring[1].fn, "maps/satring.ppm");
  42.  
  43.     /* Uranus */
  44.     ring[2].primary = 21;
  45.     ring[2].r1 = 38949.0 / KM_TO_UNITS1;
  46.     ring[2].r2 = 50271.0 / KM_TO_UNITS1;
  47.     strcpy (ring[2].fn, "maps/uraring.ppm");
  48.  
  49.     /* Neptune */
  50.     ring[3].primary = 27;
  51.     ring[3].r1 = 42000.0 / KM_TO_UNITS1;
  52.     ring[3].r2 = 63000.0 / KM_TO_UNITS1;
  53.     strcpy (ring[3].fn, "maps/nepring.ppm");
  54.  
  55.     /* Read the textures, make display lists */
  56.     for (r=0; r<NRINGS; r++)
  57.     {
  58.         ReadRingTexture (r);
  59.         MakeRingList (r);
  60.     }
  61. }
  62.  
  63. ReadRingTexture (r)
  64. int r;
  65. /*
  66.  *  Read texture for planetary rings
  67.  */
  68. {
  69.     int x, y, c, i;
  70.     FILE *fd;
  71.  
  72.     /* Get id for this texture */
  73.     glGenTextures (1, &ring[r].texid);
  74.     glBindTexture (GL_TEXTURE_2D, ring[r].texid);
  75.     glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
  76.  
  77.     /* Open the file */
  78.     if (NULL == (fd = fopen (ring[r].fn, "rb")))
  79.     {
  80.         Log ("Can't open %s, giving up!", ring[r].fn);
  81.         FinishSound();
  82.         CloseLog();
  83.         exit (0);
  84.     }
  85.  
  86.     /* Read past PPM header */
  87.     while (10 != fgetc(fd));
  88.     while (10 != fgetc(fd));
  89.     while (10 != fgetc(fd));
  90.  
  91.     /* Read in the color data */
  92.     for (y=0; y<8; y++)
  93.     {
  94.         for (x=0; x<255; x++)
  95.         {
  96.             for (i=0; i<3; i++)
  97.             {
  98.                 c = fgetc (fd);
  99.                 ring[r].tex[x][y][i] = 0xff & c;
  100.             }
  101.  
  102.             /* Don't forget alpha! */
  103.             ring[r].tex[x][y][3] = ring[r].tex[x][y][2];
  104.         }
  105.         
  106.         for (i=0; i<4; i++)
  107.         {
  108.             ring[r].tex[255][y][i] = 0;
  109.         }
  110.     }
  111.  
  112.     fclose (fd);
  113.  
  114.     /* Set the texture */
  115.     glTexImage2D (GL_TEXTURE_2D, 0, 4, 8, 256, 0, GL_RGBA,
  116.         GL_UNSIGNED_BYTE, ring[r].tex);
  117.     glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  118.     glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  119.     glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  120.     glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  121.     glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  122. }
  123.  
  124. static float MaterialColor[] = {1.0, 1.0, 1.0, 1.0};
  125.  
  126. MakeRingList (r)
  127. int r;
  128. /*
  129.  *  Make the display list for planetary rings
  130.  */
  131. {
  132.     double x, y, r1, r2, th, a;
  133.     int i, parity;
  134.  
  135.     /* Which side of the texture are we on */
  136.     parity = 0;
  137.  
  138.     /* Inner, outer radii */
  139.     r1 = ring[r].r1;
  140.     r2 = ring[r].r2;
  141.  
  142.     /* Angle of each sector */
  143.     a = 6.28 / ((double) ring_sectors);
  144.  
  145.     /* Get a display list */
  146.     ring[r].list = glGenLists (1);
  147.     glNewList (ring[r].list, GL_COMPILE);
  148.  
  149.     /* Don't write to depth buffer */
  150.     glDepthMask (GL_FALSE);
  151.  
  152.     /* Set up texture */
  153.     glBindTexture (GL_TEXTURE_2D, ring[r].texid);
  154.  
  155.     /* Do alpha blending here */
  156.     glEnable (GL_BLEND);
  157.     glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  158.  
  159.     /* Rings are a quad strip */
  160.     glBegin (GL_QUAD_STRIP);
  161.  
  162.     for (i=0, th=0.0; i<=ring_sectors; i++, th+=a)
  163.     {
  164.         if (i == ring_sectors) th = 0.0;
  165.  
  166.         x = r2 * sin (th);
  167.         y = r2 * cos (th);
  168.         glNormal3f (0.0, 0.0, 1.0);
  169.         if (parity)
  170.             glTexCoord2f (0.0, 1.0);
  171.         else
  172.             glTexCoord2f (1.0, 1.0);
  173.         glVertex3d (x, y, 0.0);
  174.  
  175.         x = r1 * sin (th);
  176.         y = r1 * cos (th);
  177.         glNormal3f (0.0, 0.0, 1.0);
  178.         if (parity)
  179.             glTexCoord2f (0.0, 0.0);
  180.         else
  181.             glTexCoord2f (1.0, 0.0);
  182.         glVertex3d (x, y, 0.0);
  183.         
  184.         parity = !parity;
  185.     }
  186.     glEnd ();    /* Quad strip */
  187.  
  188.     /* Now do one upside down */
  189.  
  190. /***********
  191.     glPushMatrix();
  192.     glRotated (180.0, 0.0, 1.0, 0.0);
  193.     glBegin (GL_QUAD_STRIP);
  194.  
  195.     parity = 0;
  196.  
  197.     for (i=0, th=0.0; i<=ring_sectors; i++, th+=a)
  198.     {
  199.         if (i == ring_sectors) th = 0.0;
  200.  
  201.         x = r2 * sin (th);
  202.         y = r2 * cos (th);
  203.         glNormal3f (0.0, 0.0, 1.0);
  204.         if (parity)
  205.             glTexCoord2f (0.0, 1.0);
  206.         else
  207.             glTexCoord2f (1.0, 1.0);
  208.         glVertex3d (x, y, 0.0);
  209.  
  210.         x = r1 * sin (th);
  211.         y = r1 * cos (th);
  212.         glNormal3f (0.0, 0.0, 1.0);
  213.         if (parity)
  214.             glTexCoord2f (0.0, 0.0);
  215.         else
  216.             glTexCoord2f (1.0, 0.0);
  217.         glVertex3d (x, y, 0.0);
  218.         
  219.         parity = !parity;
  220.     }
  221.     glEnd ();
  222.     glPopMatrix();
  223. ***************/
  224.  
  225.     glDisable (GL_BLEND);
  226.     glDepthMask (GL_TRUE);
  227.     glEndList();
  228. }
  229.  
  230. float TransColor[4] = {1.0, 1.0, 1.0, 0.5};
  231.     
  232. DrawRings()
  233. /*
  234.  *  Render those pretty rings
  235.  */
  236. {
  237.     int r, p;
  238.     double v[3];
  239.  
  240.     /* Don't bother if Sparky doesn't want them */
  241.     if (!rings) return;
  242.  
  243.     /* Turn off lighting so rings are constant brightness */
  244.     glDisable (GL_LIGHTING);
  245.  
  246.     /* Set color to white, will be modulated with texture */
  247.     if (textures)
  248.     {
  249.         glColor4fv (MaterialColor);
  250. /*        glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor);    */
  251.     }
  252.     else
  253.     {
  254. /*        glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, TransColor);    */
  255.         glColor4fv (TransColor);
  256.     }
  257.  
  258.     for (r=0; r<NRINGS; r++)
  259.     {
  260.         p = ring[r].primary;
  261.  
  262.         /* Forget it if primary is hidden */
  263.         if (planet[p].hidden) continue;
  264.  
  265.         /* Don't bother if too far away */
  266.         if (planet[p].range2 > MAX_RING_RANGE) continue;
  267.  
  268.         glPushMatrix();
  269.  
  270.         /* Translate to planet */
  271.         Vsub (v, planet[p].pos, player.pos);
  272.         glTranslated (v[0], v[1], v[2]);
  273.  
  274.         /* Rotate for oblicity */
  275.         glRotated (planet[p].oblicity, 1.0, 0.0, 0.0);
  276.  
  277.         /* Turn off backface removal so we only have to draw rings
  278.            on one side */
  279.         glDisable (GL_CULL_FACE);
  280.  
  281.         /* Draw, pahdner! */
  282.         if (textures)
  283.             glEnable (GL_TEXTURE_2D);
  284.         else
  285.             glDisable (GL_TEXTURE_2D);
  286.         glCallList (ring[r].list);
  287.  
  288.         glDisable (GL_TEXTURE_2D);
  289.         if (textures) glEnable (GL_LIGHTING);
  290.         glEnable (GL_CULL_FACE);
  291.  
  292.         glPopMatrix();
  293.     }
  294. }
  295.  
  296.