Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

tr_main.c File Reference

#include "tr_local.h"

Include dependency graph for tr_main.c:

Include dependency graph

Go to the source code of this file.

Defines

#define CUTOFF   8
#define SWAP_DRAW_SURF(a, b)   temp=((int *)a)[0];((int *)a)[0]=((int *)b)[0];((int *)b)[0]=temp; temp=((int *)a)[1];((int *)a)[1]=((int *)b)[1];((int *)b)[1]=temp;

Functions

qboolean IsMirror (const drawSurf_t *drawSurf, int entityNum)
void myGlMultMatrix (const float *a, const float *b, float *out)
void qsortFast (void *base, unsigned num, unsigned width)
void R_AddDrawSurf (surfaceType_t *surface, shader_t *shader, int fogIndex, int dlightMap)
void R_AddEntitySurfaces (void)
int R_CullLocalBox (vec3_t bounds[2])
int R_CullLocalPointAndRadius (vec3_t pt, float radius)
int R_CullPointAndRadius (vec3_t pt, float radius)
void R_DebugGraphics (void)
void R_DebugPolygon (int color, int numPoints, float *points)
void R_DecomposeSort (unsigned sort, int *entityNum, shader_t **shader, int *fogNum, int *dlightMap)
void R_GenerateDrawSurfs (void)
qboolean R_GetPortalOrientations (drawSurf_t *drawSurf, int entityNum, orientation_t *surface, orientation_t *camera, vec3_t pvsOrigin, qboolean *mirror)
void R_LocalNormalToWorld (vec3_t local, vec3_t world)
void R_LocalPointToWorld (vec3_t local, vec3_t world)
void R_MirrorPoint (vec3_t in, orientation_t *surface, orientation_t *camera, vec3_t out)
void R_MirrorVector (vec3_t in, orientation_t *surface, orientation_t *camera, vec3_t out)
qboolean R_MirrorViewBySurface (drawSurf_t *drawSurf, int entityNum)
void R_PlaneForSurface (surfaceType_t *surfType, cplane_t *plane)
void R_RenderView (viewParms_t *parms)
void R_RotateForEntity (const trRefEntity_t *ent, const viewParms_t *viewParms, orientationr_t *or)
void R_RotateForViewer (void)
void R_SetupFrustum (void)
void R_SetupProjection (void)
void R_SortDrawSurfs (drawSurf_t *drawSurfs, int numDrawSurfs)
int R_SpriteFogNum (trRefEntity_t *ent)
void R_TransformClipToWindow (const vec4_t clip, const viewParms_t *view, vec4_t normalized, vec4_t window)
void R_TransformModelToClip (const vec3_t src, const float *modelMatrix, const float *projectionMatrix, vec4_t eye, vec4_t dst)
void R_WorldToLocal (vec3_t world, vec3_t local)
void SetFarClip (void)
void shortsort (drawSurf_t *lo, drawSurf_t *hi)
qboolean SurfIsOffscreen (const drawSurf_t *drawSurf, vec4_t clipDest[128])

Variables

surfaceType_t entitySurface = SF_ENTITY
refimport_t ri
float s_flipMatrix [16]
trGlobals_t tr


Define Documentation

#define CUTOFF   8
 

Definition at line 1012 of file tr_main.c.

#define SWAP_DRAW_SURF a,
 )     temp=((int *)a)[0];((int *)a)[0]=((int *)b)[0];((int *)b)[0]=temp; temp=((int *)a)[1];((int *)a)[1]=((int *)b)[1];((int *)b)[1]=temp;
 

Definition at line 1006 of file tr_main.c.

Referenced by qsortFast(), and shortsort().


Function Documentation

qboolean IsMirror const drawSurf_t drawSurf,
int  entityNum
[static]
 

Definition at line 739 of file tr_main.c.

References cplane_t, trGlobals_t::currentEntity, trGlobals_t::currentEntityNum, d, cplane_s::dist, DotProduct, drawSurf_t, trRefEntity_t::e, e, trRefdef_t::entities, i, cplane_s::normal, trRefdef_t::num_entities, refEntity_t::oldorigin, trGlobals_t::or, refEntity_t::origin, orientationr_t::origin, qboolean, R_LocalNormalToWorld(), R_PlaneForSurface(), R_RotateForEntity(), trGlobals_t::refdef, refEntity_t::reType, drawSurf_s::surface, tr, and trGlobals_t::viewParms.

Referenced by SurfIsOffscreen().

