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