?? r_main.c
字號:
} while (node);
}
}
#if 0
for (i=0 ; i<r_worldmodel->vis->numclusters ; i++)
{
if (vis[i>>3] & (1<<(i&7)))
{
node = (mnode_t *)&r_worldmodel->leafs[i]; // FIXME: cluster
do
{
if (node->visframe == r_visframecount)
break;
node->visframe = r_visframecount;
node = node->parent;
} while (node);
}
}
#endif
}
/*
** R_DrawNullModel
**
** IMPLEMENT THIS!
*/
void R_DrawNullModel( void )
{
}
/*
=============
R_DrawEntitiesOnList
=============
*/
void R_DrawEntitiesOnList (void)
{
int i;
qboolean translucent_entities = false;
if (!r_drawentities->value)
return;
// all bmodels have already been drawn by the edge list
for (i=0 ; i<r_newrefdef.num_entities ; i++)
{
currententity = &r_newrefdef.entities[i];
if ( currententity->flags & RF_TRANSLUCENT )
{
translucent_entities = true;
continue;
}
if ( currententity->flags & RF_BEAM )
{
modelorg[0] = -r_origin[0];
modelorg[1] = -r_origin[1];
modelorg[2] = -r_origin[2];
VectorCopy( vec3_origin, r_entorigin );
R_DrawBeam( currententity );
}
else
{
currentmodel = currententity->model;
if (!currentmodel)
{
R_DrawNullModel();
continue;
}
VectorCopy (currententity->origin, r_entorigin);
VectorSubtract (r_origin, r_entorigin, modelorg);
switch (currentmodel->type)
{
case mod_sprite:
R_DrawSprite ();
break;
case mod_alias:
R_AliasDrawModel ();
break;
default:
break;
}
}
}
if ( !translucent_entities )
return;
for (i=0 ; i<r_newrefdef.num_entities ; i++)
{
currententity = &r_newrefdef.entities[i];
if ( !( currententity->flags & RF_TRANSLUCENT ) )
continue;
if ( currententity->flags & RF_BEAM )
{
modelorg[0] = -r_origin[0];
modelorg[1] = -r_origin[1];
modelorg[2] = -r_origin[2];
VectorCopy( vec3_origin, r_entorigin );
R_DrawBeam( currententity );
}
else
{
currentmodel = currententity->model;
if (!currentmodel)
{
R_DrawNullModel();
continue;
}
VectorCopy (currententity->origin, r_entorigin);
VectorSubtract (r_origin, r_entorigin, modelorg);
switch (currentmodel->type)
{
case mod_sprite:
R_DrawSprite ();
break;
case mod_alias:
R_AliasDrawModel ();
break;
default:
break;
}
}
}
}
/*
=============
R_BmodelCheckBBox
=============
*/
int R_BmodelCheckBBox (float *minmaxs)
{
int i, *pindex, clipflags;
vec3_t acceptpt, rejectpt;
float d;
clipflags = 0;
for (i=0 ; i<4 ; i++)
{
// generate accept and reject points
// FIXME: do with fast look-ups or integer tests based on the sign bit
// of the floating point values
pindex = pfrustum_indexes[i];
rejectpt[0] = minmaxs[pindex[0]];
rejectpt[1] = minmaxs[pindex[1]];
rejectpt[2] = minmaxs[pindex[2]];
d = DotProduct (rejectpt, view_clipplanes[i].normal);
d -= view_clipplanes[i].dist;
if (d <= 0)
return BMODEL_FULLY_CLIPPED;
acceptpt[0] = minmaxs[pindex[3+0]];
acceptpt[1] = minmaxs[pindex[3+1]];
acceptpt[2] = minmaxs[pindex[3+2]];
d = DotProduct (acceptpt, view_clipplanes[i].normal);
d -= view_clipplanes[i].dist;
if (d <= 0)
clipflags |= (1<<i);
}
return clipflags;
}
/*
===================
R_FindTopnode
Find the first node that splits the given box
===================
*/
mnode_t *R_FindTopnode (vec3_t mins, vec3_t maxs)
{
mplane_t *splitplane;
int sides;
mnode_t *node;
node = r_worldmodel->nodes;
while (1)
{
if (node->visframe != r_visframecount)
return NULL; // not visible at all
if (node->contents != CONTENTS_NODE)
{
if (node->contents != CONTENTS_SOLID)
return node; // we've reached a non-solid leaf, so it's
// visible and not BSP clipped
return NULL; // in solid, so not visible
}
splitplane = node->plane;
sides = BOX_ON_PLANE_SIDE(mins, maxs, (cplane_t *)splitplane);
if (sides == 3)
return node; // this is the splitter
// not split yet; recurse down the contacted side
if (sides & 1)
node = node->children[0];
else
node = node->children[1];
}
}
/*
=============
RotatedBBox
Returns an axially aligned box that contains the input box at the given rotation
=============
*/
void RotatedBBox (vec3_t mins, vec3_t maxs, vec3_t angles, vec3_t tmins, vec3_t tmaxs)
{
vec3_t tmp, v;
int i, j;
vec3_t forward, right, up;
if (!angles[0] && !angles[1] && !angles[2])
{
VectorCopy (mins, tmins);
VectorCopy (maxs, tmaxs);
return;
}
for (i=0 ; i<3 ; i++)
{
tmins[i] = 99999;
tmaxs[i] = -99999;
}
AngleVectors (angles, forward, right, up);
for ( i = 0; i < 8; i++ )
{
if ( i & 1 )
tmp[0] = mins[0];
else
tmp[0] = maxs[0];
if ( i & 2 )
tmp[1] = mins[1];
else
tmp[1] = maxs[1];
if ( i & 4 )
tmp[2] = mins[2];
else
tmp[2] = maxs[2];
VectorScale (forward, tmp[0], v);
VectorMA (v, -tmp[1], right, v);
VectorMA (v, tmp[2], up, v);
for (j=0 ; j<3 ; j++)
{
if (v[j] < tmins[j])
tmins[j] = v[j];
if (v[j] > tmaxs[j])
tmaxs[j] = v[j];
}
}
}
/*
=============
R_DrawBEntitiesOnList
=============
*/
void R_DrawBEntitiesOnList (void)
{
int i, clipflags;
vec3_t oldorigin;
vec3_t mins, maxs;
float minmaxs[6];
mnode_t *topnode;
if (!r_drawentities->value)
return;
VectorCopy (modelorg, oldorigin);
insubmodel = true;
r_dlightframecount = r_framecount;
for (i=0 ; i<r_newrefdef.num_entities ; i++)
{
currententity = &r_newrefdef.entities[i];
currentmodel = currententity->model;
if (!currentmodel)
continue;
if (currentmodel->nummodelsurfaces == 0)
continue; // clip brush only
if ( currententity->flags & RF_BEAM )
continue;
if (currentmodel->type != mod_brush)
continue;
// see if the bounding box lets us trivially reject, also sets
// trivial accept status
RotatedBBox (currentmodel->mins, currentmodel->maxs,
currententity->angles, mins, maxs);
VectorAdd (mins, currententity->origin, minmaxs);
VectorAdd (maxs, currententity->origin, (minmaxs+3));
clipflags = R_BmodelCheckBBox (minmaxs);
if (clipflags == BMODEL_FULLY_CLIPPED)
continue; // off the edge of the screen
topnode = R_FindTopnode (minmaxs, minmaxs+3);
if (!topnode)
continue; // no part in a visible leaf
VectorCopy (currententity->origin, r_entorigin);
VectorSubtract (r_origin, r_entorigin, modelorg);
r_pcurrentvertbase = currentmodel->vertexes;
// FIXME: stop transforming twice
R_RotateBmodel ();
// calculate dynamic lighting for bmodel
R_PushDlights (currentmodel);
if (topnode->contents == CONTENTS_NODE)
{
// not a leaf; has to be clipped to the world BSP
r_clipflags = clipflags;
R_DrawSolidClippedSubmodelPolygons (currentmodel, topnode);
}
else
{
// falls entirely in one leaf, so we just put all the
// edges in the edge list and let 1/z sorting handle
// drawing order
R_DrawSubmodelPolygons (currentmodel, clipflags, topnode);
}
// put back world rotation and frustum clipping
// FIXME: R_RotateBmodel should just work off base_vxx
VectorCopy (base_vpn, vpn);
VectorCopy (base_vup, vup);
VectorCopy (base_vright, vright);
VectorCopy (oldorigin, modelorg);
R_TransformFrustum ();
}
insubmodel = false;
}
/*
================
R_EdgeDrawing
================
*/
void R_EdgeDrawing (void)
{
edge_t ledges[NUMSTACKEDGES +
((CACHE_SIZE - 1) / sizeof(edge_t)) + 1];
surf_t lsurfs[NUMSTACKSURFACES +
((CACHE_SIZE - 1) / sizeof(surf_t)) + 1];
if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
return;
if (auxedges)
{
r_edges = auxedges;
}
else
{
r_edges = (edge_t *)
(((long)&ledges[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
}
if (r_surfsonstack)
{
surfaces = (surf_t *)
(((long)&lsurfs[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
surf_max = &surfaces[r_cnumsurfs];
// surface 0 doesn't really exist; it's just a dummy because index 0
// is used to indicate no edge attached to surface
surfaces--;
R_SurfacePatch ();
}
R_BeginEdgeFrame ();
if (r_dspeeds->value)
{
rw_time1 = Sys_Milliseconds ();
}
R_RenderWorld ();
if (r_dspeeds->value)
{
rw_time2 = Sys_Milliseconds ();
db_time1 = rw_time2;
}
R_DrawBEntitiesOnList ();
if (r_dspeeds->value)
{
db_time2 = Sys_Milliseconds ();
se_time1 = db_time2;
}
R_ScanEdges ();
}
//=======================================================================
/*
=============
R_CalcPalette
=============
*/
void R_CalcPalette (void)
{
static qboolean modified;
byte palette[256][4], *in, *out;
int i, j;
float alpha, one_minus_alpha;
vec3_t premult;
int v;
alpha = r_newrefdef.blend[3];
if (alpha <= 0)
{
if (modified)
{ // set back to default
modified = false;
R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
return;
}
return;
}
modified = true;
if (alpha > 1)
alpha = 1;
premult[0] = r_newrefdef.blend[0]*alpha*255;
premult[1] = r_newrefdef.blend[1]*alpha*255;
premult[2] = r_newrefdef.blend[2]*alpha*255;
one_minus_alpha = (1.0 - alpha);
in = (byte *)d_8to24table;
out = palette[0];
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -