home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / glquake_src / gl_rmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-03-20  |  26.6 KB  |  1,211 lines

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