00740 {
00741     int         i;
00742     cplane_t    originalPlane, plane;
00743     trRefEntity_t   *e;
00744     float       d;
00745 
00746     // create plane axis for the portal we are seeing
00747     R_PlaneForSurface( drawSurf->surface, &originalPlane );
00748 
00749     // rotate the plane if necessary
00750     if ( entityNum != ENTITYNUM_WORLD ) 
00751     {
00752         tr.currentEntityNum = entityNum;
00753         tr.currentEntity = &tr.refdef.entities[entityNum];
00754 
00755         // get the orientation of the entity
00756         R_RotateForEntity( tr.currentEntity, &tr.viewParms, &tr.or );
00757 
00758         // rotate the plane, but keep the non-rotated version for matching
00759         // against the portalSurface entities
00760         R_LocalNormalToWorld( originalPlane.normal, plane.normal );
00761         plane.dist = originalPlane.dist + DotProduct( plane.normal, tr.or.origin );
00762 
00763         // translate the original plane
00764         originalPlane.dist = originalPlane.dist + DotProduct( originalPlane.normal, tr.or.origin );
00765     } 
00766     else 
00767     {
00768         plane = originalPlane;
00769     }
00770 
00771     // locate the portal entity closest to this plane.
00772     // origin will be the origin of the portal, origin2 will be
00773     // the origin of the camera
00774     for ( i = 0 ; i < tr.refdef.num_entities ; i++ ) 
00775     {
00776         e = &tr.refdef.entities[i];
00777         if ( e->e.reType != RT_PORTALSURFACE ) {
00778             continue;
00779         }
00780 
00781         d = DotProduct( e->e.origin, originalPlane.normal ) - originalPlane.dist;
00782         if ( d > 64 || d < -64) {
00783             continue;
00784         }
00785 
00786         // if the entity is just a mirror, don't use as a camera point
00787         if ( e->e.oldorigin[0] == e->e.origin[0] && 
00788             e->e.oldorigin[1] == e->e.origin[1] && 
00789             e->e.oldorigin[2] == e->e.origin[2] ) 
00790         {
00791             return qtrue;
00792         }
00793 
00794         return qfalse;
00795     }
00796     return qfalse;
00797 }

Here is the call graph for this function:

void myGlMultMatrix const float *  a,
const float *  b,
float *  out
 

Definition at line 247 of file tr_main.c.

References a, b, i, and j.

Referenced by R_RotateForEntity(), and R_RotateForViewer().

00247                                                                   {
00248     int     i, j;
00249 
00250     for ( i = 0 ; i < 4 ; i++ ) {
00251         for ( j = 0 ; j < 4 ; j++ ) {
00252             out[ i * 4 + j ] =
00253                 a [ i * 4 + 0 ] * b [ 0 * 4 + j ]
00254                 + a [ i * 4 + 1 ] * b [ 1 * 4 + j ]
00255                 + a [ i * 4 + 2 ] * b [ 2 * 4 + j ]
00256                 + a [ i * 4 + 3 ] * b [ 3 * 4 + j ];
00257         }
00258     }
00259 }

void qsortFast void *  base,
unsigned  num,
unsigned  width
 

Definition at line 1035 of file tr_main.c.

References drawSurf_t, ERR_DROP, ri, shortsort(), SWAP_DRAW_SURF, and width.

Referenced by R_SortDrawSurfs().

