home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quake_src / gl_warp.c < prev    next >
C/C++ Source or Header  |  2000-06-17  |  23KB  |  1,093 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // gl_warp.c -- sky and water polygons
  21.  
  22. #include "quakedef.h"
  23.  
  24. extern  model_t *loadmodel;
  25.  
  26. int   skytexturenum;
  27.  
  28. int   solidskytexture;
  29. int   alphaskytexture;
  30. float speedscale;   // for top sky and bottom sky
  31.  
  32. msurface_t  *warpface;
  33.  
  34. extern cvar_t gl_subdivide_size;
  35.  
  36. void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs)
  37. {
  38.   int   i, j;
  39.   float *v;
  40.  
  41.   mins[0] = mins[1] = mins[2] = 9999;
  42.   maxs[0] = maxs[1] = maxs[2] = -9999;
  43.   v = verts;
  44.   for (i=0 ; i<numverts ; i++)
  45.     for (j=0 ; j<3 ; j++, v++)
  46.     {
  47.       if (*v < mins[j])
  48.         mins[j] = *v;
  49.       if (*v > maxs[j])
  50.         maxs[j] = *v;
  51.     }
  52. }
  53.  
  54. void SubdividePolygon (int numverts, float *verts)
  55. {
  56.   int   i, j, k;
  57.   vec3_t  mins, maxs;
  58.   float m;
  59.   float *v;
  60.   vec3_t  front[64], back[64];
  61.   int   f, b;
  62.   float dist[64];
  63.   float frac;
  64.   glpoly_t  *poly;
  65.   float s, t;
  66.  
  67.   if (numverts > 60)
  68.     Sys_Error ("numverts = %i", numverts);
  69.  
  70.   BoundPoly (numverts, verts, mins, maxs);
  71.  
  72.   for (i=0 ; i<3 ; i++)
  73.   {
  74.     m = (mins[i] + maxs[i]) * 0.5;
  75.     m = gl_subdivide_size.value * floor (m/gl_subdivide_size.value + 0.5);
  76.     if (maxs[i] - m < 8)
  77.       continue;
  78.     if (m - mins[i] < 8)
  79.       continue;
  80.  
  81.     // cut it
  82.     v = verts + i;
  83.     for (j=0 ; j<numverts ; j++, v+= 3)
  84.       dist[j] = *v - m;
  85.  
  86.     // wrap cases
  87.     dist[j] = dist[0];
  88.     v-=i;
  89.     VectorCopy (verts, v);
  90.  
  91.     f = b = 0;
  92.     v = verts;
  93.     for (j=0 ; j<numverts ; j++, v+= 3)
  94.     {
  95.       if (dist[j] >= 0)
  96.       {
  97.         VectorCopy (v, front[f]);
  98.         f++;
  99.       }
  100.       if (dist[j] <= 0)
  101.       {
  102.         VectorCopy (v, back[b]);
  103.         b++;
  104.       }
  105.       if (dist[j] == 0 || dist[j+1] == 0)
  106.         continue;
  107.       if ( (dist[j] > 0) != (dist[j+1] > 0) )
  108.       {
  109.         // clip point
  110.         frac = dist[j] / (dist[j] - dist[j+1]);
  111.         for (k=0 ; k<3 ; k++)
  112.           front[f][k] = back[b][k] = v[k] + frac*(v[3+k] - v[k]);
  113.         f++;
  114.         b++;
  115.       }
  116.     }
  117.  
  118.     SubdividePolygon (f, front[0]);
  119.     SubdividePolygon (b, back[0]);
  120.     return;
  121.   }
  122.  
  123.   poly = Hunk_Alloc (sizeof(glpoly_t) + (numverts-4) * VERTEXSIZE*sizeof(float));
  124.   poly->next = warpface->polys;
  125.   warpface->polys = poly;
  126.   poly->numverts = numverts;
  127.   for (i=0 ; i<numverts ; i++, verts+= 3)
  128.   {
  129.     VectorCopy (verts, poly->verts[i]);
  130.     s = DotProduct (verts, warpface->texinfo->vecs[0]);
  131.     t = DotProduct (verts, warpface->texinfo->vecs[1]);
  132.     poly->verts[i][3] = s;
  133.     poly->verts[i][4] = t;
  134.   }
  135. }
  136.  
  137. /*
  138. ================
  139. GL_SubdivideSurface
  140.  
  141. Breaks a polygon up along axial 64 unit
  142. boundaries so that turbulent and sky warps
  143. can be done reasonably.
  144. ================
  145. */
  146. void GL_SubdivideSurface (msurface_t *fa)
  147. {
  148.   vec3_t    verts[64];
  149.   int     numverts;
  150.   int     i;
  151.   int     lindex;
  152.   float   *vec;
  153.   texture_t *t;
  154.  
  155.   warpface = fa;
  156.  
  157.   //
  158.   // convert edges back to a normal polygon
  159.   //
  160.   numverts = 0;
  161.   for (i=0 ; i<fa->numedges ; i++)
  162.   {
  163.     lindex = loadmodel->surfedges[fa->firstedge + i];
  164.  
  165.     if (lindex > 0)
  166.       vec = loadmodel->vertexes[loadmodel->edges[lindex].v[0]].position;
  167.     else
  168.       vec = loadmodel->vertexes[loadmodel->edges[-lindex].v[1]].position;
  169.     VectorCopy (vec, verts[numverts]);
  170.     numverts++;
  171.   }
  172.  
  173.   SubdividePolygon (numverts, verts[0]);
  174. }
  175.  
  176. //=========================================================
  177.  
  178.  
  179.  
  180. // speed up sin calculations - Ed
  181. float turbsin[] =
  182. {
  183.   #include "gl_warp_sin.h"
  184. };
  185. #define TURBSCALE (256.0 / (2 * M_PI))
  186.  
  187. /*
  188. =============
  189. EmitWaterPolys
  190.  
  191. Does a water warp on the pre-fragmented glpoly_t chain
  192. =============
  193. */
  194. void EmitWaterPolys (msurface_t *fa)
  195. {
  196.   glpoly_t  *p;
  197.   float   *v;
  198.   int     i;
  199.   float   s, t, os, ot;
  200.  
  201.  
  202.   for (p=fa->polys ; p ; p=p->next)
  203.   {
  204.     glBegin (GL_POLYGON);
  205.     for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
  206.     {
  207.       os = v[3];
  208.       ot = v[4];
  209.  
  210.       s = os + turbsin[(int)((ot*0.125+realtime) * TURBSCALE) & 255];
  211.       s *= (1.0/64);
  212.  
  213.       t = ot + turbsin[(int)((os*0.125+realtime) * TURBSCALE) & 255];
  214.       t *= (1.0/64);
  215.  
  216.       glTexCoord2f (s, t);
  217.       glVertex3fv (v);
  218.     }
  219.     glEnd ();
  220.   }
  221. }
  222.  
  223.  
  224.  
  225.  
  226. /*
  227. =============
  228. EmitSkyPolys
  229. =============
  230. */
  231. void EmitSkyPolys (msurface_t *fa)
  232. {
  233.   glpoly_t  *p;
  234.   float   *v;
  235.   int     i;
  236.   float s, t;
  237.   vec3_t  dir;
  238.   float length;
  239.  
  240.   for (p=fa->polys ; p ; p=p->next)
  241.   {
  242.     glBegin (GL_POLYGON);
  243.     for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
  244.     {
  245.       VectorSubtract (v, r_origin, dir);
  246.       dir[2] *= 3;  // flatten the sphere
  247.  
  248.       length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2];
  249.       length = sqrt (length);
  250.       length = 6*63/length;
  251.  
  252.       dir[0] *= length;
  253.       dir[1] *= length;
  254.  
  255.       s = (speedscale + dir[0]) * (1.0/128);
  256.       t = (speedscale + dir[1]) * (1.0/128);
  257.  
  258.       glTexCoord2f (s, t);
  259.       glVertex3fv (v);
  260.     }
  261.     glEnd ();
  262.   }
  263. }
  264.  
  265. /*
  266. ===============
  267. EmitBothSkyLayers
  268.  
  269. Does a sky warp on the pre-fragmented glpoly_t chain
  270. This will be called for brushmodels, the world
  271. will have them chained together.
  272. ===============
  273. */
  274. void EmitBothSkyLayers (msurface_t *fa)
  275. {
  276.   int     i;
  277.   int     lindex;
  278.   float   *vec;
  279.  
  280.   GL_DisableMultitexture();
  281.  
  282.   GL_Bind (solidskytexture);
  283.   speedscale = realtime*8;
  284.   speedscale -= (int)speedscale & ~127 ;
  285.  
  286.   EmitSkyPolys (fa);
  287.  
  288.   glEnable (GL_BLEND);
  289.   GL_Bind (alphaskytexture);
  290.   speedscale = realtime*16;
  291.   speedscale -= (int)speedscale & ~127 ;
  292.  
  293.   EmitSkyPolys (fa);
  294.  
  295.   glDisable (GL_BLEND);
  296. }
  297.  
  298. #ifndef QUAKE2
  299. /*
  300. =================
  301. R_DrawSkyChain
  302. =================
  303. */
  304. void R_DrawSkyChain (msurface_t *s)
  305. {
  306.   msurface_t  *fa;
  307.  
  308.   GL_DisableMultitexture();
  309.  
  310.   // used when gl_texsort is on
  311.   GL_Bind(solidskytexture);
  312.   speedscale = realtime*8;
  313.   speedscale -= (int)speedscale & ~127 ;
  314.  
  315.   for (fa=s ; fa ; fa=fa->texturechain)
  316.     EmitSkyPolys (fa);
  317.  
  318.   glEnable (GL_BLEND);
  319.   GL_Bind (alphaskytexture);
  320.   speedscale = realtime*16;
  321.   speedscale -= (int)speedscale & ~127 ;
  322.  
  323.   for (fa=s ; fa ; fa=fa->texturechain)
  324.     EmitSkyPolys (fa);
  325.  
  326.   glDisable (GL_BLEND);
  327. }
  328.  
  329. #endif
  330.  
  331. /*
  332. =================================================================
  333.  
  334.   Quake 2 environment sky
  335.  
  336. =================================================================
  337. */
  338.  
  339. #ifdef QUAKE2
  340.  
  341.  
  342. #define SKY_TEX   2000
  343.  
  344. /*
  345. =================================================================
  346.  
  347.   PCX Loading
  348.  
  349. =================================================================
  350. */
  351.  
  352. typedef struct
  353. {
  354.     char  manufacturer;
  355.     char  version;
  356.     char  encoding;
  357.     char  bits_per_pixel;
  358.     unsigned short  xmin,ymin,xmax,ymax;
  359.     unsigned short  hres,vres;
  360.     unsigned char palette[48];
  361.     char  reserved;
  362.     char  color_planes;
  363.     unsigned short  bytes_per_line;
  364.     unsigned short  palette_type;
  365.     char  filler[58];
  366.     unsigned  data;     // unbounded
  367. } pcx_t;
  368.  
  369. byte  *pcx_rgb;
  370.  
  371. /*
  372. ============
  373. LoadPCX
  374. ============
  375. */
  376. void LoadPCX (FILE *f)
  377. {
  378.   pcx_t *pcx, pcxbuf;
  379.   byte  palette[768];
  380.   byte  *pix;
  381.   int   x, y;
  382.   int   dataByte, runLength;
  383.   int   count;
  384.  
  385. //
  386. // parse the PCX file
  387. //
  388.   fread (&pcxbuf, 1, sizeof(pcxbuf), f);
  389.  
  390.   pcx = &pcxbuf;
  391.  
  392.   if (pcx->manufacturer != 0x0a
  393.     || pcx->version != 5
  394.     || pcx->encoding != 1
  395.     || pcx->bits_per_pixel != 8
  396.     || pcx->xmax >= 320
  397.     || pcx->ymax >= 256)
  398.   {
  399.     Con_Printf ("Bad pcx file\n");
  400.     return;
  401.   }
  402.  
  403.   // seek to palette
  404.   fseek (f, -768, SEEK_END);
  405.   fread (palette, 1, 768, f);
  406.  
  407.   fseek (f, sizeof(pcxbuf) - 4, SEEK_SET);
  408.  
  409.   count = (pcx->xmax+1) * (pcx->ymax+1);
  410.   pcx_rgb = malloc( count * 4);
  411.  
  412.   for (y=0 ; y<=pcx->ymax ; y++)
  413.   {
  414.     pix = pcx_rgb + 4*y*(pcx->xmax+1);
  415.     for (x=0 ; x<=pcx->ymax ; )
  416.     {
  417.       dataByte = fgetc(f);
  418.  
  419.       if((dataByte & 0xC0) == 0xC0)
  420.       {
  421.         runLength = dataByte & 0x3F;
  422.         dataByte = fgetc(f);
  423.       }
  424.       else
  425.         runLength = 1;
  426.  
  427.       while(runLength-- > 0)
  428.       {
  429.         pix[0] = palette[dataByte*3];
  430.         pix[1] = palette[dataByte*3+1];
  431.         pix[2] = palette[dataByte*3+2];
  432.         pix[3] = 255;
  433.         pix += 4;
  434.         x++;
  435.       }
  436.     }
  437.   }
  438. }
  439.  
  440. /*
  441. =========================================================
  442.  
  443. TARGA LOADING
  444.  
  445. =========================================================
  446. */
  447.  
  448. typedef struct _TargaHeader {
  449.   unsigned char   id_length, colormap_type, image_type;
  450.   unsigned short  colormap_index, colormap_length;
  451.   unsigned char colormap_size;
  452.   unsigned short  x_origin, y_origin, width, height;
  453.   unsigned char pixel_size, attributes;
  454. } TargaHeader;
  455.  
  456.  
  457. TargaHeader   targa_header;
  458. byte      *targa_rgba;
  459.  
  460. int fgetLittleShort (FILE *f)
  461. {
  462.   byte  b1, b2;
  463.  
  464.   b1 = fgetc(f);
  465.   b2 = fgetc(f);
  466.  
  467.   return (short)(b1 + b2*256);
  468. }
  469.  
  470. int fgetLittleLong (FILE *f)
  471. {
  472.   byte  b1, b2, b3, b4;
  473.  
  474.   b1 = fgetc(f);
  475.   b2 = fgetc(f);
  476.   b3 = fgetc(f);
  477.   b4 = fgetc(f);
  478.  
  479.   return b1 + (b2<<8) + (b3<<16) + (b4<<24);
  480. }
  481.  
  482.  
  483. /*
  484. =============
  485. LoadTGA
  486. =============
  487. */
  488. void LoadTGA (FILE *fin)
  489. {
  490.   int       columns, rows, numPixels;
  491.   byte      *pixbuf;
  492.   int       row, column;
  493.  
  494.   targa_header.id_length = fgetc(fin);
  495.   targa_header.colormap_type = fgetc(fin);
  496.   targa_header.image_type = fgetc(fin);
  497.   
  498.   targa_header.colormap_index = fgetLittleShort(fin);
  499.   targa_header.colormap_length = fgetLittleShort(fin);
  500.   targa_header.colormap_size = fgetc(fin);
  501.   targa_header.x_origin = fgetLittleShort(fin);
  502.   targa_header.y_origin = fgetLittleShort(fin);
  503.   targa_header.width = fgetLittleShort(fin);
  504.   targa_header.height = fgetLittleShort(fin);
  505.   targa_header.pixel_size = fgetc(fin);
  506.   targa_header.attributes = fgetc(fin);
  507.  
  508.   if (targa_header.image_type!=2 
  509.     && targa_header.image_type!=10) 
  510.     Sys_Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n");
  511.  
  512.   if (targa_header.colormap_type !=0 
  513.     || (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
  514.     Sys_Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
  515.  
  516.   columns = targa_header.width;
  517.   rows = targa_header.height;
  518.   numPixels = columns * rows;
  519.  
  520.   targa_rgba = malloc (numPixels*4);
  521.   
  522.   if (targa_header.id_length != 0)
  523.     fseek(fin, targa_header.id_length, SEEK_CUR);  // skip TARGA image comment
  524.   
  525.   if (targa_header.image_type==2) {  // Uncompressed, RGB images
  526.     for(row=rows-1; row>=0; row--) {
  527.       pixbuf = targa_rgba + row*columns*4;
  528.       for(column=0; column<columns; column++) {
  529.         unsigned char red,green,blue,alphabyte;
  530.         switch (targa_header.pixel_size) {
  531.           case 24:
  532.               
  533.               blue = getc(fin);
  534.               green = getc(fin);
  535.               red = getc(fin);
  536.               *pixbuf++ = red;
  537.               *pixbuf++ = green;
  538.               *pixbuf++ = blue;
  539.               *pixbuf++ = 255;
  540.               break;
  541.           case 32:
  542.               blue = getc(fin);
  543.               green = getc(fin);
  544.               red = getc(fin);
  545.               alphabyte = getc(fin);
  546.               *pixbuf++ = red;
  547.               *pixbuf++ = green;
  548.               *pixbuf++ = blue;
  549.               *pixbuf++ = alphabyte;
  550.               break;
  551.         }
  552.       }
  553.     }
  554.   }
  555.   else if (targa_header.image_type==10) {   // Runlength encoded RGB images
  556.     unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
  557.     for(row=rows-1; row>=0; row--) {
  558.       pixbuf = targa_rgba + row*columns*4;
  559.       for(column=0; column<columns; ) {
  560.         packetHeader=getc(fin);
  561.         packetSize = 1 + (packetHeader & 0x7f);
  562.         if (packetHeader & 0x80) {        // run-length packet
  563.           switch (targa_header.pixel_size) {
  564.             case 24:
  565.                 blue = getc(fin);
  566.                 green = getc(fin);
  567.                 red = getc(fin);
  568.                 alphabyte = 255;
  569.                 break;
  570.             case 32:
  571.                 blue = getc(fin);
  572.                 green = getc(fin);
  573.                 red = getc(fin);
  574.                 alphabyte = getc(fin);
  575.                 break;
  576.           }
  577.   
  578.           for(j=0;j<packetSize;j++) {
  579.             *pixbuf++=red;
  580.             *pixbuf++=green;
  581.             *pixbuf++=blue;
  582.             *pixbuf++=alphabyte;
  583.             column++;
  584.             if (column==columns) { // run spans across rows
  585.               column=0;
  586.               if (row>0)
  587.                 row--;
  588.               else
  589.                 goto breakOut;
  590.               pixbuf = targa_rgba + row*columns*4;
  591.             }
  592.           }
  593.         }
  594.         else {                            // non run-length packet
  595.           for(j=0;j<packetSize;j++) {
  596.             switch (targa_header.pixel_size) {
  597.               case 24:
  598.                   blue = getc(fin);
  599.                   green = getc(fin);
  600.                   red = getc(fin);
  601.                   *pixbuf++ = red;
  602.                   *pixbuf++ = green;
  603.                   *pixbuf++ = blue;
  604.                   *pixbuf++ = 255;
  605.                   break;
  606.               case 32:
  607.                   blue = getc(fin);
  608.                   green = getc(fin);
  609.                   red = getc(fin);
  610.                   alphabyte = getc(fin);
  611.                   *pixbuf++ = red;
  612.                   *pixbuf++ = green;
  613.                   *pixbuf++ = blue;
  614.                   *pixbuf++ = alphabyte;
  615.                   break;
  616.             }
  617.             column++;
  618.             if (column==columns) { // pixel packet run spans across rows
  619.               column=0;
  620.               if (row>0)
  621.                 row--;
  622.               else
  623.                 goto breakOut;
  624.               pixbuf = targa_rgba + row*columns*4;
  625.             }           
  626.           }
  627.         }
  628.       }
  629.       breakOut:;
  630.     }
  631.   }
  632.   
  633.   fclose(fin);
  634. }
  635.  
  636. /*
  637. ==================
  638. R_LoadSkys
  639. ==================
  640. */
  641. char  *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
  642. void R_LoadSkys (void)
  643. {
  644.   int   i;
  645.   FILE  *f;
  646.   char  name[64];
  647.  
  648.   for (i=0 ; i<6 ; i++)
  649.   {
  650.     GL_Bind (SKY_TEX + i);
  651.     sprintf (name, "gfx/env/bkgtst%s.tga", suf[i]);
  652.     COM_FOpenFile (name, &f);
  653.     if (!f)
  654.     {
  655.       Con_Printf ("Couldn't load %s\n", name);
  656.       continue;
  657.     }
  658.     LoadTGA (f);
  659. //    LoadPCX (f);
  660.  
  661.     glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, targa_rgba);
  662. //    glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pcx_rgb);
  663.  
  664.     free (targa_rgba);
  665. //    free (pcx_rgb);
  666.  
  667.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  668.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  669.   }
  670. }
  671.  
  672.  
  673. vec3_t  skyclip[6] = {
  674.   {1,1,0},
  675.   {1,-1,0},
  676.   {0,-1,1},
  677.   {0,1,1},
  678.   {1,0,1},
  679.   {-1,0,1} 
  680. };
  681. int c_sky;
  682.  
  683. // 1 = s, 2 = t, 3 = 2048
  684. int st_to_vec[6][3] =
  685. {
  686.   {3,-1,2},
  687.   {-3,1,2},
  688.  
  689.   {1,3,2},
  690.   {-1,-3,2},
  691.  
  692.   {-2,-1,3},    // 0 degrees yaw, look straight up
  693.   {2,-1,-3}   // look straight down
  694.  
  695. //  {-1,2,3},
  696. //  {1,2,-3}
  697. };
  698.  
  699. // s = [0]/[2], t = [1]/[2]
  700. int vec_to_st[6][3] =
  701. {
  702.   {-2,3,1},
  703.   {2,3,-1},
  704.  
  705.   {1,3,2},
  706.   {-1,3,-2},
  707.  
  708.   {-2,-1,3},
  709.   {-2,1,-3}
  710.  
  711. //  {-1,2,3},
  712. //  {1,2,-3}
  713. };
  714.  
  715. float skymins[2][6], skymaxs[2][6];
  716.  
  717. void DrawSkyPolygon (int nump, vec3_t vecs)
  718. {
  719.   int   i,j;
  720.   vec3_t  v, av;
  721.   float s, t, dv;
  722.   int   axis;
  723.   float *vp;
  724.  
  725.   c_sky++;
  726. #if 0
  727. glBegin (GL_POLYGON);
  728. for (i=0 ; i<nump ; i++, vecs+=3)
  729. {
  730.   VectorAdd(vecs, r_origin, v);
  731.   glVertex3fv (v);
  732. }
  733. glEnd();
  734. return;
  735. #endif
  736.   // decide which face it maps to
  737.   VectorCopy (vec3_origin, v);
  738.   for (i=0, vp=vecs ; i<nump ; i++, vp+=3)
  739.   {
  740.     VectorAdd (vp, v, v);
  741.   }
  742.   av[0] = fabs(v[0]);
  743.   av[1] = fabs(v[1]);
  744.   av[2] = fabs(v[2]);
  745.   if (av[0] > av[1] && av[0] > av[2])
  746.   {
  747.     if (v[0] < 0)
  748.       axis = 1;
  749.     else
  750.       axis = 0;
  751.   }
  752.   else if (av[1] > av[2] && av[1] > av[0])
  753.   {
  754.     if (v[1] < 0)
  755.       axis = 3;
  756.     else
  757.       axis = 2;
  758.   }
  759.   else
  760.   {
  761.     if (v[2] < 0)
  762.       axis = 5;
  763.     else
  764.       axis = 4;
  765.   }
  766.  
  767.   // project new texture coords
  768.   for (i=0 ; i<nump ; i++, vecs+=3)
  769.   {
  770.     j = vec_to_st[axis][2];
  771.     if (j > 0)
  772.       dv = vecs[j - 1];
  773.     else
  774.       dv = -vecs[-j - 1];
  775.  
  776.     j = vec_to_st[axis][0];
  777.     if (j < 0)
  778.       s = -vecs[-j -1] / dv;
  779.     else
  780.       s = vecs[j-1] / dv;
  781.     j = vec_to_st[axis][1];
  782.     if (j < 0)
  783.       t = -vecs[-j -1] / dv;
  784.     else
  785.       t = vecs[j-1] / dv;
  786.  
  787.     if (s < skymins[0][axis])
  788.       skymins[0][axis] = s;
  789.     if (t < skymins[1][axis])
  790.       skymins[1][axis] = t;
  791.     if (s > skymaxs[0][axis])
  792.       skymaxs[0][axis] = s;
  793.     if (t > skymaxs[1][axis])
  794.       skymaxs[1][axis] = t;
  795.   }
  796. }
  797.  
  798. #define MAX_CLIP_VERTS  64
  799. void ClipSkyPolygon (int nump, vec3_t vecs, int stage)
  800. {
  801.   float *norm;
  802.   float *v;
  803.   qboolean  front, back;
  804.   float d, e;
  805.   float dists[MAX_CLIP_VERTS];
  806.   int   sides[MAX_CLIP_VERTS];
  807.   vec3_t  newv[2][MAX_CLIP_VERTS];
  808.   int   newc[2];
  809.   int   i, j;
  810.  
  811.   if (nump > MAX_CLIP_VERTS-2)
  812.     Sys_Error ("ClipSkyPolygon: MAX_CLIP_VERTS");
  813.   if (stage == 6)
  814.   { // fully clipped, so draw it
  815.     DrawSkyPolygon (nump, vecs);
  816.     return;
  817.   }
  818.  
  819.   front = back = false;
  820.   norm = skyclip[stage];
  821.   for (i=0, v = vecs ; i<nump ; i++, v+=3)
  822.   {
  823.     d = DotProduct (v, norm);
  824.     if (d > ON_EPSILON)
  825.     {
  826.       front = true;
  827.       sides[i] = SIDE_FRONT;
  828.     }
  829.     else if (d < ON_EPSILON)
  830.     {
  831.       back = true;
  832.       sides[i] = SIDE_BACK;
  833.     }
  834.     else
  835.       sides[i] = SIDE_ON;
  836.     dists[i] = d;
  837.   }
  838.  
  839.   if (!front || !back)
  840.   { // not clipped
  841.     ClipSkyPolygon (nump, vecs, stage+1);
  842.     return;
  843.   }
  844.  
  845.   // clip it
  846.   sides[i] = sides[0];
  847.   dists[i] = dists[0];
  848.   VectorCopy (vecs, (vecs+(i*3)) );
  849.   newc[0] = newc[1] = 0;
  850.  
  851.   for (i=0, v = vecs ; i<nump ; i++, v+=3)
  852.   {
  853.     switch (sides[i])
  854.     {
  855.     case SIDE_FRONT:
  856.       VectorCopy (v, newv[0][newc[0]]);
  857.       newc[0]++;
  858.       break;
  859.     case SIDE_BACK:
  860.       VectorCopy (v, newv[1][newc[1]]);
  861.       newc[1]++;
  862.       break;
  863.     case SIDE_ON:
  864.       VectorCopy (v, newv[0][newc[0]]);
  865.       newc[0]++;
  866.       VectorCopy (v, newv[1][newc[1]]);
  867.       newc[1]++;
  868.       break;
  869.     }
  870.  
  871.     if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
  872.       continue;
  873.  
  874.     d = dists[i] / (dists[i] - dists[i+1]);
  875.     for (j=0 ; j<3 ; j++)
  876.     {
  877.       e = v[j] + d*(v[j+3] - v[j]);
  878.       newv[0][newc[0]][j] = e;
  879.       newv[1][newc[1]][j] = e;
  880.     }
  881.     newc[0]++;
  882.     newc[1]++;
  883.   }
  884.  
  885.   // continue
  886.   ClipSkyPolygon (newc[0], newv[0][0], stage+1);
  887.   ClipSkyPolygon (newc[1], newv[1][0], stage+1);
  888. }
  889.  
  890. /*
  891. =================
  892. R_DrawSkyChain
  893. =================
  894. */
  895. void R_DrawSkyChain (msurface_t *s)
  896. {
  897.   msurface_t  *fa;
  898.  
  899.   int   i;
  900.   vec3_t  verts[MAX_CLIP_VERTS];
  901.   glpoly_t  *p;
  902.  
  903.   c_sky = 0;
  904.   GL_Bind(solidskytexture);
  905.  
  906.   // calculate vertex values for sky box
  907.  
  908.   for (fa=s ; fa ; fa=fa->texturechain)
  909.   {
  910.     for (p=fa->polys ; p ; p=p->next)
  911.     {
  912.       for (i=0 ; i<p->numverts ; i++)
  913.       {
  914.         VectorSubtract (p->verts[i], r_origin, verts[i]);
  915.       }
  916.       ClipSkyPolygon (p->numverts, verts[0], 0);
  917.     }
  918.   }
  919. }
  920.  
  921.  
  922. /*
  923. ==============
  924. R_ClearSkyBox
  925. ==============
  926. */
  927. void R_ClearSkyBox (void)
  928. {
  929.   int   i;
  930.  
  931.   for (i=0 ; i<6 ; i++)
  932.   {
  933.     skymins[0][i] = skymins[1][i] = 9999;
  934.     skymaxs[0][i] = skymaxs[1][i] = -9999;
  935.   }
  936. }
  937.  
  938.  
  939. void MakeSkyVec (float s, float t, int axis)
  940. {
  941.   vec3_t    v, b;
  942.   int     j, k;
  943.  
  944.   b[0] = s*2048;
  945.   b[1] = t*2048;
  946.   b[2] = 2048;
  947.  
  948.   for (j=0 ; j<3 ; j++)
  949.   {
  950.     k = st_to_vec[axis][j];
  951.     if (k < 0)
  952.       v[j] = -b[-k - 1];
  953.     else
  954.       v[j] = b[k - 1];
  955.     v[j] += r_origin[j];
  956.   }
  957.  
  958.   // avoid bilerp seam
  959.   s = (s+1)*0.5;
  960.   t = (t+1)*0.5;
  961.  
  962.   if (s < 1.0/512)
  963.     s = 1.0/512;
  964.   else if (s > 511.0/512)
  965.     s = 511.0/512;
  966.   if (t < 1.0/512)
  967.     t = 1.0/512;
  968.   else if (t > 511.0/512)
  969.     t = 511.0/512;
  970.  
  971.   t = 1.0 - t;
  972.   glTexCoord2f (s, t);
  973.   glVertex3fv (v);
  974. }
  975.  
  976. /*
  977. ==============
  978. R_DrawSkyBox
  979. ==============
  980. */
  981. int skytexorder[6] = {0,2,1,3,4,5};
  982. void R_DrawSkyBox (void)
  983. {
  984.   int   i, j, k;
  985.   vec3_t  v;
  986.   float s, t;
  987.  
  988. #if 0
  989. glEnable (GL_BLEND);
  990. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  991. glColor4f (1,1,1,0.5);
  992. glDisable (GL_DEPTH_TEST);
  993. #endif
  994.   for (i=0 ; i<6 ; i++)
  995.   {
  996.     if (skymins[0][i] >= skymaxs[0][i]
  997.     || skymins[1][i] >= skymaxs[1][i])
  998.       continue;
  999.  
  1000.     GL_Bind (SKY_TEX+skytexorder[i]);
  1001. #if 0
  1002. skymins[0][i] = -1;
  1003. skymins[1][i] = -1;
  1004. skymaxs[0][i] = 1;
  1005. skymaxs[1][i] = 1;
  1006. #endif
  1007.     glBegin (GL_QUADS);
  1008.     MakeSkyVec (skymins[0][i], skymins[1][i], i);
  1009.     MakeSkyVec (skymins[0][i], skymaxs[1][i], i);
  1010.     MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i);
  1011.     MakeSkyVec (skymaxs[0][i], skymins[1][i], i);
  1012.     glEnd ();
  1013.   }
  1014. #if 0
  1015. glDisable (GL_BLEND);
  1016. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  1017. glColor4f (1,1,1,0.5);
  1018. glEnable (GL_DEPTH_TEST);
  1019. #endif
  1020. }
  1021.  
  1022.  
  1023. #endif
  1024.  
  1025. //===============================================================
  1026.  
  1027. /*
  1028. =============
  1029. R_InitSky
  1030.  
  1031. A sky texture is 256*128, with the right side being a masked overlay
  1032. ==============
  1033. */
  1034. void R_InitSky (texture_t *mt)
  1035. {
  1036.   int     i, j, p;
  1037.   byte    *src;
  1038.   unsigned  trans[128*128];
  1039.   unsigned  transpix;
  1040.   int     r, g, b;
  1041.   unsigned  *rgba;
  1042.   extern  int     skytexturenum;
  1043.  
  1044.   src = (byte *)mt + mt->offsets[0];
  1045.  
  1046.   // make an average value for the back to avoid
  1047.   // a fringe on the top level
  1048.  
  1049.   r = g = b = 0;
  1050.   for (i=0 ; i<128 ; i++)
  1051.     for (j=0 ; j<128 ; j++)
  1052.     {
  1053.       p = src[i*256 + j + 128];
  1054.       rgba = &d_8to24table[p];
  1055.       trans[(i*128) + j] = *rgba;
  1056.       r += ((byte *)rgba)[0];
  1057.       g += ((byte *)rgba)[1];
  1058.       b += ((byte *)rgba)[2];
  1059.     }
  1060.  
  1061.   ((byte *)&transpix)[0] = r/(128*128);
  1062.   ((byte *)&transpix)[1] = g/(128*128);
  1063.   ((byte *)&transpix)[2] = b/(128*128);
  1064.   ((byte *)&transpix)[3] = 0;
  1065.  
  1066.  
  1067.   if (!solidskytexture)
  1068.     solidskytexture = texture_extension_number++;
  1069.   GL_Bind (solidskytexture );
  1070.   glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
  1071.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1072.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1073.  
  1074.  
  1075.   for (i=0 ; i<128 ; i++)
  1076.     for (j=0 ; j<128 ; j++)
  1077.     {
  1078.       p = src[i*256 + j];
  1079.       if (p == 0)
  1080.         trans[(i*128) + j] = transpix;
  1081.       else
  1082.         trans[(i*128) + j] = d_8to24table[p];
  1083.     }
  1084.  
  1085.   if (!alphaskytexture)
  1086.     alphaskytexture = texture_extension_number++;
  1087.   GL_Bind(alphaskytexture);
  1088.   glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
  1089.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1090.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1091. }
  1092.  
  1093.