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