01040 {
01041     char *lo, *hi;              /* ends of sub-array currently sorting */
01042     char *mid;                  /* points to middle of subarray */
01043     char *loguy, *higuy;        /* traveling pointers for partition step */
01044     unsigned size;              /* size of the sub-array */
01045     char *lostk[30], *histk[30];
01046     int stkptr;                 /* stack for saving sub-array to be processed */
01047     int temp;
01048 
01049     if ( sizeof(drawSurf_t) != 8 ) {
01050         ri.Error( ERR_DROP, "change SWAP_DRAW_SURF macro" );
01051     }
01052 
01053     /* Note: the number of stack entries required is no more than
01054        1 + log2(size), so 30 is sufficient for any array */
01055 
01056     if (num < 2 || width == 0)
01057         return;                 /* nothing to do */
01058 
01059     stkptr = 0;                 /* initialize stack */
01060 
01061     lo = base;
01062     hi = (char *)base + width * (num-1);        /* initialize limits */
01063 
01064     /* this entry point is for pseudo-recursion calling: setting
01065        lo and hi and jumping to here is like recursion, but stkptr is
01066        prserved, locals aren't, so we preserve stuff on the stack */
01067 recurse:
01068 
01069     size = (hi - lo) / width + 1;        /* number of el's to sort */
01070 
01071     /* below a certain size, it is faster to use a O(n^2) sorting method */
01072     if (size <= CUTOFF) {
01073          shortsort((drawSurf_t *)lo, (drawSurf_t *)hi);
01074     }
01075     else {
01076         /* First we pick a partititioning element.  The efficiency of the
01077            algorithm demands that we find one that is approximately the
01078            median of the values, but also that we select one fast.  Using
01079            the first one produces bad performace if the array is already
01080            sorted, so we use the middle one, which would require a very
01081            wierdly arranged array for worst case performance.  Testing shows
01082            that a median-of-three algorithm does not, in general, increase
01083            performance. */
01084 
01085         mid = lo + (size / 2) * width;      /* find middle element */
01086         SWAP_DRAW_SURF(mid, lo);               /* swap it to beginning of array */
01087 
01088         /* We now wish to partition the array into three pieces, one
01089            consisiting of elements <= partition element, one of elements
01090            equal to the parition element, and one of element >= to it.  This
01091            is done below; comments indicate conditions established at every
01092            step. */
01093 
01094         loguy = lo;
01095         higuy = hi + width;
01096 
01097         /* Note that higuy decreases and loguy increases on every iteration,
01098            so loop must terminate. */
01099         for (;;) {
01100             /* lo <= loguy < hi, lo < higuy <= hi + 1,
01101                A[i] <= A[lo] for lo <= i <= loguy,
01102                A[i] >= A[lo] for higuy <= i <= hi */
01103 
01104             do  {
01105                 loguy += width;
01106             } while (loguy <= hi &&  
01107                 ( ((drawSurf_t *)loguy)->sort <= ((drawSurf_t *)lo)->sort ) );
01108 
01109             /* lo < loguy <= hi+1, A[i] <= A[lo] for lo <= i < loguy,
01110                either loguy > hi or A[loguy] > A[lo] */
01111 
01112             do  {
01113                 higuy -= width;
01114             } while (higuy > lo && 
01115                 ( ((drawSurf_t *)higuy)->sort >= ((drawSurf_t *)lo)->sort ) );
01116 
01117             /* lo-1 <= higuy <= hi, A[i] >= A[lo] for higuy < i <= hi,
01118                either higuy <= lo or A[higuy] < A[lo] */
01119 
01120             if (higuy < loguy)
01121                 break;
01122 
01123             /* if loguy > hi or higuy <= lo, then we would have exited, so
01124                A[loguy] > A[lo], A[higuy] < A[lo],
01125                loguy < hi, highy > lo */
01126 
01127             SWAP_DRAW_SURF(loguy, higuy);
01128 
01129             /* A[loguy] < A[lo], A[higuy] > A[lo]; so condition at top
01130                of loop is re-established */
01131         }
01132 
01133         /*     A[i] >= A[lo] for higuy < i <= hi,
01134                A[i] <= A[lo] for lo <= i < loguy,
01135                higuy < loguy, lo <= higuy <= hi
01136            implying:
01137                A[i] >= A[lo] for loguy <= i <= hi,
01138                A[i] <= A[lo] for lo <= i <= higuy,
01139                A[i] = A[lo] for higuy < i < loguy */
01140 
01141         SWAP_DRAW_SURF(lo, higuy);     /* put partition element in place */
01142 
01143         /* OK, now we have the following:
01144               A[i] >= A[higuy] for loguy <= i <= hi,
01145               A[i] <= A[higuy] for lo <= i < higuy
01146               A[i] = A[lo] for higuy <= i < loguy    */
01147 
01148         /* We've finished the partition, now we want to sort the subarrays
01149            [lo, higuy-1] and [loguy, hi].
01150            We do the smaller one first to minimize stack usage.
01151            We only sort arrays of length 2 or more.*/
01152 
01153         if ( higuy - 1 - lo >= hi - loguy ) {
01154             if (lo + width < higuy) {
01155                 lostk[stkptr] = lo;
01156                 histk[stkptr] = higuy - width;
01157                 ++stkptr;
01158             }                           /* save big recursion for later */
01159 
01160             if (loguy < hi) {
01161                 lo = loguy;
01162                 goto recurse;           /* do small recursion */
01163             }
01164         }
01165         else {
01166             if (loguy < hi) {
01167                 lostk[stkptr] = loguy;
01168                 histk[stkptr] = hi;
01169                 ++stkptr;               /* save big recursion for later */
01170             }
01171 
01172             if (lo + width < higuy) {
01173                 hi = higuy - width;
01174                 goto recurse;           /* do small recursion */
01175             }
01176         }
01177     }
01178 
01179     /* We have sorted the array, except for any pending sorts on the stack.
01180        Check if there are any, and do them. */
01181 
01182     --stkptr;
01183     if (stkptr >= 0) {
01184         lo = lostk[stkptr];
01185         hi = histk[stkptr];
01186         goto recurse;           /* pop subarray from stack */
01187     }
01188     else
01189         return;                 /* all subarrays done */
01190 }

