Annotation of quakeworld/client/gl_rmain.c, revision 1.1.1.1

1.1       root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.