Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.