Here is the call graph for this function:

void R_AddDrawSurf surfaceType_t surface,
shader_t shader,
int  fogIndex,
int  dlightMap
 

Definition at line 1200 of file tr_main.c.

References trRefdef_t::drawSurfs, trRefdef_t::numDrawSurfs, trGlobals_t::refdef, shader_t, trGlobals_t::shiftedEntityNum, drawSurf_s::sort, shader_s::sortedIndex, drawSurf_s::surface, and tr.

Referenced by R_AddAnimSurfaces(), R_AddEntitySurfaces(), R_AddMD3Surfaces(), R_AddPolygonSurfaces(), and R_AddWorldSurface().

01201                                                  {
01202     int         index;
01203 
01204     // instead of checking for overflow, we just mask the index
01205     // so it wraps around
01206     index = tr.refdef.numDrawSurfs & DRAWSURF_MASK;
01207     // the sort data is packed into a single 32 bit value so it can be
01208     // compared quickly during the qsorting process
01209     tr.refdef.drawSurfs[index].sort = (shader->sortedIndex << QSORT_SHADERNUM_SHIFT) 
01210         | tr.shiftedEntityNum | ( fogIndex << QSORT_FOGNUM_SHIFT ) | (int)dlightMap;
01211     tr.refdef.drawSurfs[index].surface = surface;
01212     tr.refdef.numDrawSurfs++;
01213 }

void R_AddEntitySurfaces void   ) 
 

Definition at line 1289 of file tr_main.c.

References trGlobals_t::currentEntity, trGlobals_t::currentEntityNum, trGlobals_t::currentModel, refEntity_t::customShader, trGlobals_t::defaultShader, trRefEntity_t::e, trRefdef_t::entities, entitySurface, ERR_DROP, refEntity_t::hModel, cvar_s::integer, viewParms_t::isPortal, MOD_BAD, MOD_BRUSH, MOD_MD4, MOD_MESH, trRefEntity_t::needDlights, trRefdef_t::num_entities, trGlobals_t::or, R_AddAnimSurfaces(), R_AddBrushModelSurfaces(), R_AddDrawSurf(), R_AddMD3Surfaces(), r_drawentities, R_GetModelByHandle(), R_GetShaderByHandle(), R_RotateForEntity(), R_SpriteFogNum(), trGlobals_t::refdef, refEntity_t::renderfx, refEntity_t::reType, ri, RT_BEAM, RT_LIGHTNING, RT_MODEL, RT_PORTALSURFACE, RT_RAIL_CORE, RT_RAIL_RINGS, RT_SPRITE, shader_t, trGlobals_t::shiftedEntityNum, tr, model_s::type, and trGlobals_t::viewParms.

Referenced by R_GenerateDrawSurfs().

