home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 14 / MA_Cover_14.iso / source / c / q1source_amy / qw / client / gl_rmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-21  |  23.7 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.