home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 14 / MA_Cover_14.iso / source / c / q1source_amy / qw / client / gl_rsurf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-21  |  34.9 KB  |  1,698 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. // r_surf.c: surface-related refresh code
  21.  
  22. #include "quakedef.h"
  23.  
  24. int            skytexturenum;
  25.  
  26. #ifndef GL_RGBA4
  27. #define    GL_RGBA4    0
  28. #endif
  29.  
  30.  
  31. int        lightmap_bytes;        // 1, 2, or 4
  32.  
  33. int        lightmap_textures;
  34.  
  35. unsigned        blocklights[18*18];
  36.  
  37. #define    BLOCK_WIDTH        128
  38. #define    BLOCK_HEIGHT    128
  39.  
  40. #define    MAX_LIGHTMAPS    64
  41. int            active_lightmaps;
  42.  
  43. typedef struct glRect_s {
  44.     unsigned char l,t,w,h;
  45. } glRect_t;
  46.  
  47. glpoly_t    *lightmap_polys[MAX_LIGHTMAPS];
  48. qboolean    lightmap_modified[MAX_LIGHTMAPS];
  49. glRect_t    lightmap_rectchange[MAX_LIGHTMAPS];
  50.  
  51. int            allocated[MAX_LIGHTMAPS][BLOCK_WIDTH];
  52.  
  53. // the lightmap texture data needs to be kept in
  54. // main memory so texsubimage can update properly
  55. byte        lightmaps[4*MAX_LIGHTMAPS*BLOCK_WIDTH*BLOCK_HEIGHT];
  56.  
  57. // For gl_texsort 0
  58. msurface_t  *skychain = NULL;
  59. msurface_t  *waterchain = NULL;
  60.  
  61. void R_RenderDynamicLightmaps (msurface_t *fa);
  62.  
  63. /*
  64. ===============
  65. R_AddDynamicLights
  66. ===============
  67. */
  68. void R_AddDynamicLights (msurface_t *surf)
  69. {
  70.     int            lnum;
  71.     int            sd, td;
  72.     float        dist, rad, minlight;
  73.     vec3_t        impact, local;
  74.     int            s, t;
  75.     int            i;
  76.     int            smax, tmax;
  77.     mtexinfo_t    *tex;
  78.  
  79.     smax = (surf->extents[0]>>4)+1;
  80.     tmax = (surf->extents[1]>>4)+1;
  81.     tex = surf->texinfo;
  82.  
  83.     for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
  84.     {
  85.         if ( !(surf->dlightbits & (1<<lnum) ) )
  86.             continue;        // not lit by this light
  87.  
  88.         rad = cl_dlights[lnum].radius;
  89.         dist = DotProduct (cl_dlights[lnum].origin, surf->plane->normal) -
  90.                 surf->plane->dist;
  91.         rad -= fabs(dist);
  92.         minlight = cl_dlights[lnum].minlight;
  93.         if (rad < minlight)
  94.             continue;
  95.         minlight = rad - minlight;
  96.  
  97.         for (i=0 ; i<3 ; i++)
  98.         {
  99.             impact[i] = cl_dlights[lnum].origin[i] -
  100.                     surf->plane->normal[i]*dist;
  101.         }
  102.  
  103.         local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3];
  104.         local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3];
  105.  
  106.         local[0] -= surf->texturemins[0];
  107.         local[1] -= surf->texturemins[1];
  108.         
  109.         for (t = 0 ; t<tmax ; t++)
  110.         {
  111.             td = local[1] - t*16;
  112.             if (td < 0)
  113.                 td = -td;
  114.             for (s=0 ; s<smax ; s++)
  115.             {
  116.                 sd = local[0] - s*16;
  117.                 if (sd < 0)
  118.                     sd = -sd;
  119.                 if (sd > td)
  120.                     dist = sd + (td>>1);
  121.                 else
  122.                     dist = td + (sd>>1);
  123.                 if (dist < minlight)
  124.                     blocklights[t*smax + s] += (rad - dist)*256;
  125.             }
  126.         }
  127.     }
  128. }
  129.  
  130.  
  131. /*
  132. ===============
  133. R_BuildLightMap
  134.  
  135. Combine and scale multiple lightmaps into the 8.8 format in blocklights
  136. ===============
  137. */
  138. void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
  139. {
  140.     int            smax, tmax;
  141.     int            t;
  142.     int            i, j, size;
  143.     byte        *lightmap;
  144.     unsigned    scale;
  145.     int            maps;
  146.     unsigned    *bl;
  147.  
  148.     surf->cached_dlight = (surf->dlightframe == r_framecount);
  149.  
  150.     smax = (surf->extents[0]>>4)+1;
  151.     tmax = (surf->extents[1]>>4)+1;
  152.     size = smax*tmax;
  153.     lightmap = surf->samples;
  154.  
  155. // set to full bright if no light data
  156.     if (/* r_fullbright.value || */ !cl.worldmodel->lightdata)
  157.     {
  158.         for (i=0 ; i<size ; i++)
  159.             blocklights[i] = 255*256;
  160.         goto store;
  161.     }
  162.  
  163. // clear to no light
  164.     for (i=0 ; i<size ; i++)
  165.         blocklights[i] = 0;
  166.  
  167. // add all the lightmaps
  168.     if (lightmap)
  169.         for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
  170.              maps++)
  171.         {
  172.             scale = d_lightstylevalue[surf->styles[maps]];
  173.             surf->cached_light[maps] = scale;    // 8.8 fraction
  174.             for (i=0 ; i<size ; i++)
  175.                 blocklights[i] += lightmap[i] * scale;
  176.             lightmap += size;    // skip to next lightmap
  177.         }
  178.  
  179. // add all the dynamic lights
  180.     if (surf->dlightframe == r_framecount)
  181.         R_AddDynamicLights (surf);
  182.  
  183. // bound, invert, and shift
  184. store:
  185.     switch (gl_lightmap_format)
  186.     {
  187.     case GL_RGBA:
  188.         stride -= (smax<<2);
  189.         bl = blocklights;
  190.         for (i=0 ; i<tmax ; i++, dest += stride)
  191.         {
  192.             for (j=0 ; j<smax ; j++)
  193.             {
  194.                 t = *bl++;
  195.                 t >>= 7;
  196.                 if (t > 255)
  197.                     t = 255;
  198.                 dest[3] = 255-t;
  199.                 dest += 4;
  200.             }
  201.         }
  202.         break;
  203.     case GL_ALPHA:
  204.     case GL_LUMINANCE:
  205.     case GL_INTENSITY:
  206.         bl = blocklights;
  207.         for (i=0 ; i<tmax ; i++, dest += stride)
  208.         {
  209.             for (j=0 ; j<smax ; j++)
  210.             {
  211.                 t = *bl++;
  212.                 t >>= 7;
  213.                 if (t > 255)
  214.                     t = 255;
  215.                 dest[j] = 255-t;
  216.             }
  217.         }
  218.         break;
  219.     default:
  220.         Sys_Error ("Bad lightmap format");
  221.     }
  222. }
  223.  
  224.  
  225. /*
  226. ===============
  227. R_TextureAnimation
  228.  
  229. Returns the proper texture for a given time and base texture
  230. ===============
  231. */
  232. texture_t *R_TextureAnimation (texture_t *base)
  233. {
  234.     int        reletive;
  235.     int        count;
  236.  
  237.     if (currententity->frame)
  238.     {
  239.         if (base->alternate_anims)
  240.             base = base->alternate_anims;
  241.     }
  242.     
  243.     if (!base->anim_total)
  244.         return base;
  245.  
  246.     reletive = (int)(cl.time*10) % base->anim_total;
  247.  
  248.     count = 0;    
  249.     while (base->anim_min > reletive || base->anim_max <= reletive)
  250.     {
  251.         base = base->anim_next;
  252.         if (!base)
  253.             Sys_Error ("R_TextureAnimation: broken cycle");
  254.         if (++count > 100)
  255.             Sys_Error ("R_TextureAnimation: infinite cycle");
  256.     }
  257.  
  258.     return base;
  259. }
  260.  
  261.  
  262. /*
  263. =============================================================
  264.  
  265.     BRUSH MODELS
  266.  
  267. =============================================================
  268. */
  269.  
  270.  
  271. extern    int        solidskytexture;
  272. extern    int        alphaskytexture;
  273. extern    float    speedscale;        // for top sky and bottom sky
  274.  
  275. void DrawGLWaterPoly (glpoly_t *p);
  276. void DrawGLWaterPolyLightmap (glpoly_t *p);
  277.  
  278. #ifdef _WIN32
  279. lpMTexFUNC qglMTexCoord2fSGIS = NULL;
  280. lpSelTexFUNC qglSelectTextureSGIS = NULL;
  281. #endif
  282.  
  283. qboolean mtexenabled = false;
  284.  
  285. void GL_SelectTexture (GLenum target);
  286.  
  287. void GL_DisableMultitexture(void) 
  288. {
  289.     if (mtexenabled) {
  290.         glDisable(GL_TEXTURE_2D);
  291.         GL_SelectTexture(TEXTURE0_SGIS);
  292.         mtexenabled = false;
  293.     }
  294. }
  295.  
  296. void GL_EnableMultitexture(void) 
  297. {
  298.     if (gl_mtexable) {
  299.         GL_SelectTexture(TEXTURE1_SGIS);
  300.         glEnable(GL_TEXTURE_2D);
  301.         mtexenabled = true;
  302.     }
  303. }
  304.  
  305. #ifndef _WIN32
  306. /*
  307. ================
  308. R_DrawSequentialPoly
  309.  
  310. Systems that have fast state and texture changes can
  311. just do everything as it passes with no need to sort
  312. ================
  313. */
  314. void R_DrawSequentialPoly (msurface_t *s)
  315. {
  316.     glpoly_t    *p;
  317.     float        *v;
  318.     int            i;
  319.     texture_t    *t;
  320.  
  321.     //
  322.     // normal lightmaped poly
  323.     //
  324. //    if ((!(s->flags & (SURF_DRAWSKY|SURF_DRAWTURB)))
  325. //        && ((r_viewleaf->contents!=CONTENTS_EMPTY && (s->flags & SURF_UNDERWATER)) ||
  326. //        (r_viewleaf->contents==CONTENTS_EMPTY && !(s->flags & SURF_UNDERWATER))))
  327.     if (0)
  328.     {
  329.         p = s->polys;
  330.  
  331.         t = R_TextureAnimation (s->texinfo->texture);
  332.         GL_Bind (t->gl_texturenum);
  333.         glBegin (GL_POLYGON);
  334.         v = p->verts[0];
  335.         for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
  336.         {
  337.             glTexCoord2f (v[3], v[4]);
  338.             glVertex3fv (v);
  339.         }
  340.         glEnd ();
  341.  
  342.         GL_Bind (lightmap_textures + s->lightmaptexturenum);
  343.         glEnable (GL_BLEND);
  344.         glBegin (GL_POLYGON);
  345.         v = p->verts[0];
  346.         for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
  347.         {
  348.             glTexCoord2f (v[5], v[6]);
  349.             glVertex3fv (v);
  350.         }
  351.         glEnd ();
  352.  
  353.         glDisable (GL_BLEND);
  354.  
  355.         return;
  356.     }
  357.  
  358.     //
  359.     // subdivided water surface warp
  360.     //
  361.     if (s->flags & SURF_DRAWTURB)
  362.     {
  363.         GL_Bind (s->texinfo->texture->gl_texturenum);
  364.         EmitWaterPolys (s);
  365.         return;
  366.     }
  367.  
  368.     //
  369.     // subdivided sky warp
  370.     //
  371.     if (s->flags & SURF_DRAWSKY)
  372.     {
  373.         GL_Bind (solidskytexture);
  374.         speedscale = realtime*8;
  375.         speedscale -= (int)speedscale;
  376.  
  377.         EmitSkyPolys (s);
  378.  
  379.         glEnable (GL_BLEND);
  380.         glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  381.         GL_Bind (alphaskytexture);
  382.         speedscale = realtime*16;
  383.         speedscale -= (int)speedscale;
  384.         EmitSkyPolys (s);
  385.         if (gl_lightmap_format == GL_LUMINANCE)
  386.             glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
  387.  
  388.         glDisable (GL_BLEND);
  389.     }
  390.  
  391.     //
  392.     // underwater warped with lightmap
  393.     //
  394.     p = s->polys;
  395.  
  396.     t = R_TextureAnimation (s->texinfo->texture);
  397.     GL_Bind (t->gl_texturenum);
  398.     DrawGLWaterPoly (p);
  399.  
  400.     GL_Bind (lightmap_textures + s->lightmaptexturenum);
  401.     glEnable (GL_BLEND);
  402.     DrawGLWaterPolyLightmap (p);
  403.     glDisable (GL_BLEND);
  404. }
  405. #else
  406. /*
  407. ================
  408. R_DrawSequentialPoly
  409.  
  410. Systems that have fast state and texture changes can
  411. just do everything as it passes with no need to sort
  412. ================
  413. */
  414. void R_DrawSequentialPoly (msurface_t *s)
  415. {
  416.     glpoly_t    *p;
  417.     float        *v;
  418.     int            i;
  419.     texture_t    *t;
  420.     vec3_t        nv, dir;
  421.     float        ss, ss2, length;
  422.     float        s1, t1;
  423.     glRect_t    *theRect;
  424.  
  425.     //
  426.     // normal lightmaped poly
  427.     //
  428.  
  429.     if (! (s->flags & (SURF_DRAWSKY|SURF_DRAWTURB|SURF_UNDERWATER) ) )
  430.     {
  431.         R_RenderDynamicLightmaps (s);
  432.         if (gl_mtexable) {
  433.             p = s->polys;
  434.  
  435.             t = R_TextureAnimation (s->texinfo->texture);
  436.             // Binds world to texture env 0
  437.             GL_SelectTexture(TEXTURE0_SGIS);
  438.             GL_Bind (t->gl_texturenum);
  439.             glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  440.             // Binds lightmap to texenv 1
  441.             GL_EnableMultitexture(); // Same as SelectTexture (TEXTURE1)
  442.             GL_Bind (lightmap_textures + s->lightmaptexturenum);
  443.             i = s->lightmaptexturenum;
  444.             if (lightmap_modified[i])
  445.             {
  446.                 lightmap_modified[i] = false;
  447.                 theRect = &lightmap_rectchange[i];
  448.                 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t, 
  449.                     BLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE,
  450.                     lightmaps+(i* BLOCK_HEIGHT + theRect->t) *BLOCK_WIDTH*lightmap_bytes);
  451.                 theRect->l = BLOCK_WIDTH;
  452.                 theRect->t = BLOCK_HEIGHT;
  453.                 theRect->h = 0;
  454.                 theRect->w = 0;
  455.             }
  456.             glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
  457.             glBegin(GL_POLYGON);
  458.             v = p->verts[0];
  459.             for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
  460.             {
  461.                 qglMTexCoord2fSGIS (TEXTURE0_SGIS, v[3], v[4]);
  462.                 qglMTexCoord2fSGIS (TEXTURE1_SGIS, v[5], v[6]);
  463.                 glVertex3fv (v);
  464.             }
  465.             glEnd ();
  466.             return;
  467.         } else {
  468.             p = s->polys;
  469.  
  470.             t = R_TextureAnimation (s->texinfo->texture);
  471.             GL_Bind (t->gl_texturenum);
  472.             glBegin (GL_POLYGON);
  473.             v = p->verts[0];
  474.             for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
  475.             {
  476.                 glTexCoord2f (v[3], v[4]);
  477.                 glVertex3fv (v);
  478.             }
  479.             glEnd ();
  480.  
  481.             GL_Bind (lightmap_textures + s->lightmaptexturenum);
  482.             glEnable (GL_BLEND);
  483.             glBegin (GL_POLYGON);
  484.             v = p->verts[0];
  485.             for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
  486.             {
  487.                 glTexCoord2f (v[5], v[6]);
  488.                 glVertex3fv (v);
  489.             }
  490.             glEnd ();
  491.  
  492.             glDisable (GL_BLEND);
  493.         }
  494.  
  495.         return;
  496.     }
  497.  
  498.     //
  499.     // subdivided water surface warp
  500.     //
  501.  
  502.     if (s->flags & SURF_DRAWTURB)
  503.     {
  504.         GL_DisableMultitexture();
  505.         GL_Bind (s->texinfo->texture->gl_texturenum);
  506.         EmitWaterPolys (s);
  507.         return;
  508.     }
  509.  
  510.     //
  511.     // subdivided sky warp
  512.     //
  513.     if (s->flags & SURF_DRAWSKY)
  514.     {
  515.         GL_DisableMultitexture();
  516.         GL_Bind (solidskytexture);
  517.         speedscale = realtime*8;
  518.         speedscale -= (int)speedscale & ~127;
  519.  
  520.         EmitSkyPolys (s);
  521.  
  522.         glEnable (GL_BLEND);
  523.         GL_Bind (alphaskytexture);
  524.         speedscale = realtime*16;
  525.         speedscale -= (int)speedscale & ~127;
  526.         EmitSkyPolys (s);
  527.  
  528.         glDisable (GL_BLEND);
  529.         return;
  530.     }
  531.  
  532.     //
  533.     // underwater warped with lightmap
  534.     //
  535.     R_RenderDynamicLightmaps (s);
  536.     if (gl_mtexable) {
  537.         p = s->polys;
  538.  
  539.         t = R_TextureAnimation (s->texinfo->texture);
  540.         GL_SelectTexture(TEXTURE0_SGIS);
  541.         GL_Bind (t->gl_texturenum);
  542.         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  543.         GL_EnableMultitexture();
  544.         GL_Bind (lightmap_textures + s->lightmaptexturenum);
  545.         i = s->lightmaptexturenum;
  546.         if (lightmap_modified[i])
  547.         {
  548.             lightmap_modified[i] = false;
  549.             theRect = &lightmap_rectchange[i];
  550.             glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t, 
  551.                 BLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE,
  552.                 lightmaps+(i* BLOCK_HEIGHT + theRect->t) *BLOCK_WIDTH*lightmap_bytes);
  553.             theRect->l = BLOCK_WIDTH;
  554.             theRect->t = BLOCK_HEIGHT;
  555.             theRect->h = 0;
  556.             theRect->w = 0;
  557.         }
  558.         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
  559.         glBegin (GL_TRIANGLE_FAN);
  560.         v = p->verts[0];
  561.         for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
  562.         {
  563.             qglMTexCoord2fSGIS (TEXTURE0_SGIS, v[3], v[4]);
  564.             qglMTexCoord2fSGIS (TEXTURE1_SGIS, v[5], v[6]);
  565.  
  566.             nv[0] = v[0] + 8*sin(v[1]*0.05+realtime)*sin(v[2]*0.05+realtime);
  567.             nv[1] = v[1] + 8*sin(v[0]*0.05+realtime)*sin(v[2]*0.05+realtime);
  568.             nv[2] = v[2];
  569.  
  570.             glVertex3fv (nv);
  571.         }
  572.         glEnd ();
  573.  
  574.     } else {
  575.         p = s->polys;
  576.  
  577.         t = R_TextureAnimation (s->texinfo->texture);
  578.         GL_Bind (t->gl_texturenum);
  579.         DrawGLWaterPoly (p);
  580.  
  581.         GL_Bind (lightmap_textures + s->lightmaptexturenum);
  582.         glEnable (GL_BLEND);
  583.         DrawGLWaterPolyLightmap (p);
  584.         glDisable (GL_BLEND);
  585.     }
  586. }
  587. #endif
  588.  
  589.  
  590. /*
  591. ================
  592. DrawGLWaterPoly
  593.  
  594. Warp the vertex coordinates
  595. ================
  596. */
  597. void DrawGLWaterPoly (glpoly_t *p)
  598. {
  599.     int        i;
  600.     float    *v;
  601.     vec3_t    nv;
  602.  
  603.     GL_DisableMultitexture();
  604.  
  605.     glBegin (GL_TRIANGLE_FAN);
  606.     v = p->verts[0];
  607.     for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
  608.     {
  609.         glTexCoord2f (v[3], v[4]);
  610.  
  611.         nv[0] = v[0] + 8*sin(v[1]*0.05+realtime)*sin(v[2]*0.05+realtime);
  612.         nv[1] = v[1] + 8*sin(v[0]*0.05+realtime)*sin(v[2]*0.05+realtime);
  613.         nv[2] = v[2];
  614.  
  615.         glVertex3fv (nv);
  616.     }
  617.     glEnd ();
  618. }
  619.  
  620. void DrawGLWaterPolyLightmap (glpoly_t *p)
  621. {
  622.     int        i;
  623.     float    *v;
  624.     vec3_t    nv;
  625.  
  626.     GL_DisableMultitexture();
  627.  
  628.     glBegin (GL_TRIANGLE_FAN);
  629.     v = p->verts[0];
  630.     for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
  631.     {
  632.         glTexCoord2f (v[5], v[6]);
  633.  
  634.         nv[0] = v[0] + 8*sin(v[1]*0.05+realtime)*sin(v[2]*0.05+realtime);
  635.         nv[1] = v[1] + 8*sin(v[0]*0.05+realtime)*sin(v[2]*0.05+realtime);
  636.         nv[2] = v[2];
  637.  
  638.         glVertex3fv (nv);
  639.     }
  640.     glEnd ();
  641. }
  642.  
  643. /*
  644. ================
  645. DrawGLPoly
  646. ================
  647. */
  648. void DrawGLPoly (glpoly_t *p)
  649. {
  650.     int        i;
  651.     float    *v;
  652.  
  653.     glBegin (GL_POLYGON);
  654.     v = p->verts[0];
  655.     for (i=0 ; i<p->numverts ; i++, v+= VERTEXSIZE)
  656.     {
  657.         glTexCoord2f (v[3], v[4]);
  658.         glVertex3fv (v);
  659.     }
  660.     glEnd ();
  661. }
  662.  
  663.  
  664. /*
  665. ================
  666. R_BlendLightmaps
  667. ================
  668. */
  669. void R_BlendLightmaps (void)
  670. {
  671.     int            i, j;
  672.     glpoly_t    *p;
  673.     float        *v;
  674.     glRect_t    *theRect;
  675.  
  676. #if 0
  677.     if (r_fullbright.value)
  678.         return;
  679. #endif
  680.     if (!gl_texsort.value)
  681.         return;
  682.  
  683.     glDepthMask (0);        // don't bother writing Z
  684.  
  685.     if (gl_lightmap_format == GL_LUMINANCE)
  686.         glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
  687.     else if (gl_lightmap_format == GL_INTENSITY)
  688.     {
  689.         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  690.         glColor4f (0,0,0,1);
  691.         glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  692.     }
  693.  
  694.     if (!r_lightmap.value)
  695.     {
  696.         glEnable (GL_BLEND);
  697.     }
  698.  
  699.     for (i=0 ; i<MAX_LIGHTMAPS ; i++)
  700.     {
  701.         p = lightmap_polys[i];
  702.         if (!p)
  703.             continue;
  704.         GL_Bind(lightmap_textures+i);
  705.         if (lightmap_modified[i])
  706.         {
  707.             lightmap_modified[i] = false;
  708.             theRect = &lightmap_rectchange[i];
  709. //            theRect->l = 0;
  710. //            theRect->t = 0;
  711. //            theRect->w = BLOCK_WIDTH;
  712. //            theRect->h = BLOCK_HEIGHT;
  713. //            glTexImage2D (GL_TEXTURE_2D, 0, lightmap_bytes
  714. //            , BLOCK_WIDTH, BLOCK_HEIGHT, 0, 
  715. //            gl_lightmap_format, GL_UNSIGNED_BYTE, lightmaps+i*BLOCK_WIDTH*BLOCK_HEIGHT*lightmap_bytes);
  716. //            glTexImage2D (GL_TEXTURE_2D, 0, lightmap_bytes
  717. //                , BLOCK_WIDTH, theRect->h, 0, 
  718. //                gl_lightmap_format, GL_UNSIGNED_BYTE, lightmaps+(i*BLOCK_HEIGHT+theRect->t)*BLOCK_WIDTH*lightmap_bytes);
  719.             glTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t, 
  720.                 BLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE,
  721.                 lightmaps+(i* BLOCK_HEIGHT + theRect->t) *BLOCK_WIDTH*lightmap_bytes);
  722.             theRect->l = BLOCK_WIDTH;
  723.             theRect->t = BLOCK_HEIGHT;
  724.             theRect->h = 0;
  725.             theRect->w = 0;
  726.         }
  727.         for ( ; p ; p=p->chain)
  728.         {
  729. //            if (p->flags & SURF_UNDERWATER)
  730. //                DrawGLWaterPolyLightmap (p);
  731.             if (((r_viewleaf->contents==CONTENTS_EMPTY && (p->flags & SURF_UNDERWATER)) ||
  732.                 (r_viewleaf->contents!=CONTENTS_EMPTY && !(p->flags & SURF_UNDERWATER)))
  733.                 && !(p->flags & SURF_DONTWARP))
  734.                 DrawGLWaterPolyLightmap (p);
  735.             else
  736.             {
  737.                 glBegin (GL_POLYGON);
  738.                 v = p->verts[0];
  739.                 for (j=0 ; j<p->numverts ; j++, v+= VERTEXSIZE)
  740.                 {
  741.                     glTexCoord2f (v[5], v[6]);
  742.                     glVertex3fv (v);
  743.                 }
  744.                 glEnd ();
  745.             }
  746.         }
  747.     }
  748.  
  749.     glDisable (GL_BLEND);
  750.     if (gl_lightmap_format == GL_LUMINANCE)
  751.         glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  752.     else if (gl_lightmap_format == GL_INTENSITY)
  753.     {
  754.         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  755.         glColor4f (1,1,1,1);
  756.     }
  757.  
  758.     glDepthMask (1);        // back to normal Z buffering
  759. }
  760.  
  761. /*
  762. ================
  763. R_RenderBrushPoly
  764. ================
  765. */
  766. void R_RenderBrushPoly (msurface_t *fa)
  767. {
  768.     texture_t    *t;
  769.     byte        *base;
  770.     int            maps;
  771.     glRect_t    *theRect;
  772.     int smax, tmax;
  773.  
  774.     c_brush_polys++;
  775.  
  776.     if (fa->flags & SURF_DRAWSKY)
  777.     {    // warp texture, no lightmaps
  778.         EmitBothSkyLayers (fa);
  779.         return;
  780.     }
  781.         
  782.     t = R_TextureAnimation (fa->texinfo->texture);
  783.     GL_Bind (t->gl_texturenum);
  784.  
  785.     if (fa->flags & SURF_DRAWTURB)
  786.     {    // warp texture, no lightmaps
  787.         EmitWaterPolys (fa);
  788.         return;
  789.     }
  790.  
  791.     if (((r_viewleaf->contents==CONTENTS_EMPTY && (fa->flags & SURF_UNDERWATER)) ||
  792.         (r_viewleaf->contents!=CONTENTS_EMPTY && !(fa->flags & SURF_UNDERWATER)))
  793.         && !(fa->flags & SURF_DONTWARP))
  794.         DrawGLWaterPoly (fa->polys);
  795.     else
  796.         DrawGLPoly (fa->polys);
  797.  
  798.     // add the poly to the proper lightmap chain
  799.  
  800.     fa->polys->chain = lightmap_polys[fa->lightmaptexturenum];
  801.     lightmap_polys[fa->lightmaptexturenum] = fa->polys;
  802.  
  803.     // check for lightmap modification
  804.     for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ;
  805.          maps++)
  806.         if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps])
  807.             goto dynamic;
  808.  
  809.     if (fa->dlightframe == r_framecount    // dynamic this frame
  810.         || fa->cached_dlight)            // dynamic previously
  811.     {
  812. dynamic:
  813.         if (r_dynamic.value)
  814.         {
  815.             lightmap_modified[fa->lightmaptexturenum] = true;
  816.             theRect = &lightmap_rectchange[fa->lightmaptexturenum];
  817.             if (fa->light_t < theRect->t) {
  818.                 if (theRect->h)
  819.                     theRect->h += theRect->t - fa->light_t;
  820.                 theRect->t = fa->light_t;
  821.             }
  822.             if (fa->light_s < theRect->l) {
  823.                 if (theRect->w)
  824.                     theRect->w += theRect->l - fa->light_s;
  825.                 theRect->l = fa->light_s;
  826.             }
  827.             smax = (fa->extents[0]>>4)+1;
  828.             tmax = (fa->extents[1]>>4)+1;
  829.             if ((theRect->w + theRect->l) < (fa->light_s + smax))
  830.                 theRect->w = (fa->light_s-theRect->l)+smax;
  831.             if ((theRect->h + theRect->t) < (fa->light_t + tmax))
  832.                 theRect->h = (fa->light_t-theRect->t)+tmax;
  833.             base = lightmaps + fa->lightmaptexturenum*lightmap_bytes*BLOCK_WIDTH*BLOCK_HEIGHT;
  834.             base += fa->light_t * BLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes;
  835.             R_BuildLightMap (fa, base, BLOCK_WIDTH*lightmap_bytes);
  836.         }
  837.     }
  838. }
  839.  
  840. /*
  841. ================
  842. R_RenderDynamicLightmaps
  843. Multitexture
  844. ================
  845. */
  846. void R_RenderDynamicLightmaps (msurface_t *fa)
  847. {
  848.     byte        *base;
  849.     int            maps;
  850.     glRect_t    *theRect;
  851.     int smax, tmax;
  852.  
  853.     c_brush_polys++;
  854.  
  855.     if (fa->flags & ( SURF_DRAWSKY | SURF_DRAWTURB) )
  856.         return;
  857.         
  858.     fa->polys->chain = lightmap_polys[fa->lightmaptexturenum];
  859.     lightmap_polys[fa->lightmaptexturenum] = fa->polys;
  860.  
  861.     // check for lightmap modification
  862.     for (maps = 0 ; maps < MAXLIGHTMAPS && fa->styles[maps] != 255 ;
  863.          maps++)
  864.         if (d_lightstylevalue[fa->styles[maps]] != fa->cached_light[maps])
  865.             goto dynamic;
  866.  
  867.     if (fa->dlightframe == r_framecount    // dynamic this frame
  868.         || fa->cached_dlight)            // dynamic previously
  869.     {
  870. dynamic:
  871.         if (r_dynamic.value)
  872.         {
  873.             lightmap_modified[fa->lightmaptexturenum] = true;
  874.             theRect = &lightmap_rectchange[fa->lightmaptexturenum];
  875.             if (fa->light_t < theRect->t) {
  876.                 if (theRect->h)
  877.                     theRect->h += theRect->t - fa->light_t;
  878.                 theRect->t = fa->light_t;
  879.             }
  880.             if (fa->light_s < theRect->l) {
  881.                 if (theRect->w)
  882.                     theRect->w += theRect->l - fa->light_s;
  883.                 theRect->l = fa->light_s;
  884.             }
  885.             smax = (fa->extents[0]>>4)+1;
  886.             tmax = (fa->extents[1]>>4)+1;
  887.             if ((theRect->w + theRect->l) < (fa->light_s + smax))
  888.                 theRect->w = (fa->light_s-theRect->l)+smax;
  889.             if ((theRect->h + theRect->t) < (fa->light_t + tmax))
  890.                 theRect->h = (fa->light_t-theRect->t)+tmax;
  891.             base = lightmaps + fa->lightmaptexturenum*lightmap_bytes*BLOCK_WIDTH*BLOCK_HEIGHT;
  892.             base += fa->light_t * BLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes;
  893.             R_BuildLightMap (fa, base, BLOCK_WIDTH*lightmap_bytes);
  894.         }
  895.     }
  896. }
  897.  
  898. /*
  899. ================
  900. R_MirrorChain
  901. ================
  902. */
  903. void R_MirrorChain (msurface_t *s)
  904. {
  905.     if (mirror)
  906.         return;
  907.     mirror = true;
  908.     mirror_plane = s->plane;
  909. }
  910.  
  911.  
  912. #if 0
  913. /*
  914. ================
  915. R_DrawWaterSurfaces
  916. ================
  917. */
  918. void R_DrawWaterSurfaces (void)
  919. {
  920.     int            i;
  921.     msurface_t    *s;
  922.     texture_t    *t;
  923.  
  924.     if (r_wateralpha.value == 1.0)
  925.         return;
  926.  
  927.     //
  928.     // go back to the world matrix
  929.     //
  930.     glLoadMatrixf (r_world_matrix);
  931.  
  932.     glEnable (GL_BLEND);
  933.     glColor4f (1,1,1,r_wateralpha.value);
  934.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  935.  
  936.     for (i=0 ; i<cl.worldmodel->numtextures ; i++)
  937.     {
  938.         t = cl.worldmodel->textures[i];
  939.         if (!t)
  940.             continue;
  941.         s = t->texturechain;
  942.         if (!s)
  943.             continue;
  944.         if ( !(s->flags & SURF_DRAWTURB) )
  945.             continue;
  946.  
  947.         // set modulate mode explicitly
  948.         GL_Bind (t->gl_texturenum);
  949.  
  950.         for ( ; s ; s=s->texturechain)
  951.             R_RenderBrushPoly (s);
  952.  
  953.         t->texturechain = NULL;
  954.     }
  955.  
  956.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  957.  
  958.     glColor4f (1,1,1,1);
  959.     glDisable (GL_BLEND);
  960. }
  961. #else
  962. /*
  963. ================
  964. R_DrawWaterSurfaces
  965. ================
  966. */
  967. void R_DrawWaterSurfaces (void)
  968. {
  969.     int            i;
  970.     msurface_t    *s;
  971.     texture_t    *t;
  972.  
  973.     if (r_wateralpha.value == 1.0 && gl_texsort.value)
  974.         return;
  975.  
  976.     //
  977.     // go back to the world matrix
  978.     //
  979.  
  980.     glLoadMatrixf (r_world_matrix);
  981.  
  982.     if (r_wateralpha.value < 1.0) {
  983.         glEnable (GL_BLEND);
  984.         glColor4f (1,1,1,r_wateralpha.value);
  985.         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  986.     }
  987.  
  988.     if (!gl_texsort.value) {
  989.         if (!waterchain)
  990.             return;
  991.  
  992.         for ( s = waterchain ; s ; s=s->texturechain) {
  993.             GL_Bind (s->texinfo->texture->gl_texturenum);
  994.             EmitWaterPolys (s);
  995.         }
  996.         
  997.         waterchain = NULL;
  998.     } else {
  999.  
  1000.         for (i=0 ; i<cl.worldmodel->numtextures ; i++)
  1001.         {
  1002.             t = cl.worldmodel->textures[i];
  1003.             if (!t)
  1004.                 continue;
  1005.             s = t->texturechain;
  1006.             if (!s)
  1007.                 continue;
  1008.             if ( !(s->flags & SURF_DRAWTURB ) )
  1009.                 continue;
  1010.  
  1011.             // set modulate mode explicitly
  1012.             
  1013.             GL_Bind (t->gl_texturenum);
  1014.  
  1015.             for ( ; s ; s=s->texturechain)
  1016.                 EmitWaterPolys (s);
  1017.             
  1018.             t->texturechain = NULL;
  1019.         }
  1020.  
  1021.     }
  1022.  
  1023.     if (r_wateralpha.value < 1.0) {
  1024.         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  1025.  
  1026.         glColor4f (1,1,1,1);
  1027.         glDisable (GL_BLEND);
  1028.     }
  1029.  
  1030. }
  1031.  
  1032. #endif
  1033.  
  1034. /*
  1035. ================
  1036. DrawTextureChains
  1037. ================
  1038. */
  1039. void DrawTextureChains (void)
  1040. {
  1041.     int        i;
  1042.     msurface_t    *s;
  1043.     texture_t    *t;
  1044.  
  1045.     if (!gl_texsort.value) {
  1046.         GL_DisableMultitexture();
  1047.  
  1048.         if (skychain) {
  1049.             R_DrawSkyChain(skychain);
  1050.             skychain = NULL;
  1051.         }
  1052.  
  1053.         return;
  1054.     } 
  1055.  
  1056.     for (i=0 ; i<cl.worldmodel->numtextures ; i++)
  1057.     {
  1058.         t = cl.worldmodel->textures[i];
  1059.         if (!t)
  1060.             continue;
  1061.         s = t->texturechain;
  1062.         if (!s)
  1063.             continue;
  1064.         if (i == skytexturenum)
  1065.             R_DrawSkyChain (s);
  1066.         else if (i == mirrortexturenum && r_mirroralpha.value != 1.0)
  1067.         {
  1068.             R_MirrorChain (s);
  1069.             continue;
  1070.         }
  1071.         else
  1072.         {
  1073.             if ((s->flags & SURF_DRAWTURB) && r_wateralpha.value != 1.0)
  1074.                 continue;    // draw translucent water later
  1075.             for ( ; s ; s=s->texturechain)
  1076.                 R_RenderBrushPoly (s);
  1077.         }
  1078.  
  1079.         t->texturechain = NULL;
  1080.     }
  1081. }
  1082.  
  1083. /*
  1084. =================
  1085. R_DrawBrushModel
  1086. =================
  1087. */
  1088. void R_DrawBrushModel (entity_t *e)
  1089. {
  1090.     int            i;
  1091.     int            k;
  1092.     vec3_t        mins, maxs;
  1093.     msurface_t    *psurf;
  1094.     float        dot;
  1095.     mplane_t    *pplane;
  1096.     model_t        *clmodel;
  1097.     qboolean    rotated;
  1098.  
  1099.     currententity = e;
  1100.     currenttexture = -1;
  1101.  
  1102.     clmodel = e->model;
  1103.  
  1104.     if (e->angles[0] || e->angles[1] || e->angles[2])
  1105.     {
  1106.         rotated = true;
  1107.         for (i=0 ; i<3 ; i++)
  1108.         {
  1109.             mins[i] = e->origin[i] - clmodel->radius;
  1110.             maxs[i] = e->origin[i] + clmodel->radius;
  1111.         }
  1112.     }
  1113.     else
  1114.     {
  1115.         rotated = false;
  1116.         VectorAdd (e->origin, clmodel->mins, mins);
  1117.         VectorAdd (e->origin, clmodel->maxs, maxs);
  1118.     }
  1119.  
  1120.     if (R_CullBox (mins, maxs))
  1121.         return;
  1122.  
  1123.     glColor3f (1,1,1);
  1124.     memset (lightmap_polys, 0, sizeof(lightmap_polys));
  1125.  
  1126.     VectorSubtract (r_refdef.vieworg, e->origin, modelorg);
  1127.     if (rotated)
  1128.     {
  1129.         vec3_t    temp;
  1130.         vec3_t    forward, right, up;
  1131.  
  1132.         VectorCopy (modelorg, temp);
  1133.         AngleVectors (e->angles, forward, right, up);
  1134.         modelorg[0] = DotProduct (temp, forward);
  1135.         modelorg[1] = -DotProduct (temp, right);
  1136.         modelorg[2] = DotProduct (temp, up);
  1137.     }
  1138.  
  1139.     psurf = &clmodel->surfaces[clmodel->firstmodelsurface];
  1140.  
  1141. // calculate dynamic lighting for bmodel if it's not an
  1142. // instanced model
  1143.     if (clmodel->firstmodelsurface != 0 && !gl_flashblend.value)
  1144.     {
  1145.         for (k=0 ; k<MAX_DLIGHTS ; k++)
  1146.         {
  1147.             if ((cl_dlights[k].die < cl.time) ||
  1148.                 (!cl_dlights[k].radius))
  1149.                 continue;
  1150.  
  1151.             R_MarkLights (&cl_dlights[k], 1<<k,
  1152.                 clmodel->nodes + clmodel->hulls[0].firstclipnode);
  1153.         }
  1154.     }
  1155.  
  1156.     glPushMatrix ();
  1157. e->angles[0] = -e->angles[0];    // stupid quake bug
  1158.     R_RotateForEntity (e);
  1159. e->angles[0] = -e->angles[0];    // stupid quake bug
  1160.  
  1161.     //
  1162.     // draw texture
  1163.     //
  1164.     for (i=0 ; i<clmodel->nummodelsurfaces ; i++, psurf++)
  1165.     {
  1166.     // find which side of the node we are on
  1167.         pplane = psurf->plane;
  1168.  
  1169.         dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
  1170.  
  1171.     // draw the polygon
  1172.         if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
  1173.             (!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
  1174.         {
  1175.             if (gl_texsort.value)
  1176.                 R_RenderBrushPoly (psurf);
  1177.             else
  1178.                 R_DrawSequentialPoly (psurf);
  1179.         }
  1180.     }
  1181.  
  1182.     R_BlendLightmaps ();
  1183.  
  1184.     glPopMatrix ();
  1185. }
  1186.  
  1187. /*
  1188. =============================================================
  1189.  
  1190.     WORLD MODEL
  1191.  
  1192. =============================================================
  1193. */
  1194.  
  1195. /*
  1196. ================
  1197. R_RecursiveWorldNode
  1198. ================
  1199. */
  1200. void R_RecursiveWorldNode (mnode_t *node)
  1201. {
  1202.     int            c, side;
  1203.     mplane_t    *plane;
  1204.     msurface_t    *surf, **mark;
  1205.     mleaf_t        *pleaf;
  1206.     double        dot;
  1207.  
  1208.     if (node->contents == CONTENTS_SOLID)
  1209.         return;        // solid
  1210.  
  1211.     if (node->visframe != r_visframecount)
  1212.         return;
  1213.     if (R_CullBox (node->minmaxs, node->minmaxs+3))
  1214.         return;
  1215.     
  1216. // if a leaf node, draw stuff
  1217.     if (node->contents < 0)
  1218.     {
  1219.         pleaf = (mleaf_t *)node;
  1220.  
  1221.         mark = pleaf->firstmarksurface;
  1222.         c = pleaf->nummarksurfaces;
  1223.  
  1224.         if (c)
  1225.         {
  1226.             do
  1227.             {
  1228.                 (*mark)->visframe = r_framecount;
  1229.                 mark++;
  1230.             } while (--c);
  1231.         }
  1232.  
  1233.     // deal with model fragments in this leaf
  1234.         if (pleaf->efrags)
  1235.             R_StoreEfrags (&pleaf->efrags);
  1236.  
  1237.         return;
  1238.     }
  1239.  
  1240. // node is just a decision point, so go down the apropriate sides
  1241.  
  1242. // find which side of the node we are on
  1243.     plane = node->plane;
  1244.  
  1245.     switch (plane->type)
  1246.     {
  1247.     case PLANE_X:
  1248.         dot = modelorg[0] - plane->dist;
  1249.         break;
  1250.     case PLANE_Y:
  1251.         dot = modelorg[1] - plane->dist;
  1252.         break;
  1253.     case PLANE_Z:
  1254.         dot = modelorg[2] - plane->dist;
  1255.         break;
  1256.     default:
  1257.         dot = DotProduct (modelorg, plane->normal) - plane->dist;
  1258.         break;
  1259.     }
  1260.  
  1261.     if (dot >= 0)
  1262.         side = 0;
  1263.     else
  1264.         side = 1;
  1265.  
  1266. // recurse down the children, front side first
  1267.     R_RecursiveWorldNode (node->children[side]);
  1268.  
  1269. // draw stuff
  1270.     c = node->numsurfaces;
  1271.  
  1272.     if (c)
  1273.     {
  1274.         surf = cl.worldmodel->surfaces + node->firstsurface;
  1275.  
  1276.         if (dot < 0 -BACKFACE_EPSILON)
  1277.             side = SURF_PLANEBACK;
  1278.         else if (dot > BACKFACE_EPSILON)
  1279.             side = 0;
  1280.         {
  1281.             for ( ; c ; c--, surf++)
  1282.             {
  1283.                 if (surf->visframe != r_framecount)
  1284.                     continue;
  1285.  
  1286.                 // don't backface underwater surfaces, because they warp
  1287. //                if ( !(surf->flags & SURF_UNDERWATER) && ( (dot < 0) ^ !!(surf->flags & SURF_PLANEBACK)) )
  1288. //                    continue;        // wrong side
  1289.                 if ( !(((r_viewleaf->contents==CONTENTS_EMPTY && (surf->flags & SURF_UNDERWATER)) ||
  1290.                     (r_viewleaf->contents!=CONTENTS_EMPTY && !(surf->flags & SURF_UNDERWATER)))
  1291.                     && !(surf->flags & SURF_DONTWARP)) && ( (dot < 0) ^ !!(surf->flags & SURF_PLANEBACK)) )
  1292.                     continue;        // wrong side
  1293.  
  1294.                 // if sorting by texture, just store it out
  1295.                 if (gl_texsort.value)
  1296.                 {
  1297.                     if (!mirror
  1298.                     || surf->texinfo->texture != cl.worldmodel->textures[mirrortexturenum])
  1299.                     {
  1300.                         surf->texturechain = surf->texinfo->texture->texturechain;
  1301.                         surf->texinfo->texture->texturechain = surf;
  1302.                     }
  1303.                 } else if (surf->flags & SURF_DRAWSKY) {
  1304.                     surf->texturechain = skychain;
  1305.                     skychain = surf;
  1306.                 } else if (surf->flags & SURF_DRAWTURB) {
  1307.                     surf->texturechain = waterchain;
  1308.                     waterchain = surf;
  1309.                 } else
  1310.                     R_DrawSequentialPoly (surf);
  1311.  
  1312.             }
  1313.         }
  1314.  
  1315.     }
  1316.  
  1317. // recurse down the back side
  1318.     R_RecursiveWorldNode (node->children[!side]);
  1319. }
  1320.  
  1321.  
  1322.  
  1323. /*
  1324. =============
  1325. R_DrawWorld
  1326. =============
  1327. */
  1328. void R_DrawWorld (void)
  1329. {
  1330.     entity_t    ent;
  1331.  
  1332.     memset (&ent, 0, sizeof(ent));
  1333.     ent.model = cl.worldmodel;
  1334.  
  1335.     VectorCopy (r_refdef.vieworg, modelorg);
  1336.  
  1337.     currententity = &ent;
  1338.     currenttexture = -1;
  1339.  
  1340.     glColor3f (1,1,1);
  1341.     memset (lightmap_polys, 0, sizeof(lightmap_polys));
  1342. #ifdef QUAKE2
  1343.     R_ClearSkyBox ();
  1344. #endif
  1345.  
  1346.     R_RecursiveWorldNode (cl.worldmodel->nodes);
  1347.  
  1348.         DrawTextureChains ();
  1349.  
  1350.     R_BlendLightmaps ();
  1351.  
  1352. #ifdef QUAKE2
  1353.     R_DrawSkyBox ();
  1354. #endif
  1355. }
  1356.  
  1357.  
  1358. /*
  1359. ===============
  1360. R_MarkLeaves
  1361. ===============
  1362. */
  1363. void R_MarkLeaves (void)
  1364. {
  1365.     byte    *vis;
  1366.     mnode_t    *node;
  1367.     int        i;
  1368.     byte    solid[4096];
  1369.  
  1370.     if (r_oldviewleaf == r_viewleaf && !r_novis.value)
  1371.         return;
  1372.     
  1373.     if (mirror)
  1374.         return;
  1375.  
  1376.     r_visframecount++;
  1377.     r_oldviewleaf = r_viewleaf;
  1378.  
  1379.     if (r_novis.value)
  1380.     {
  1381.         vis = solid;
  1382.         memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3);
  1383.     }
  1384.     else
  1385.         vis = Mod_LeafPVS (r_viewleaf, cl.worldmodel);
  1386.         
  1387.     for (i=0 ; i<cl.worldmodel->numleafs ; i++)
  1388.     {
  1389.         if (vis[i>>3] & (1<<(i&7)))
  1390.         {
  1391.             node = (mnode_t *)&cl.worldmodel->leafs[i+1];
  1392.             do
  1393.             {
  1394.                 if (node->visframe == r_visframecount)
  1395.                     break;
  1396.                 node->visframe = r_visframecount;
  1397.                 node = node->parent;
  1398.             } while (node);
  1399.         }
  1400.     }
  1401. }
  1402.  
  1403.  
  1404.  
  1405. /*
  1406. =============================================================================
  1407.  
  1408.   LIGHTMAP ALLOCATION
  1409.  
  1410. =============================================================================
  1411. */
  1412.  
  1413. // returns a texture number and the position inside it
  1414. int AllocBlock (int w, int h, int *x, int *y)
  1415. {
  1416.     int        i, j;
  1417.     int        best, best2;
  1418.     int        texnum;
  1419.  
  1420.     for (texnum=0 ; texnum<MAX_LIGHTMAPS ; texnum++)
  1421.     {
  1422.         best = BLOCK_HEIGHT;
  1423.  
  1424.         for (i=0 ; i<BLOCK_WIDTH-w ; i++)
  1425.         {
  1426.             best2 = 0;
  1427.  
  1428.             for (j=0 ; j<w ; j++)
  1429.             {
  1430.                 if (allocated[texnum][i+j] >= best)
  1431.                     break;
  1432.                 if (allocated[texnum][i+j] > best2)
  1433.                     best2 = allocated[texnum][i+j];
  1434.             }
  1435.             if (j == w)
  1436.             {    // this is a valid spot
  1437.                 *x = i;
  1438.                 *y = best = best2;
  1439.             }
  1440.         }
  1441.  
  1442.         if (best + h > BLOCK_HEIGHT)
  1443.             continue;
  1444.  
  1445.         for (i=0 ; i<w ; i++)
  1446.             allocated[texnum][*x + i] = best + h;
  1447.  
  1448.         return texnum;
  1449.     }
  1450.  
  1451.     Sys_Error ("AllocBlock: full");
  1452.     return 0;
  1453. }
  1454.  
  1455.  
  1456. mvertex_t    *r_pcurrentvertbase;
  1457. model_t        *currentmodel;
  1458.  
  1459. int    nColinElim;
  1460.  
  1461. /*
  1462. ================
  1463. BuildSurfaceDisplayList
  1464. ================
  1465. */
  1466. void BuildSurfaceDisplayList (msurface_t *fa)
  1467. {
  1468.     int            i, lindex, lnumverts;
  1469.     medge_t        *pedges, *r_pedge;
  1470.     int            vertpage;
  1471.     float        *vec;
  1472.     float        s, t;
  1473.     glpoly_t    *poly;
  1474.  
  1475. // reconstruct the polygon
  1476.     pedges = currentmodel->edges;
  1477.     lnumverts = fa->numedges;
  1478.     vertpage = 0;
  1479.  
  1480.     //
  1481.     // draw texture
  1482.     //
  1483.     poly = Hunk_Alloc (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float));
  1484.     poly->next = fa->polys;
  1485.     poly->flags = fa->flags;
  1486.     fa->polys = poly;
  1487.     poly->numverts = lnumverts;
  1488.  
  1489.     for (i=0 ; i<lnumverts ; i++)
  1490.     {
  1491.         lindex = currentmodel->surfedges[fa->firstedge + i];
  1492.  
  1493.         if (lindex > 0)
  1494.         {
  1495.             r_pedge = &pedges[lindex];
  1496.             vec = r_pcurrentvertbase[r_pedge->v[0]].position;
  1497.         }
  1498.         else
  1499.         {
  1500.             r_pedge = &pedges[-lindex];
  1501.             vec = r_pcurrentvertbase[r_pedge->v[1]].position;
  1502.         }
  1503.         s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
  1504.         s /= fa->texinfo->texture->width;
  1505.  
  1506.         t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
  1507.         t /= fa->texinfo->texture->height;
  1508.  
  1509.         VectorCopy (vec, poly->verts[i]);
  1510.         poly->verts[i][3] = s;
  1511.         poly->verts[i][4] = t;
  1512.  
  1513.         //
  1514.         // lightmap texture coordinates
  1515.         //
  1516.         s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
  1517.         s -= fa->texturemins[0];
  1518.         s += fa->light_s*16;
  1519.         s += 8;
  1520.         s /= BLOCK_WIDTH*16; //fa->texinfo->texture->width;
  1521.  
  1522.         t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
  1523.         t -= fa->texturemins[1];
  1524.         t += fa->light_t*16;
  1525.         t += 8;
  1526.         t /= BLOCK_HEIGHT*16; //fa->texinfo->texture->height;
  1527.  
  1528.         poly->verts[i][5] = s;
  1529.         poly->verts[i][6] = t;
  1530.     }
  1531.  
  1532.     //
  1533.     // remove co-linear points - Ed
  1534.     //
  1535.     if (!gl_keeptjunctions.value && !(fa->flags & SURF_UNDERWATER) )
  1536.     {
  1537.         for (i = 0 ; i < lnumverts ; ++i)
  1538.         {
  1539.             vec3_t v1, v2;
  1540.             float *prev, *this, *next;
  1541.  
  1542.             prev = poly->verts[(i + lnumverts - 1) % lnumverts];
  1543.             this = poly->verts[i];
  1544.             next = poly->verts[(i + 1) % lnumverts];
  1545.  
  1546.             VectorSubtract( this, prev, v1 );
  1547.             VectorNormalize( v1 );
  1548.             VectorSubtract( next, prev, v2 );
  1549.             VectorNormalize( v2 );
  1550.  
  1551.             // skip co-linear points
  1552.             #define COLINEAR_EPSILON 0.001
  1553.             if ((fabs( v1[0] - v2[0] ) <= COLINEAR_EPSILON) &&
  1554.                 (fabs( v1[1] - v2[1] ) <= COLINEAR_EPSILON) && 
  1555.                 (fabs( v1[2] - v2[2] ) <= COLINEAR_EPSILON))
  1556.             {
  1557.                 int j;
  1558.                 for (j = i + 1; j < lnumverts; ++j)
  1559.                 {
  1560.                     int k;
  1561.                     for (k = 0; k < VERTEXSIZE; ++k)
  1562.                         poly->verts[j - 1][k] = poly->verts[j][k];
  1563.                 }
  1564.                 --lnumverts;
  1565.                 ++nColinElim;
  1566.                 // retry next vertex next time, which is now current vertex
  1567.                 --i;
  1568.             }
  1569.         }
  1570.     }
  1571.     poly->numverts = lnumverts;
  1572.  
  1573. }
  1574.  
  1575. /*
  1576. ========================
  1577. GL_CreateSurfaceLightmap
  1578. ========================
  1579. */
  1580. void GL_CreateSurfaceLightmap (msurface_t *surf)
  1581. {
  1582.     int        smax, tmax;
  1583.     byte    *base;
  1584.  
  1585.     if (surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB))
  1586.         return;
  1587.  
  1588.     smax = (surf->extents[0]>>4)+1;
  1589.     tmax = (surf->extents[1]>>4)+1;
  1590.  
  1591.     surf->lightmaptexturenum = AllocBlock (smax, tmax, &surf->light_s, &surf->light_t);
  1592.     base = lightmaps + surf->lightmaptexturenum*lightmap_bytes*BLOCK_WIDTH*BLOCK_HEIGHT;
  1593.     base += (surf->light_t * BLOCK_WIDTH + surf->light_s) * lightmap_bytes;
  1594.     R_BuildLightMap (surf, base, BLOCK_WIDTH*lightmap_bytes);
  1595. }
  1596.  
  1597.  
  1598. /*
  1599. ==================
  1600. GL_BuildLightmaps
  1601.  
  1602. Builds the lightmap texture
  1603. with all the surfaces from all brush models
  1604. ==================
  1605. */
  1606. void GL_BuildLightmaps (void)
  1607. {
  1608.     int        i, j;
  1609.     model_t    *m;
  1610.  
  1611.     memset (allocated, 0, sizeof(allocated));
  1612.  
  1613.     r_framecount = 1;        // no dlightcache
  1614.  
  1615.     if (!lightmap_textures)
  1616.     {
  1617.         lightmap_textures = texture_extension_number;
  1618.         texture_extension_number += MAX_LIGHTMAPS;
  1619.     }
  1620.  
  1621.     gl_lightmap_format = GL_LUMINANCE;
  1622.     if (COM_CheckParm ("-lm_1"))
  1623.         gl_lightmap_format = GL_LUMINANCE;
  1624.     if (COM_CheckParm ("-lm_a"))
  1625.         gl_lightmap_format = GL_ALPHA;
  1626.     if (COM_CheckParm ("-lm_i"))
  1627.         gl_lightmap_format = GL_INTENSITY;
  1628.     if (COM_CheckParm ("-lm_2"))
  1629.         gl_lightmap_format = GL_RGBA4;
  1630.     if (COM_CheckParm ("-lm_4"))
  1631.         gl_lightmap_format = GL_RGBA;
  1632.  
  1633.     switch (gl_lightmap_format)
  1634.     {
  1635.     case GL_RGBA:
  1636.         lightmap_bytes = 4;
  1637.         break;
  1638.     case GL_RGBA4:
  1639.         lightmap_bytes = 2;
  1640.         break;
  1641.     case GL_LUMINANCE:
  1642.     case GL_INTENSITY:
  1643.     case GL_ALPHA:
  1644.         lightmap_bytes = 1;
  1645.         break;
  1646.     }
  1647.  
  1648.     for (j=1 ; j<MAX_MODELS ; j++)
  1649.     {
  1650.         m = cl.model_precache[j];
  1651.         if (!m)
  1652.             break;
  1653.         if (m->name[0] == '*')
  1654.             continue;
  1655.         r_pcurrentvertbase = m->vertexes;
  1656.         currentmodel = m;
  1657.         for (i=0 ; i<m->numsurfaces ; i++)
  1658.         {
  1659.             GL_CreateSurfaceLightmap (m->surfaces + i);
  1660.             if ( m->surfaces[i].flags & SURF_DRAWTURB )
  1661.                 continue;
  1662. #ifndef QUAKE2
  1663.             if ( m->surfaces[i].flags & SURF_DRAWSKY )
  1664.                 continue;
  1665. #endif
  1666.             BuildSurfaceDisplayList (m->surfaces + i);
  1667.         }
  1668.     }
  1669.  
  1670.      if (!gl_texsort.value)
  1671.          GL_SelectTexture(TEXTURE1_SGIS);
  1672.  
  1673.     //
  1674.     // upload all lightmaps that were filled
  1675.     //
  1676.     for (i=0 ; i<MAX_LIGHTMAPS ; i++)
  1677.     {
  1678.         if (!allocated[i][0])
  1679.             break;        // no more used
  1680.         lightmap_modified[i] = false;
  1681.         lightmap_rectchange[i].l = BLOCK_WIDTH;
  1682.         lightmap_rectchange[i].t = BLOCK_HEIGHT;
  1683.         lightmap_rectchange[i].w = 0;
  1684.         lightmap_rectchange[i].h = 0;
  1685.         GL_Bind(lightmap_textures + i);
  1686.         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1687.         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1688.         glTexImage2D (GL_TEXTURE_2D, 0, lightmap_bytes
  1689.         , BLOCK_WIDTH, BLOCK_HEIGHT, 0, 
  1690.         gl_lightmap_format, GL_UNSIGNED_BYTE, lightmaps+i*BLOCK_WIDTH*BLOCK_HEIGHT*lightmap_bytes);
  1691.     }
  1692.  
  1693.      if (!gl_texsort.value)
  1694.          GL_SelectTexture(TEXTURE0_SGIS);
  1695.  
  1696. }
  1697.  
  1698.