01289                                 {
01290     trRefEntity_t   *ent;
01291     shader_t        *shader;
01292 
01293     if ( !r_drawentities->integer ) {
01294         return;
01295     }
01296 
01297     for ( tr.currentEntityNum = 0; 
01298           tr.currentEntityNum < tr.refdef.num_entities; 
01299           tr.currentEntityNum++ ) {
01300         ent = tr.currentEntity = &tr.refdef.entities[tr.currentEntityNum];
01301 
01302         ent->needDlights = qfalse;
01303 
01304         // preshift the value we are going to OR into the drawsurf sort
01305         tr.shiftedEntityNum = tr.currentEntityNum << QSORT_ENTITYNUM_SHIFT;
01306 
01307         //
01308         // the weapon model must be handled special --
01309         // we don't want the hacked weapon position showing in 
01310         // mirrors, because the true body position will already be drawn
01311         //
01312         if ( (ent->e.renderfx & RF_FIRST_PERSON) && tr.viewParms.isPortal) {
01313             continue;
01314         }
01315 
01316         // simple generated models, like sprites and beams, are not culled
01317         switch ( ent->e.reType ) {
01318         case RT_PORTALSURFACE:
01319             break;      // don't draw anything
01320         case RT_SPRITE:
01321         case RT_BEAM:
01322         case RT_LIGHTNING:
01323         case RT_RAIL_CORE:
01324         case RT_RAIL_RINGS:
01325             // self blood sprites, talk balloons, etc should not be drawn in the primary
01326             // view.  We can't just do this check for all entities, because md3
01327             // entities may still want to cast shadows from them
01328             if ( (ent->e.renderfx & RF_THIRD_PERSON) && !tr.viewParms.isPortal) {
01329                 continue;
01330             }
01331             shader = R_GetShaderByHandle( ent->e.customShader );
01332             R_AddDrawSurf( &entitySurface, shader, R_SpriteFogNum( ent ), 0 );
01333             break;
01334 
01335         case RT_MODEL:
01336             // we must set up parts of tr.or for model culling
01337             R_RotateForEntity( ent, &tr.viewParms, &tr.or );
01338 
01339             tr.currentModel = R_GetModelByHandle( ent->e.hModel );
01340             if (!tr.currentModel) {
01341                 R_AddDrawSurf( &entitySurface, tr.defaultShader, 0, 0 );
01342             } else {
01343                 switch ( tr.currentModel->type ) {
01344                 case MOD_MESH:
01345                     R_AddMD3Surfaces( ent );
01346                     break;
01347                 case MOD_MD4:
01348                     R_AddAnimSurfaces( ent );
01349                     break;
01350                 case MOD_BRUSH:
01351                     R_AddBrushModelSurfaces( ent );
01352                     break;
01353                 case MOD_BAD:       // null model axis
01354                     if ( (ent->e.renderfx & RF_THIRD_PERSON) && !tr.viewParms.isPortal) {
01355                         break;
01356                     }
01357                     shader = R_GetShaderByHandle( ent->e.customShader );
01358                     R_AddDrawSurf( &entitySurface, tr.defaultShader, 0, 0 );
01359                     break;
01360                 default:
01361                     ri.Error( ERR_DROP, "R_AddEntitySurfaces: Bad modeltype" );
01362                     break;
01363                 }
01364             }
01365             break;
01366         default:
01367             ri.Error( ERR_DROP, "R_AddEntitySurfaces: Bad reType" );
01368         }
01369     }
01370 
01371 }

Here is the call graph for this function:

int R_CullLocalBox vec3_t  bounds[2]  ) 
 

Definition at line 51 of file tr_main.c.

References orientationr_t::axis, cplane_t, cplane_s::dist, DotProduct, viewParms_t::frustum, i, cvar_s::integer, j, cplane_s::normal, trGlobals_t::or, orientationr_t::origin, r_nocull, tr, v, vec3_t, VectorCopy, VectorMA, and trGlobals_t::viewParms.

Referenced by R_AddBrushModelSurfaces(), R_CullGrid(), R_CullModel(), and R_CullTriSurf().

00051                                       {
00052     int     i, j;
00053     vec3_t  transformed[8];
00054     float   dists[8];
00055     vec3_t  v;
00056     cplane_t    *frust;
00057     int         anyBack;
00058     int         front, back;
00059 
00060     if ( r_nocull->integer ) {
00061         return CULL_CLIP;
00062     }
00063 
00064     // transform into world space
00065     for (i = 0 ; i < 8 ; i++) {
00066         v[0] = bounds[i&1][0];
00067         v[1] = bounds[(i>>1)&1][1];
00068         v[2] = bounds[(i>>2)&1][2];
00069 
00070         VectorCopy( tr.or.origin, transformed[i] );
00071         VectorMA( transformed[i], v[0], tr.or.axis[0], transformed[i] );
00072         VectorMA( transformed[i], v[1], tr.or.axis[1], transformed[i] );
00073         VectorMA( transformed[i], v[2], tr.or.axis[2], transformed[i] );
00074     }
00075 
00076     // check against frustum planes
00077     anyBack = 0;
00078     for (i = 0 ; i < 4 ; i++) {
00079         frust = &tr.viewParms.frustum[i];
00080 
00081         front = back = 0;
00082         for (j = 0 ; j < 8 ; j++) {
00083             dists[j] = DotProduct(transformed[j], frust->normal);
00084             if ( dists[j] > frust->dist ) {
00085                 front = 1;
00086                 if ( back ) {
00087                     break;      // a point is in front
00088                 }
00089             } else {
00090                 back = 1;
00091             }
00092         }
00093         if ( !front ) {
00094             // all points were behind one of the planes
00095             return CULL_OUT;
00096         }
00097         anyBack |= back;
00098     }
00099 
00100     if ( !anyBack ) {
00101         return CULL_IN;     // completely inside frustum
00102     }
00103 
00104     return CULL_CLIP;       // partially clipped
00105 }

int R_CullLocalPointAndRadius vec3_t  pt,
float  radius
 

Definition at line 110 of file tr_main.c.

