Annotation of quakeworld/client/gl_rmain.c, revision 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.