Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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