References R_CullPointAndRadius(), R_LocalPointToWorld(), and vec3_t.

Referenced by R_CullGrid(), and R_CullModel().

00111 {
00112     vec3_t transformed;
00113 
00114     R_LocalPointToWorld( pt, transformed );
00115 
00116     return R_CullPointAndRadius( transformed, radius );
00117 }

Here is the call graph for this function:

int R_CullPointAndRadius vec3_t  pt,
float  radius
 

Definition at line 122 of file tr_main.c.

References cplane_t, cplane_s::dist, DotProduct, viewParms_t::frustum, i, cvar_s::integer, cplane_s::normal, qboolean, r_nocull, tr, and trGlobals_t::viewParms.

Referenced by R_CullGrid(), and R_CullLocalPointAndRadius().

00123 {
00124     int     i;
00125     float   dist;
00126     cplane_t    *frust;
00127     qboolean mightBeClipped = qfalse;
00128 
00129     if ( r_nocull->integer ) {
00130         return CULL_CLIP;
00131     }
00132 
00133     // check against frustum planes
00134     for (i = 0 ; i < 4 ; i++) 
00135     {
00136         frust = &tr.viewParms.frustum[i];
00137 
00138         dist = DotProduct( pt, frust->normal) - frust->dist;
00139         if ( dist < -radius )
00140         {
00141             return CULL_OUT;
00142         }
00143         else if ( dist <= radius ) 
00144         {
00145             mightBeClipped = qtrue;
00146         }
00147     }
00148 
00149     if ( mightBeClipped )
00150     {
00151         return CULL_CLIP;
00152     }
00153 
00154     return CULL_IN;     // completely inside frustum
00155 }

void R_DebugGraphics void   ) 
 

Definition at line 1432 of file tr_main.c.

References refimport_t::CM_DrawDebugSurface, CT_FRONT_SIDED, GL_Bind(), GL_Cull(), cvar_s::integer, R_DebugPolygon(), r_debugSurface, R_SyncRenderThread(), ri, tr, and trGlobals_t::whiteImage.

Referenced by R_RenderView().

01432                              {
01433     if ( !r_debugSurface->integer ) {
01434         return;
01435     }
01436 
01437     // the render thread can't make callbacks to the main thread
01438     R_SyncRenderThread();
01439 
01440     GL_Bind( tr.whiteImage);
01441     GL_Cull( CT_FRONT_SIDED );
01442     ri.CM_DrawDebugSurface( R_DebugPolygon );
01443 }

Here is the call graph for this function:

void R_DebugPolygon int  color,
int  numPoints,
float *  points
 

Definition at line 1399 of file tr_main.c.

References GL_State(), GLS_DEPTHMASK_TRUE, GLS_DSTBLEND_ONE, GLS_POLYMODE_LINE, GLS_SRCBLEND_ONE, i, points, qglBegin, qglColor3f, qglDepthRange, qglEnd, and qglVertex3fv.

Referenced by R_DebugGraphics().

01399                                                                {
01400     int     i;
01401 
01402     GL_State( GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
01403 
01404     // draw solid shade
01405 
01406     qglColor3f( color&1, (color>>1)&1, (color>>2)&1 );
01407     qglBegin( GL_POLYGON );
01408     for ( i = 0 ; i < numPoints ; i++ ) {
01409         qglVertex3fv( points + i * 3 );
01410     }
01411     qglEnd();
01412 
01413     // draw wireframe outline
01414     GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
01415     qglDepthRange( 0, 0 );
01416     qglColor3f( 1, 1, 1 );
01417     qglBegin( GL_POLYGON );
01418     for ( i = 0 ; i < numPoints ; i++ ) {
01419         qglVertex3fv( points + i * 3 );
01420     }
01421     qglEnd();
01422     qglDepthRange( 0, 1 );
01423 }

Here is the call graph for this function:

void R_DecomposeSort unsigned  sort,
int *  entityNum,
shader_t **  shader,
int *  fogNum,
int *  dlightMap
 

Definition at line 1220 of file tr_main.c.

References MAX_SHADERS, shader_t, sort(), trGlobals_t::sortedShaders, and tr.

Referenced by FixRenderCommandList(), R_SortDrawSurfs(), RB_RenderDrawSurfList(), and SurfIsOffscreen().

01221                                                    {
01222     *fogNum = ( sort >> QSORT_FOGNUM_SHIFT ) & 31;
01223     *shader = tr.sortedShaders[ ( sort >> QSORT_SHADERNUM_SHIFT ) & (MAX_SHADERS-1) ];
01224     *entityNum = ( sort >> QSORT_ENTITYNUM_SHIFT ) & 1023;
01225     *dlightMap = sort & 3;
01226 }

Here is the call graph for this function:

void R_GenerateDrawSurfs void   ) 
 

