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