Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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_main.c
  21.  
  22. #include "quakedef.h"
  23.  
  24. entity_t        r_worldentity;
  25.  
  26. qboolean        r_cache_thrash;         // compatability
  27.  
  28. vec3_t          modelorg, r_entorigin;
  29. entity_t        *currententity;
  30.  
  31. int                     r_visframecount;        // bumped when going to a new PVS
  32. int                     r_framecount;           // used for dlight push checking
  33.  
  34. mplane_t        frustum[4];
  35.  
  36. int                     c_brush_polys, c_alias_polys;
  37.  
  38. qboolean        envmap;                         // true during envmap command capture
  39.  
  40. int                     currenttexture = -1;            // to avoid unnecessary texture sets
  41.  
  42. int                     cnttextures[2] = {-1, -1};     // cached
  43.  
  44. int                     particletexture;        // little dot for particles
  45. int                     playertextures;         // up to 16 color translated skins
  46.  
  47. int                     mirrortexturenum;       // quake texturenum, not gltexturenum
  48. qboolean        mirror;
  49. mplane_t        *mirror_plane;
  50.  
  51. //
  52. // view origin
  53. //
  54. vec3_t  vup;
  55. vec3_t  vpn;
  56. vec3_t  vright;
  57. vec3_t  r_origin;
  58.  
  59. float   r_world_matrix[16];
  60. float   r_base_world_matrix[16];
  61.  
  62. //
  63. // screen size info
  64. //
  65. refdef_t        r_refdef;
  66.  
  67. mleaf_t         *r_viewleaf, *r_oldviewleaf;
  68.  
  69. texture_t       *r_notexture_mip;
  70.  
  71. int             d_lightstylevalue[256]; // 8.8 fraction of base light value
  72.  
  73.  
  74. void R_MarkLeaves (void);
  75.  
  76. cvar_t  r_norefresh = {"r_norefresh","0"};
  77. cvar_t  r_drawentities = {"r_drawentities","1"};
  78. cvar_t  r_drawviewmodel = {"r_drawviewmodel","1"};
  79. cvar_t  r_speeds = {"r_speeds","0"};
  80. cvar_t  r_fullbright = {"r_fullbright","0"};
  81. cvar_t  r_lightmap = {"r_lightmap","0"};
  82. cvar_t  r_shadows = {"r_shadows","0"};
  83. cvar_t  r_mirroralpha = {"r_mirroralpha","1"};
  84. cvar_t  r_wateralpha = {"r_wateralpha","1"};
  85. cvar_t  r_dynamic = {"r_dynamic","1"};
  86. cvar_t  r_novis = {"r_novis","0"};
  87.  
  88. cvar_t  gl_finish = {"gl_finish","0"};
  89. cvar_t  gl_clear = {"gl_clear","0"};
  90. cvar_t  gl_cull = {"gl_cull","1"};
  91. cvar_t  gl_texsort = {"gl_texsort","1"};
  92. cvar_t  gl_smoothmodels = {"gl_smoothmodels","1"};
  93. cvar_t  gl_affinemodels = {"gl_affinemodels","0"};
  94. cvar_t  gl_polyblend = {"gl_polyblend","1"};
  95. cvar_t  gl_flashblend = {"gl_flashblend","1"};
  96. cvar_t  gl_playermip = {"gl_playermip","0"};
  97. cvar_t  gl_nocolors = {"gl_nocolors","0"};
  98. cvar_t  gl_keeptjunctions = {"gl_keeptjunctions","0"};
  99. cvar_t  gl_reporttjunctions = {"gl_reporttjunctions","0"};
  100. cvar_t  gl_doubleeyes = {"gl_doubleeys", "1"};
  101.  
  102. extern  cvar_t  gl_ztrick;
  103.  
  104. /*
  105. =================
  106. R_CullBox
  107.  
  108. Returns true if the box is completely outside the frustom
  109. =================
  110. */
  111. qboolean R_CullBox (vec3_t mins, vec3_t maxs)
  112. {
  113.         int             i;
  114.  
  115.         for (i=0 ; i<4 ; i++)
  116.                 if (BoxOnPlaneSide (mins, maxs, &frustum[i]) == 2)
  117.                         return true;
  118.         return false;
  119. }
  120.  
  121.  
  122. void R_RotateForEntity (entity_t *e)
  123. {
  124.     glTranslatef (e->origin[0],  e->origin[1],  e->origin[2]);
  125.  
  126.     glRotatef (e->angles[1],  0, 0, 1);
  127.     glRotatef (-e->angles[0],  0, 1, 0);
  128.     glRotatef (e->angles[2],  1, 0, 0);
  129. }
  130.  
  131. /*
  132. =============================================================
  133.  
  134.   SPRITE MODELS
  135.  
  136. =============================================================
  137. */
  138.  
  139. /*
  140. ================
  141. R_GetSpriteFrame
  142. ================
  143. */
  144. mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
  145. {
  146.         msprite_t               *psprite;
  147.         mspritegroup_t  *pspritegroup;
  148.         mspriteframe_t  *pspriteframe;
  149.         int                             i, numframes, frame;
  150.         float                   *pintervals, fullinterval, targettime, time;
  151.  
  152.         psprite = currententity->model->cache.data;
  153.         frame = currententity->frame;
  154.  
  155.         if ((frame >= psprite->numframes) || (frame < 0))
  156.         {
  157.                 Con_Printf ("R_DrawSprite: no such frame %d\n", frame);
  158.                 frame = 0;
  159.         }
  160.  
  161.         if (psprite->frames[frame].type == SPR_SINGLE)
  162.         {
  163.                 pspriteframe = psprite->frames[frame].frameptr;
  164.         }
  165.         else
  166.         {
  167.                 pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
  168.                 pintervals = pspritegroup->intervals;
  169.                 numframes = pspritegroup->numframes;
  170.                 fullinterval = pintervals[numframes-1];
  171.  
  172.                 time = cl.time + currententity->syncbase;
  173.  
  174.         // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
  175.         // are positive, so we don't have to worry about division by 0
  176.                 targettime = time - ((int)(time / fullinterval)) * fullinterval;
  177.  
  178.                 for (i=0 ; i<(numframes-1) ; i++)
  179.                 {
  180.                         if (pintervals[i] > targettime)
  181.                                 break;
  182.                 }
  183.  
  184.                 pspriteframe = pspritegroup->frames[i];
  185.         }
  186.  
  187.         return pspriteframe;
  188. }
  189.  
  190.  
  191. /*
  192. =================
  193. R_DrawSpriteModel
  194.  
  195. =================
  196. */
  197. void R_DrawSpriteModel (entity_t *e)
  198. {
  199.         vec3_t  point;
  200.         mspriteframe_t  *frame;
  201.         float           *up, *right;
  202.         vec3_t          v_forward, v_right, v_up;
  203.         msprite_t               *psprite;
  204.  
  205.         // don't even bother culling, because it's just a single
  206.         // polygon without a surface cache
  207.         frame = R_GetSpriteFrame (e);
  208.         psprite = currententity->model->cache.data;
  209.  
  210.         if (psprite->type == SPR_ORIENTED)
  211.         {       // bullet marks on walls
  212.                 AngleVectors (currententity->angles, v_forward, v_right, v_up);
  213.                 up = v_up;
  214.                 right = v_right;
  215.         }
  216.         else
  217.         {       // normal sprite
  218.                 up = vup;
  219.                 right = vright;
  220.         }
  221.  
  222.         glColor3f (1,1,1);
  223.  
  224.         GL_DisableMultitexture();
  225.  
  226.     GL_Bind(frame->gl_texturenum);
  227.  
  228.         glEnable (GL_ALPHA_TEST);
  229.         glBegin (GL_QUADS);
  230.  
  231.         glTexCoord2f (0, 1);
  232.         VectorMA (e->origin, frame->down, up, point);
  233.         VectorMA (point, frame->left, right, point);
  234.         glVertex3fv (point);
  235.  
  236.         glTexCoord2f (0, 0);
  237.         VectorMA (e->origin, frame->up, up, point);
  238.         VectorMA (point, frame->left, right, point);
  239.         glVertex3fv (point);
  240.  
  241.         glTexCoord2f (1, 0);
  242.         VectorMA (e->origin, frame->up, up, point);
  243.         VectorMA (point, frame->right, right, point);
  244.         glVertex3fv (point);
  245.  
  246.         glTexCoord2f (1, 1);
  247.         VectorMA (e->origin, frame->down, up, point);
  248.         VectorMA (point, frame->right, right, point);
  249.         glVertex3fv (point);
  250.        
  251.         glEnd ();
  252.  
  253.         glDisable (GL_ALPHA_TEST);
  254. }
  255.  
  256. /*
  257. =============================================================
  258.  
  259.   ALIAS MODELS
  260.  
  261. =============================================================
  262. */
  263.  
  264.  
  265. #define NUMVERTEXNORMALS        162
  266.  
  267. float   r_avertexnormals[NUMVERTEXNORMALS][3] = {
  268. #include "anorms.h"
  269. };
  270.  
  271. vec3_t  shadevector;
  272. float   shadelight, ambientlight;
  273.  
  274. // precalculated dot products for quantized angles
  275. #define SHADEDOT_QUANT 16
  276. float   r_avertexnormal_dots[SHADEDOT_QUANT][256] =
  277. #include "anorm_dots.h"
  278. ;
  279.  
  280. float   *shadedots = r_avertexnormal_dots[0];
  281.  
  282. int     lastposenum;
  283.  
  284. /*
  285. =============
  286. GL_DrawAliasFrame
  287. =============
  288. */
  289. void GL_DrawAliasFrame (aliashdr_t *paliashdr, int posenum)
  290. {
  291.         float   s, t;
  292.         float   l;
  293.         int             i, j;
  294.         int             index;
  295.         trivertx_t      *v, *verts;
  296.         int             list;
  297.         int             *order;
  298.         vec3_t  point;
  299.         float   *normal;
  300.         int             count;
  301.  
  302. lastposenum = posenum;
  303.  
  304.         verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata);
  305.         verts += posenum * paliashdr->poseverts;
  306.         order = (int *)((byte *)paliashdr + paliashdr->commands);
  307.  
  308.         while (1)
  309.         {
  310.                 // get the vertex count and primitive type
  311.                 count = *order++;
  312.                 if (!count)
  313.                         break;          // done
  314.                 if (count < 0)
  315.                 {
  316.                         count = -count;
  317.                         glBegin (GL_TRIANGLE_FAN);
  318.                 }
  319.                 else
  320.                         glBegin (GL_TRIANGLE_STRIP);
  321.  
  322.                 do
  323.                 {
  324.                         // texture coordinates come from the draw list
  325.                         glTexCoord2f (((float *)order)[0], ((float *)order)[1]);
  326.                         order += 2;
  327.  
  328.                         // normals and vertexes come from the frame list
  329.                         l = shadedots[verts->lightnormalindex] * shadelight;
  330.                         glColor3f (l, l, l);
  331.                         glVertex3f (verts->v[0], verts->v[1], verts->v[2]);
  332.                         verts++;
  333.                 } while (--count);
  334.  
  335.                 glEnd ();
  336.         }
  337. }
  338.  
  339.  
  340. /*
  341. =============
  342. GL_DrawAliasShadow
  343. =============
  344. */
  345. extern  vec3_t                  lightspot;
  346.  
  347. void GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum)
  348. {
  349.         float   s, t, l;
  350.         int             i, j;
  351.         int             index;
  352.         trivertx_t      *v, *verts;
  353.         int             list;
  354.         int             *order;
  355.         vec3_t  point;
  356.         float   *normal;
  357.         float   height, lheight;
  358.         int             count;
  359.  
  360.         lheight = currententity->origin[2] - lightspot[2];
  361.  
  362.         height = 0;
  363.         verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata);
  364.         verts += posenum * paliashdr->poseverts;
  365.         order = (int *)((byte *)paliashdr + paliashdr->commands);
  366.  
  367.         height = -lheight + 1.0;
  368.  
  369.         while (1)
  370.         {
  371.                 // get the vertex count and primitive type
  372.                 count = *order++;
  373.                 if (!count)
  374.                         break;          // done
  375.                 if (count < 0)
  376.                 {
  377.                         count = -count;
  378.                         glBegin (GL_TRIANGLE_FAN);
  379.                 }
  380.                 else
  381.                         glBegin (GL_TRIANGLE_STRIP);
  382.  
  383.                 do
  384.                 {
  385.                         // texture coordinates come from the draw list
  386.                         // (skipped for shadows) glTexCoord2fv ((float *)order);
  387.                         order += 2;
  388.  
  389.                         // normals and vertexes come from the frame list
  390.                         point[0] = verts->v[0] * paliashdr->scale[0] + paliashdr->scale_origin[0];
  391.                         point[1] = verts->v[1] * paliashdr->scale[1] + paliashdr->scale_origin[1];
  392.                         point[2] = verts->v[2] * paliashdr->scale[2] + paliashdr->scale_origin[2];
  393.  
  394.                         point[0] -= shadevector[0]*(point[2]+lheight);
  395.                         point[1] -= shadevector[1]*(point[2]+lheight);
  396.                         point[2] = height;
  397. //                      height -= 0.001;
  398.                         glVertex3fv (point);
  399.  
  400.                         verts++;
  401.                 } while (--count);
  402.  
  403.                 glEnd ();
  404.         }      
  405. }
  406.  
  407.  
  408.  
  409. /*
  410. =================
  411. R_SetupAliasFrame
  412.  
  413. =================
  414. */
  415. void R_SetupAliasFrame (int frame, aliashdr_t *paliashdr)
  416. {
  417.         int                             pose, numposes;
  418.         float                   interval;
  419.  
  420.         if ((frame >= paliashdr->numframes) || (frame < 0))
  421.         {
  422.                 Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame);
  423.                 frame = 0;
  424.         }
  425.  
  426.         pose = paliashdr->frames[frame].firstpose;
  427.         numposes = paliashdr->frames[frame].numposes;
  428.  
  429.         if (numposes > 1)
  430.         {
  431.                 interval = paliashdr->frames[frame].interval;
  432.                 pose += (int)(cl.time / interval) % numposes;
  433.         }
  434.  
  435.         GL_DrawAliasFrame (paliashdr, pose);
  436. }
  437.  
  438.  
  439.  
  440. /*
  441. =================
  442. R_DrawAliasModel
  443.  
  444. =================
  445. */
  446. void R_DrawAliasModel (entity_t *e)
  447. {
  448.         int                     i, j;
  449.         int                     lnum;
  450.         vec3_t          dist;
  451.         float           add;
  452.         model_t         *clmodel;
  453.         vec3_t          mins, maxs;
  454.         aliashdr_t      *paliashdr;
  455.         trivertx_t      *verts, *v;
  456.         int                     index;
  457.         float           s, t, an;
  458.         int                     anim;
  459.  
  460.         clmodel = currententity->model;
  461.  
  462.         VectorAdd (currententity->origin, clmodel->mins, mins);
  463.         VectorAdd (currententity->origin, clmodel->maxs, maxs);
  464.  
  465.         if (R_CullBox (mins, maxs))
  466.                 return;
  467.  
  468.  
  469.         VectorCopy (currententity->origin, r_entorigin);
  470.         VectorSubtract (r_origin, r_entorigin, modelorg);
  471.  
  472.         //
  473.         // get lighting information
  474.         //
  475.  
  476.         ambientlight = shadelight = R_LightPoint (currententity->origin);
  477.  
  478.         // allways give the gun some light
  479.         if (e == &cl.viewent && ambientlight < 24)
  480.                 ambientlight = shadelight = 24;
  481.  
  482.         for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
  483.         {
  484.                 if (cl_dlights[lnum].die >= cl.time)
  485.                 {
  486.                         VectorSubtract (currententity->origin,
  487.                                                         cl_dlights[lnum].origin,
  488.                                                         dist);
  489.                         add = cl_dlights[lnum].radius - Length(dist);
  490.  
  491.                         if (add > 0) {
  492.                                 ambientlight += add;
  493.                                 //ZOID models should be affected by dlights as well
  494.                                 shadelight += add;
  495.                         }
  496.                 }
  497.         }
  498.  
  499.         // clamp lighting so it doesn't overbright as much
  500.         if (ambientlight > 128)
  501.                 ambientlight = 128;
  502.         if (ambientlight + shadelight > 192)
  503.                 shadelight = 192 - ambientlight;
  504.  
  505.         // ZOID: never allow players to go totally black
  506.         i = currententity - cl_entities;
  507.         if (i >= 1 && i<=cl.maxclients /* && !strcmp (currententity->model->name, "progs/player.mdl") */)
  508.                 if (ambientlight < 8)
  509.                         ambientlight = shadelight = 8;
  510.  
  511.         // HACK HACK HACK -- no fullbright colors, so make torches full light
  512.         if (!strcmp (clmodel->name, "progs/flame2.mdl")
  513.                 || !strcmp (clmodel->name, "progs/flame.mdl") )
  514.                 ambientlight = shadelight = 256;
  515.  
  516.         shadedots = r_avertexnormal_dots[((int)(e->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
  517.         shadelight = shadelight / 200.0;
  518.        
  519.         an = e->angles[1]/180*M_PI;
  520.         shadevector[0] = cos(-an);
  521.         shadevector[1] = sin(-an);
  522.         shadevector[2] = 1;
  523.         VectorNormalize (shadevector);
  524.  
  525.         //
  526.         // locate the proper data
  527.         //
  528.         paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model);
  529.  
  530.         c_alias_polys += paliashdr->numtris;
  531.  
  532.         //
  533.         // draw all the triangles
  534.         //
  535.  
  536.         GL_DisableMultitexture();
  537.  
  538.     glPushMatrix ();
  539.         R_RotateForEntity (e);
  540.  
  541.         if (!strcmp (clmodel->name, "progs/eyes.mdl") && gl_doubleeyes.value) {
  542.                 glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2] - (22 + 8));
  543. // double size of eyes, since they are really hard to see in gl
  544.                 glScalef (paliashdr->scale[0]*2, paliashdr->scale[1]*2, paliashdr->scale[2]*2);
  545.         } else {
  546.                 glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2]);
  547.                 glScalef (paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2]);
  548.         }
  549.  
  550.         anim = (int)(cl.time*10) & 3;
  551.     GL_Bind(paliashdr->gl_texturenum[currententity->skinnum][anim]);
  552.  
  553.         // we can't dynamically colormap textures, so they are cached
  554.         // seperately for the players.  Heads are just uncolored.
  555.         if (currententity->colormap != vid.colormap && !gl_nocolors.value)
  556.         {
  557.                 i = currententity - cl_entities;
  558.                 if (i >= 1 && i<=cl.maxclients /* && !strcmp (currententity->model->name, "progs/player.mdl") */)
  559.                     GL_Bind(playertextures - 1 + i);
  560.         }
  561.  
  562.         if (gl_smoothmodels.value)
  563.                 glShadeModel (GL_SMOOTH);
  564.         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  565.  
  566.         if (gl_affinemodels.value)
  567.                 glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  568.  
  569.         R_SetupAliasFrame (currententity->frame, paliashdr);
  570.  
  571.         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  572.  
  573.         glShadeModel (GL_FLAT);
  574.         if (gl_affinemodels.value)
  575.                 glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  576.  
  577.         glPopMatrix ();
  578.  
  579.         if (r_shadows.value)
  580.         {
  581.                 glPushMatrix ();
  582.                 R_RotateForEntity (e);
  583.                 glDisable (GL_TEXTURE_2D);
  584.                 glEnable (GL_BLEND);
  585.                 glColor4f (0,0,0,0.5);
  586.                 GL_DrawAliasShadow (paliashdr, lastposenum);
  587.                 glEnable (GL_TEXTURE_2D);
  588.                 glDisable (GL_BLEND);
  589.                 glColor4f (1,1,1,1);
  590.                 glPopMatrix ();
  591.         }
  592.  
  593. }
  594.  
  595. //==================================================================================
  596.  
  597. /*
  598. =============
  599. R_DrawEntitiesOnList
  600. =============
  601. */
  602. void R_DrawEntitiesOnList (void)
  603. {
  604.         int             i;
  605.  
  606.         if (!r_drawentities.value)
  607.                 return;
  608.  
  609.         // draw sprites seperately, because of alpha blending
  610.         for (i=0 ; i<cl_numvisedicts ; i++)
  611.         {
  612.                 currententity = cl_visedicts[i];
  613.  
  614.                 switch (currententity->model->type)
  615.                 {
  616.                 case mod_alias:
  617.                         R_DrawAliasModel (currententity);
  618.                         break;
  619.  
  620.                 case mod_brush:
  621.                         R_DrawBrushModel (currententity);
  622.                         break;
  623.  
  624.                 default:
  625.                         break;
  626.                 }
  627.         }
  628.  
  629.         for (i=0 ; i<cl_numvisedicts ; i++)
  630.         {
  631.                 currententity = cl_visedicts[i];
  632.  
  633.                 switch (currententity->model->type)
  634.                 {
  635.                 case mod_sprite:
  636.                         R_DrawSpriteModel (currententity);
  637.                         break;
  638.                 }
  639.         }
  640. }
  641.  
  642. /*
  643. =============
  644. R_DrawViewModel
  645. =============
  646. */
  647. void R_DrawViewModel (void)
  648. {
  649.         float           ambient[4], diffuse[4];
  650.         int                     j;
  651.         int                     lnum;
  652.         vec3_t          dist;
  653.         float           add;
  654.         dlight_t        *dl;
  655.         int                     ambientlight, shadelight;
  656.  
  657.         if (!r_drawviewmodel.value)
  658.                 return;
  659.  
  660.         if (chase_active.value)
  661.                 return;
  662.  
  663.         if (envmap)
  664.                 return;
  665.  
  666.         if (!r_drawentities.value)
  667.                 return;
  668.  
  669.         if (cl.items & IT_INVISIBILITY)
  670.                 return;
  671.  
  672.         if (cl.stats[STAT_HEALTH] <= 0)
  673.                 return;
  674.  
  675.         currententity = &cl.viewent;
  676.         if (!currententity->model)
  677.                 return;
  678.  
  679.         j = R_LightPoint (currententity->origin);
  680.  
  681.         if (j < 24)
  682.                 j = 24;         // allways give some light on gun
  683.         ambientlight = j;
  684.         shadelight = j;
  685.  
  686. // add dynamic lights          
  687.         for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
  688.         {
  689.                 dl = &cl_dlights[lnum];
  690.                 if (!dl->radius)
  691.                         continue;
  692.                 if (!dl->radius)
  693.                         continue;
  694.                 if (dl->die < cl.time)
  695.                         continue;
  696.  
  697.                 VectorSubtract (currententity->origin, dl->origin, dist);
  698.                 add = dl->radius - Length(dist);
  699.                 if (add > 0)
  700.                         ambientlight += add;
  701.         }
  702.  
  703.         ambient[0] = ambient[1] = ambient[2] = ambient[3] = (float)ambientlight / 128;
  704.         diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = (float)shadelight / 128;
  705.  
  706.         // hack the depth range to prevent view model from poking into walls
  707.         glDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin));
  708.         R_DrawAliasModel (currententity);
  709.         glDepthRange (gldepthmin, gldepthmax);
  710. }
  711.  
  712.  
  713. /*
  714. ============
  715. R_PolyBlend
  716. ============
  717. */
  718. void R_PolyBlend (void)
  719. {
  720.         if (!gl_polyblend.value)
  721.                 return;
  722.         if (!v_blend[3])
  723.                 return;
  724.  
  725.         GL_DisableMultitexture();
  726.  
  727.         glDisable (GL_ALPHA_TEST);
  728.         glEnable (GL_BLEND);
  729.         glDisable (GL_DEPTH_TEST);
  730.         glDisable (GL_TEXTURE_2D);
  731.  
  732.     glLoadIdentity ();
  733.  
  734.     glRotatef (-90,  1, 0, 0);      // put Z going up
  735.     glRotatef (90,  0, 0, 1);       // put Z going up
  736.  
  737.         glColor4fv (v_blend);
  738.  
  739.         glBegin (GL_QUADS);
  740.  
  741.         glVertex3f (10, 100, 100);
  742.         glVertex3f (10, -100, 100);
  743.         glVertex3f (10, -100, -100);
  744.         glVertex3f (10, 100, -100);
  745.         glEnd ();
  746.  
  747.         glDisable (GL_BLEND);
  748.         glEnable (GL_TEXTURE_2D);
  749.         glEnable (GL_ALPHA_TEST);
  750. }
  751.  
  752.  
  753. int SignbitsForPlane (mplane_t *out)
  754. {
  755.         int     bits, j;
  756.  
  757.         // for fast box on planeside test
  758.  
  759.         bits = 0;
  760.         for (j=0 ; j<3 ; j++)
  761.         {
  762.                 if (out->normal[j] < 0)
  763.                         bits |= 1<<j;
  764.         }
  765.         return bits;
  766. }
  767.  
  768.  
  769. void R_SetFrustum (void)
  770. {
  771.         int             i;
  772.  
  773.         if (r_refdef.fov_x == 90)
  774.         {
  775.                 // front side is visible
  776.  
  777.                 VectorAdd (vpn, vright, frustum[0].normal);
  778.                 VectorSubtract (vpn, vright, frustum[1].normal);
  779.  
  780.                 VectorAdd (vpn, vup, frustum[2].normal);
  781.                 VectorSubtract (vpn, vup, frustum[3].normal);
  782.         }
  783.         else
  784.         {
  785.                 // rotate VPN right by FOV_X/2 degrees
  786.                 RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_refdef.fov_x / 2 ) );
  787.                 // rotate VPN left by FOV_X/2 degrees
  788.                 RotatePointAroundVector( frustum[1].normal, vup, vpn, 90-r_refdef.fov_x / 2 );
  789.                 // rotate VPN up by FOV_X/2 degrees
  790.                 RotatePointAroundVector( frustum[2].normal, vright, vpn, 90-r_refdef.fov_y / 2 );
  791.                 // rotate VPN down by FOV_X/2 degrees
  792.                 RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_refdef.fov_y / 2 ) );
  793.         }
  794.  
  795.         for (i=0 ; i<4 ; i++)
  796.         {
  797.                 frustum[i].type = PLANE_ANYZ;
  798.                 frustum[i].dist = DotProduct (r_origin, frustum[i].normal);
  799.                 frustum[i].signbits = SignbitsForPlane (&frustum[i]);
  800.         }
  801. }
  802.  
  803.  
  804.  
  805. /*
  806. ===============
  807. R_SetupFrame
  808. ===============
  809. */
  810. void R_SetupFrame (void)
  811. {
  812.         int                             edgecount;
  813.         vrect_t                 vrect;
  814.         float                   w, h;
  815.  
  816. // don't allow cheats in multiplayer
  817.         if (cl.maxclients > 1)
  818.                 Cvar_Set ("r_fullbright", "0");
  819.  
  820.         R_AnimateLight ();
  821.  
  822.         r_framecount++;
  823.  
  824. // build the transformation matrix for the given view angles
  825.         VectorCopy (r_refdef.vieworg, r_origin);
  826.  
  827.         AngleVectors (r_refdef.viewangles, vpn, vright, vup);
  828.  
  829. // current viewleaf
  830.         r_oldviewleaf = r_viewleaf;
  831.         r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel);
  832.  
  833.         V_SetContentsColor (r_viewleaf->contents);
  834.         V_CalcBlend ();
  835.  
  836.         r_cache_thrash = false;
  837.  
  838.         c_brush_polys = 0;
  839.         c_alias_polys = 0;
  840.  
  841. }
  842.  
  843.  
  844. void MYgluPerspective( GLdouble fovy, GLdouble aspect,
  845.                      GLdouble zNear, GLdouble zFar )
  846. {
  847.    GLdouble xmin, xmax, ymin, ymax;
  848.  
  849.    ymax = zNear * tan( fovy * M_PI / 360.0 );
  850.    ymin = -ymax;
  851.  
  852.    xmin = ymin * aspect;
  853.    xmax = ymax * aspect;
  854.  
  855.    glFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
  856. }
  857.  
  858.  
  859. /*
  860. =============
  861. R_SetupGL
  862. =============
  863. */
  864. void R_SetupGL (void)
  865. {
  866.         float   screenaspect;
  867.         float   yfov;
  868.         int             i;
  869.         extern  int glwidth, glheight;
  870.         int             x, x2, y2, y, w, h;
  871.  
  872.         //
  873.         // set up viewpoint
  874.         //
  875.         glMatrixMode(GL_PROJECTION);
  876.     glLoadIdentity ();
  877.         x = r_refdef.vrect.x * glwidth/vid.width;
  878.         x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/vid.width;
  879.         y = (vid.height-r_refdef.vrect.y) * glheight/vid.height;
  880.         y2 = (vid.height - (r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/vid.height;
  881.  
  882.         // fudge around because of frac screen scale
  883.         if (x > 0)
  884.                 x--;
  885.         if (x2 < glwidth)
  886.                 x2++;
  887.         if (y2 < 0)
  888.                 y2--;
  889.         if (y < glheight)
  890.                 y++;
  891.  
  892.         w = x2 - x;
  893.         h = y - y2;
  894.  
  895.         if (envmap)
  896.         {
  897.                 x = y2 = 0;
  898.                 w = h = 256;
  899.         }
  900.  
  901.         glViewport (glx + x, gly + y2, w, h);
  902.     screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height;
  903. //      yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI;
  904.     MYgluPerspective (r_refdef.fov_y,  screenaspect,  4,  4096);
  905.  
  906.         if (mirror)
  907.         {
  908.                 if (mirror_plane->normal[2])
  909.                         glScalef (1, -1, 1);
  910.                 else
  911.                         glScalef (-1, 1, 1);
  912.                 glCullFace(GL_BACK);
  913.         }
  914.         else
  915.                 glCullFace(GL_FRONT);
  916.  
  917.         glMatrixMode(GL_MODELVIEW);
  918.     glLoadIdentity ();
  919.  
  920.     glRotatef (-90,  1, 0, 0);      // put Z going up
  921.     glRotatef (90,  0, 0, 1);       // put Z going up
  922.     glRotatef (-r_refdef.viewangles[2],  1, 0, 0);
  923.     glRotatef (-r_refdef.viewangles[0],  0, 1, 0);
  924.     glRotatef (-r_refdef.viewangles[1],  0, 0, 1);
  925.     glTranslatef (-r_refdef.vieworg[0],  -r_refdef.vieworg[1],  -r_refdef.vieworg[2]);
  926.  
  927.         glGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix);
  928.  
  929.         //
  930.         // set drawing parms
  931.         //
  932.         if (gl_cull.value)
  933.                 glEnable(GL_CULL_FACE);
  934.         else
  935.                 glDisable(GL_CULL_FACE);
  936.  
  937.         glDisable(GL_BLEND);
  938.         glDisable(GL_ALPHA_TEST);
  939.         glEnable(GL_DEPTH_TEST);
  940. }
  941.  
  942. /*
  943. ================
  944. R_RenderScene
  945.  
  946. r_refdef must be set before the first call
  947. ================
  948. */
  949. void R_RenderScene (void)
  950. {
  951.         R_SetupFrame ();
  952.  
  953.         R_SetFrustum ();
  954.  
  955.         R_SetupGL ();
  956.  
  957.         R_MarkLeaves ();        // done here so we know if we're in water
  958.  
  959.         R_DrawWorld ();         // adds static entities to the list
  960.  
  961.         S_ExtraUpdate ();       // don't let sound get messed up if going slow
  962.  
  963.         R_DrawEntitiesOnList ();
  964.  
  965.         GL_DisableMultitexture();
  966.  
  967.         R_RenderDlights ();
  968.  
  969.         R_DrawParticles ();
  970.  
  971. #ifdef GLTEST
  972.         Test_Draw ();
  973. #endif
  974.  
  975. }
  976.  
  977.  
  978. /*
  979. =============
  980. R_Clear
  981. =============
  982. */
  983. void R_Clear (void)
  984. {
  985.         if (r_mirroralpha.value != 1.0)
  986.         {
  987.                 if (gl_clear.value)
  988.                         glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  989.                 else
  990.                         glClear (GL_DEPTH_BUFFER_BIT);
  991.                 gldepthmin = 0;
  992.                 gldepthmax = 0.5;
  993.                 glDepthFunc (GL_LEQUAL);
  994.         }
  995.         else if (gl_ztrick.value)
  996.         {
  997.                 static int trickframe;
  998.  
  999.                 if (gl_clear.value)
  1000.                         glClear (GL_COLOR_BUFFER_BIT);
  1001.  
  1002.                 trickframe++;
  1003.                 if (trickframe & 1)
  1004.                 {
  1005.                         gldepthmin = 0;
  1006.                         gldepthmax = 0.49999;
  1007.                         glDepthFunc (GL_LEQUAL);
  1008.                 }
  1009.                 else
  1010.                 {
  1011.                         gldepthmin = 1;
  1012.                         gldepthmax = 0.5;
  1013.                         glDepthFunc (GL_GEQUAL);
  1014.                 }
  1015.         }
  1016.         else
  1017.         {
  1018.                 if (gl_clear.value)
  1019.                         glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  1020.                 else
  1021.                         glClear (GL_DEPTH_BUFFER_BIT);
  1022.                 gldepthmin = 0;
  1023.                 gldepthmax = 1;
  1024.                 glDepthFunc (GL_LEQUAL);
  1025.         }
  1026.  
  1027.         glDepthRange (gldepthmin, gldepthmax);
  1028. }
  1029.  
  1030. /*
  1031. =============
  1032. R_Mirror
  1033. =============
  1034. */
  1035. void R_Mirror (void)
  1036. {
  1037.         float           d;
  1038.         msurface_t      *s;
  1039.         entity_t        *ent;
  1040.  
  1041.         if (!mirror)
  1042.                 return;
  1043.  
  1044.         memcpy (r_base_world_matrix, r_world_matrix, sizeof(r_base_world_matrix));
  1045.  
  1046.         d = DotProduct (r_refdef.vieworg, mirror_plane->normal) - mirror_plane->dist;
  1047.         VectorMA (r_refdef.vieworg, -2*d, mirror_plane->normal, r_refdef.vieworg);
  1048.  
  1049.         d = DotProduct (vpn, mirror_plane->normal);
  1050.         VectorMA (vpn, -2*d, mirror_plane->normal, vpn);
  1051.  
  1052.         r_refdef.viewangles[0] = -asin (vpn[2])/M_PI*180;
  1053.         r_refdef.viewangles[1] = atan2 (vpn[1], vpn[0])/M_PI*180;
  1054.         r_refdef.viewangles[2] = -r_refdef.viewangles[2];
  1055.  
  1056.         ent = &cl_entities[cl.viewentity];
  1057.         if (cl_numvisedicts < MAX_VISEDICTS)
  1058.         {
  1059.                 cl_visedicts[cl_numvisedicts] = ent;
  1060.                 cl_numvisedicts++;
  1061.         }
  1062.  
  1063.         gldepthmin = 0.5;
  1064.         gldepthmax = 1;
  1065.         glDepthRange (gldepthmin, gldepthmax);
  1066.         glDepthFunc (GL_LEQUAL);
  1067.  
  1068.         R_RenderScene ();
  1069.         R_DrawWaterSurfaces ();
  1070.  
  1071.         gldepthmin = 0;
  1072.         gldepthmax = 0.5;
  1073.         glDepthRange (gldepthmin, gldepthmax);
  1074.         glDepthFunc (GL_LEQUAL);
  1075.  
  1076.         // blend on top
  1077.         glEnable (GL_BLEND);
  1078.         glMatrixMode(GL_PROJECTION);
  1079.         if (mirror_plane->normal[2])
  1080.                 glScalef (1,-1,1);
  1081.         else
  1082.                 glScalef (-1,1,1);
  1083.         glCullFace(GL_FRONT);
  1084.         glMatrixMode(GL_MODELVIEW);
  1085.  
  1086.         glLoadMatrixf (r_base_world_matrix);
  1087.  
  1088.         glColor4f (1,1,1,r_mirroralpha.value);
  1089.         s = cl.worldmodel->textures[mirrortexturenum]->texturechain;
  1090.         for ( ; s ; s=s->texturechain)
  1091.                 R_RenderBrushPoly (s);
  1092.         cl.worldmodel->textures[mirrortexturenum]->texturechain = NULL;
  1093.         glDisable (GL_BLEND);
  1094.         glColor4f (1,1,1,1);
  1095. }
  1096.  
  1097. /*
  1098. ================
  1099. R_RenderView
  1100.  
  1101. r_refdef must be set before the first call
  1102. ================
  1103. */
  1104. void R_RenderView (void)
  1105. {
  1106.         double  time1, time2;
  1107.         GLfloat colors[4] = {(GLfloat) 0.0, (GLfloat) 0.0, (GLfloat) 1, (GLfloat) 0.20};
  1108.  
  1109.         if (r_norefresh.value)
  1110.                 return;
  1111.  
  1112.         if (!r_worldentity.model || !cl.worldmodel)
  1113.                 Sys_Error ("R_RenderView: NULL worldmodel");
  1114.  
  1115.         if (r_speeds.value)
  1116.         {
  1117.                 glFinish ();
  1118.                 time1 = Sys_FloatTime ();
  1119.                 c_brush_polys = 0;
  1120.                 c_alias_polys = 0;
  1121.         }
  1122.  
  1123.         mirror = false;
  1124.  
  1125.         if (gl_finish.value)
  1126.                 glFinish ();
  1127.  
  1128.         R_Clear ();
  1129.  
  1130.         // render normal view
  1131.  
  1132. /***** Experimental silly looking fog ******
  1133. ****** Use r_fullbright if you enable ******
  1134.         glFogi(GL_FOG_MODE, GL_LINEAR);
  1135.         glFogfv(GL_FOG_COLOR, colors);
  1136.         glFogf(GL_FOG_END, 512.0);
  1137.         glEnable(GL_FOG);
  1138. ********************************************/
  1139.  
  1140.         R_RenderScene ();
  1141.         R_DrawViewModel ();
  1142.         R_DrawWaterSurfaces ();
  1143.  
  1144. //  More fog right here :)
  1145. //      glDisable(GL_FOG);
  1146. //  End of all fog code...
  1147.  
  1148.         // render mirror view
  1149.         R_Mirror ();
  1150.  
  1151.         R_PolyBlend ();
  1152.  
  1153.         if (r_speeds.value)
  1154.         {
  1155. //              glFinish ();
  1156.                 time2 = Sys_FloatTime ();
  1157.                 Con_Printf ("%3i ms  %4i wpoly %4i epoly\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys);
  1158.         }
  1159. }
  1160.