Definition at line 1379 of file tr_main.c.

References R_AddEntitySurfaces(), R_AddPolygonSurfaces(), R_AddWorldSurfaces(), and R_SetupProjection().

Referenced by R_RenderView().

01379                                  {
01380     R_AddWorldSurfaces ();
01381 
01382     R_AddPolygonSurfaces();
01383 
01384     // set the projection matrix with the minimum zfar
01385     // now that we have the world bounded
01386     // this needs to be done before entities are
01387     // added, because they use the projection
01388     // matrix for lod calculation
01389     R_SetupProjection ();
01390 
01391     R_AddEntitySurfaces ();
01392 }

Here is the call graph for this function:

qboolean R_GetPortalOrientations drawSurf_t drawSurf,
int  entityNum,
orientation_t surface,
orientation_t camera,
vec3_t  pvsOrigin,
qboolean mirror
 

Definition at line 620 of file tr_main.c.

References refEntity_t::axis, orientation_t::axis, AxisCopy(), camera, cplane_t, CrossProduct(), trGlobals_t::currentEntity, trGlobals_t::currentEntityNum, d, cplane_s::dist, DotProduct, drawSurf_t, trRefEntity_t::e, e, trRefdef_t::entities, refEntity_t::frame, i, cplane_s::normal, trRefdef_t::num_entities, refEntity_t::oldframe, refEntity_t::oldorigin, trGlobals_t::or, orientation_t::origin, refEntity_t::origin, orientationr_t::origin, PerpendicularVector(), qboolean, R_LocalNormalToWorld(), R_PlaneForSurface(), R_RotateForEntity(), trGlobals_t::refdef, refEntity_t::reType, RotatePointAroundVector(), sin(), refEntity_t::skinNum, drawSurf_s::surface, trRefdef_t::time, tr, vec3_origin, vec3_t, VectorCopy, VectorMA, VectorScale, VectorSubtract, and trGlobals_t::viewParms.

Referenced by R_MirrorViewBySurface().

00622                                                                   {
00623     int         i;
00624     cplane_t    originalPlane, plane;
00625     trRefEntity_t   *e;
00626     float       d;
00627     vec3_t      transformed;
00628 
00629     // create plane axis for the portal we are seeing
00630     R_PlaneForSurface( drawSurf->surface, &originalPlane );
00631 
00632     // rotate the plane if necessary
00633     if ( entityNum != ENTITYNUM_WORLD ) {
00634         tr.currentEntityNum = entityNum;
00635         tr.currentEntity = &tr.refdef.entities[entityNum];
00636 
00637         // get the orientation of the entity
00638         R_RotateForEntity( tr.currentEntity, &tr.viewParms, &tr.or );
00639 
00640         // rotate the plane, but keep the non-rotated version for matching
00641         // against the portalSurface entities
00642         R_LocalNormalToWorld( originalPlane.normal, plane.normal );
00643         plane.dist = originalPlane.dist + DotProduct( plane.normal, tr.or.origin );
00644 
00645         // translate the original plane
00646         originalPlane.dist = originalPlane.dist + DotProduct( originalPlane.normal, tr.or.origin );
00647     } else {
00648         plane = originalPlane;
00649     }
00650 
00651     VectorCopy( plane.normal, surface->axis[0] );
00652     PerpendicularVector( surface->axis[1], surface->axis[0] );
00653     CrossProduct( surface->axis[0], surface->axis[1], surface->axis[2] );
00654 
00655     // locate the portal entity closest to this plane.
00656     // origin will be the origin of the portal, origin2 will be
00657     // the origin of the camera
00658     for ( i = 0 ; i < tr.refdef.num_entities ; i++ ) {
00659         e = &tr.refdef.entities[i];
00660         if ( e->e.reType != RT_PORTALSURFACE ) {
00661             continue;
00662         }
00663 
00664         d = DotProduct( e->e.origin, originalPlane.normal ) - originalPlane.dist;
00665         if ( d > 64 || d < -64) {
00666             continue;
00667         }
00668 
00669         // get the pvsOrigin from the entity
00670         VectorCopy( e->e.oldorigin, pvsOrigin );
00671 
00672         // if the entity is just a mirror, don't use as a camera point
00673         if ( e->e.oldorigin[0] == e->e.origin[0] && 
00674             e->e.oldorigin[1] == e->e.origin[1] && 
00675             e->e.oldorigin[2] == e->e.origin[2] ) {
00676             VectorScale( plane.normal, plane.dist, surface->origin );
00677             VectorCopy( surface->origin, camera->origin );
00678             VectorSubtract( vec3_origin, surface->axis[0], camera->axis[0] );
00679             VectorCopy( surface->axis[1], camera->axis[1] );
00680             VectorCopy( surface->axis[2], camera->axis[2] );
00681 
00682             *mirror = qtrue;
00683             return qtrue;
00684         }
00685 
00686         // project the origin onto the surface plane to get
00687         // an origin point we can rotate around
00688         d = DotProduct( e->e.origin, plane.normal ) - plane.dist;
00689         VectorMA( e->e.origin, -d, surface->axis[0], surface->origin );
00690             
00691         // now get the camera origin and orientation
00692         VectorCopy( e->e.oldorigin, camera->origin );
00693         AxisCopy( e->e.axis, camera->axis );
00694         VectorSubtract( vec3_origin, camera->axis[0], camera->axis[0] );
00695         VectorSubtract( vec3_origin, camera->axis[1], camera->axis[1] );
00696 
00697         // optionally rotate
00698         if ( e->e.oldframe ) {
00699             // if a speed is specified
00700             if ( e->e.frame ) {
00701                 // continuous rotate
00702                 d = (tr.refdef.time/1000.0f) * e->e.frame;
00703                 VectorCopy( camera->axis[1], transformed );
00704                 RotatePointAroundVector( camera->axis[1], camera->axis[0], transformed, d );
00705                 CrossProduct( camera->axis[0], camera->axis[1], camera->axis[2] );
00706             } else {
00707                 // bobbing rotate, with skinNum being the rotation offset
00708                 d = sin( tr.refdef.time * 0.003f );
00709                 d = e->e.skinNum + d * 4;
00710                 VectorCopy( camera->axis[1], transformed );
00711                 RotatePointAroundVector( camera->axis[1], camera->axis[0], transformed, d );
00712                 CrossProduct( camera->axis[0], camera->axis[1], camera->axis[2] );
00713             }
00714         }
00715         else if ( e->e.skinNum ) {
00716             d = e->e.skinNum;
00717             VectorCopy( camera->axis[1], transformed );
00718             RotatePointAroundVector( camera->axis[1], camera->axis[0], transformed, d );
00719             CrossProduct( camera->axis[0], camera->axis[1], camera->axis[2] );
00720         }
00721         *mirror = qfalse;
00722         return qtrue;
00723     }
00724 
00725     // if we didn't locate a portal entity, don't render anything.
00726     // We don't want to just treat it as a mirror, because without a
00727     // portal entity the server won't have communicated a proper entity set
00728     // in the snapshot
00729 
00730     // unfortunately, with local movement prediction it is easily possible
00731     // to see a surface before the server has communicated the matching
00732     // portal surface entity, so we don't want to print anything here...
00733 
00734     //ri.Printf( PRINT_ALL, "Portal surface without a portal entity\n" );
00735 
00736     return qfalse;
00737 }

Here is the call graph for this function:

void R_LocalNormalToWorld vec3_t  local,
vec3_t  world
 

Definition at line 164 of file tr_main.c.

References orientationr_t::axis, trGlobals_t::or, and tr.

Referenced by IsMirror(), and R_GetPortalOrientations().

00164                                                        {
00165     world[0] = local[0] * tr.or.axis[0][0] + local[1] * tr.or.axis[1][0] + local[2] * tr.or.axis[2][0];
00166     world[1] = local[0] * tr.or.axis[0][1] + local[1] * tr.or.axis[1][1] + local[2] * tr.or.axis[2][1];
00167     world[2] = local[0] * tr.or.axis[0][2] + local[1] * tr.or.axis[1][2] + local[2] * tr.or.axis[2][2];
00168 }

void R_LocalPointToWorld vec3_t  local,
vec3_t  world
 

Definition at line 176 of file tr_main.c.

References orientationr_t::axis, trGlobals_t::or, orientationr_t::origin, and tr.

Referenced by R_CullLocalPointAndRadius().

00176                                                       {
00177     world[0] = local[0] * tr.or.axis[0][0] + local[1] * tr.or.axis[1][0] + local[2] * tr.or.axis[2][0] + tr.or.origin[0];
00178     world[1] = local[0] * tr.or.axis[0][1] + local[1] * tr.or.axis[1][1] + local[2] * tr.or.axis[2][1] + tr.or.origin[1];
00179     world[2] = local[0] * tr.or.axis[0][2] + local[1] * tr.or.