📄 r_alias.c
字号:
// TODO: should be global, set when vright, etc., set
VectorCopy (vright, viewmatrix[0]);
VectorCopy (vup, viewmatrix[1]);
VectorInverse (viewmatrix[1]);
VectorCopy (vpn, viewmatrix[2]);
// viewmatrix[0][3] = 0;
// viewmatrix[1][3] = 0;
// viewmatrix[2][3] = 0;
R_ConcatTransforms (viewmatrix, rotationmatrix, aliastransform);
// do the scaling up of x and y to screen coordinates as part of the transform
// for the unclipped case (it would mess up clipping in the clipped case).
// Also scale down z, so 1/z is scaled 31 bits for free, and scale down x and y
// correspondingly so the projected x and y come out right
// FIXME: make this work for clipped case too?
if (trivial_accept)
{
for (i=0 ; i<4 ; i++)
{
aliastransform[0][i] *= aliasxscale *
(1.0 / ((float)0x8000 * 0x10000));
aliastransform[1][i] *= aliasyscale *
(1.0 / ((float)0x8000 * 0x10000));
aliastransform[2][i] *= 1.0 / ((float)0x8000 * 0x10000);
}
}
}
/*
================
R_AliasTransformFinalVert
================
*/
void R_AliasTransformFinalVert (finalvert_t *fv, auxvert_t *av,
trivertx_t *pverts, stvert_t *pstverts)
{
int temp;
float lightcos, *plightnormal;
av->fv[0] = DotProduct(pverts->v, aliastransform[0]) +
aliastransform[0][3];
av->fv[1] = DotProduct(pverts->v, aliastransform[1]) +
aliastransform[1][3];
av->fv[2] = DotProduct(pverts->v, aliastransform[2]) +
aliastransform[2][3];
fv->v[2] = pstverts->s;
fv->v[3] = pstverts->t;
fv->flags = pstverts->onseam;
// lighting
plightnormal = r_avertexnormals[pverts->lightnormalindex];
lightcos = DotProduct (plightnormal, r_plightvec);
temp = r_ambientlight;
if (lightcos < 0)
{
temp += (int)(r_shadelight * lightcos);
// clamp; because we limited the minimum ambient and shading light, we
// don't have to clamp low light, just bright
if (temp < 0)
temp = 0;
}
fv->v[4] = temp;
}
#if !id386
/*
================
R_AliasTransformAndProjectFinalVerts
================
*/
void R_AliasTransformAndProjectFinalVerts (finalvert_t *fv, stvert_t *pstverts)
{
int i, temp;
float lightcos, *plightnormal, zi;
trivertx_t *pverts;
pverts = r_apverts;
for (i=0 ; i<r_anumverts ; i++, fv++, pverts++, pstverts++)
{
// transform and project
zi = 1.0 / (DotProduct(pverts->v, aliastransform[2]) +
aliastransform[2][3]);
// x, y, and z are scaled down by 1/2**31 in the transform, so 1/z is
// scaled up by 1/2**31, and the scaling cancels out for x and y in the
// projection
fv->v[5] = zi;
fv->v[0] = ((DotProduct(pverts->v, aliastransform[0]) +
aliastransform[0][3]) * zi) + aliasxcenter;
fv->v[1] = ((DotProduct(pverts->v, aliastransform[1]) +
aliastransform[1][3]) * zi) + aliasycenter;
fv->v[2] = pstverts->s;
fv->v[3] = pstverts->t;
fv->flags = pstverts->onseam;
// lighting
plightnormal = r_avertexnormals[pverts->lightnormalindex];
lightcos = DotProduct (plightnormal, r_plightvec);
temp = r_ambientlight;
if (lightcos < 0)
{
temp += (int)(r_shadelight * lightcos);
// clamp; because we limited the minimum ambient and shading light, we
// don't have to clamp low light, just bright
if (temp < 0)
temp = 0;
}
fv->v[4] = temp;
}
}
#endif
/*
================
R_AliasProjectFinalVert
================
*/
void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av)
{
float zi;
// project points
zi = 1.0 / av->fv[2];
fv->v[5] = zi * ziscale;
fv->v[0] = (av->fv[0] * aliasxscale * zi) + aliasxcenter;
fv->v[1] = (av->fv[1] * aliasyscale * zi) + aliasycenter;
}
/*
================
R_AliasPrepareUnclippedPoints
================
*/
void R_AliasPrepareUnclippedPoints (void)
{
stvert_t *pstverts;
finalvert_t *fv;
pstverts = (stvert_t *)((byte *)paliashdr + paliashdr->stverts);
r_anumverts = pmdl->numverts;
// FIXME: just use pfinalverts directly?
fv = pfinalverts;
R_AliasTransformAndProjectFinalVerts (fv, pstverts);
if (r_affinetridesc.drawtype)
D_PolysetDrawFinalVerts (fv, r_anumverts);
r_affinetridesc.pfinalverts = pfinalverts;
r_affinetridesc.ptriangles = (mtriangle_t *)
((byte *)paliashdr + paliashdr->triangles);
r_affinetridesc.numtriangles = pmdl->numtris;
D_PolysetDraw ();
}
/*
===============
R_AliasSetupSkin
===============
*/
void R_AliasSetupSkin (void)
{
int skinnum;
int i, numskins;
maliasskingroup_t *paliasskingroup;
float *pskinintervals, fullskininterval;
float skintargettime, skintime;
skinnum = currententity->skinnum;
if ((skinnum >= pmdl->numskins) || (skinnum < 0))
{
Con_DPrintf ("R_AliasSetupSkin: no such skin # %d\n", skinnum);
skinnum = 0;
}
pskindesc = ((maliasskindesc_t *)
((byte *)paliashdr + paliashdr->skindesc)) + skinnum;
a_skinwidth = pmdl->skinwidth;
if (pskindesc->type == ALIAS_SKIN_GROUP)
{
paliasskingroup = (maliasskingroup_t *)((byte *)paliashdr +
pskindesc->skin);
pskinintervals = (float *)
((byte *)paliashdr + paliasskingroup->intervals);
numskins = paliasskingroup->numskins;
fullskininterval = pskinintervals[numskins-1];
skintime = cl.time + currententity->syncbase;
// when loading in Mod_LoadAliasSkinGroup, we guaranteed all interval
// values are positive, so we don't have to worry about division by 0
skintargettime = skintime -
((int)(skintime / fullskininterval)) * fullskininterval;
for (i=0 ; i<(numskins-1) ; i++)
{
if (pskinintervals[i] > skintargettime)
break;
}
pskindesc = &paliasskingroup->skindescs[i];
}
r_affinetridesc.pskindesc = pskindesc;
r_affinetridesc.pskin = (void *)((byte *)paliashdr + pskindesc->skin);
r_affinetridesc.skinwidth = a_skinwidth;
r_affinetridesc.seamfixupX16 = (a_skinwidth >> 1) << 16;
r_affinetridesc.skinheight = pmdl->skinheight;
}
/*
================
R_AliasSetupLighting
================
*/
void R_AliasSetupLighting (alight_t *plighting)
{
// guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have
// to clamp off the bottom
r_ambientlight = plighting->ambientlight;
if (r_ambientlight < LIGHT_MIN)
r_ambientlight = LIGHT_MIN;
r_ambientlight = (255 - r_ambientlight) << VID_CBITS;
if (r_ambientlight < LIGHT_MIN)
r_ambientlight = LIGHT_MIN;
r_shadelight = plighting->shadelight;
if (r_shadelight < 0)
r_shadelight = 0;
r_shadelight *= VID_GRADES;
// rotate the lighting vector into the model's frame of reference
r_plightvec[0] = DotProduct (plighting->plightvec, alias_forward);
r_plightvec[1] = -DotProduct (plighting->plightvec, alias_right);
r_plightvec[2] = DotProduct (plighting->plightvec, alias_up);
}
/*
=================
R_AliasSetupFrame
set r_apverts
=================
*/
void R_AliasSetupFrame (void)
{
int frame;
int i, numframes;
maliasgroup_t *paliasgroup;
float *pintervals, fullinterval, targettime, time;
frame = currententity->frame;
if ((frame >= pmdl->numframes) || (frame < 0))
{
Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame);
frame = 0;
}
if (paliashdr->frames[frame].type == ALIAS_SINGLE)
{
r_apverts = (trivertx_t *)
((byte *)paliashdr + paliashdr->frames[frame].frame);
return;
}
paliasgroup = (maliasgroup_t *)
((byte *)paliashdr + paliashdr->frames[frame].frame);
pintervals = (float *)((byte *)paliashdr + paliasgroup->intervals);
numframes = paliasgroup->numframes;
fullinterval = pintervals[numframes-1];
time = cl.time + currententity->syncbase;
//
// when loading in Mod_LoadAliasGroup, we guaranteed all interval values
// are positive, so we don't have to worry about division by 0
//
targettime = time - ((int)(time / fullinterval)) * fullinterval;
for (i=0 ; i<(numframes-1) ; i++)
{
if (pintervals[i] > targettime)
break;
}
r_apverts = (trivertx_t *)
((byte *)paliashdr + paliasgroup->frames[i].frame);
}
/*
================
R_AliasDrawModel
================
*/
void R_AliasDrawModel (alight_t *plighting)
{
finalvert_t finalverts[MAXALIASVERTS +
((CACHE_SIZE - 1) / sizeof(finalvert_t)) + 1];
auxvert_t auxverts[MAXALIASVERTS];
r_amodels_drawn++;
// cache align
pfinalverts = (finalvert_t *)
(((long)&finalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
pauxverts = &auxverts[0];
paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model);
pmdl = (mdl_t *)((byte *)paliashdr + paliashdr->model);
R_AliasSetupSkin ();
R_AliasSetUpTransform (currententity->trivial_accept);
R_AliasSetupLighting (plighting);
R_AliasSetupFrame ();
if (!currententity->colormap)
Sys_Error ("R_AliasDrawModel: !currententity->colormap");
r_affinetridesc.drawtype = (currententity->trivial_accept == 3) &&
r_recursiveaffinetriangles;
if (r_affinetridesc.drawtype)
{
D_PolysetUpdateTables (); // FIXME: precalc...
}
else
{
#if id386
D_Aff8Patch (currententity->colormap);
#endif
}
acolormap = currententity->colormap;
if (currententity != &cl.viewent)
ziscale = (float)0x8000 * (float)0x10000;
else
ziscale = (float)0x8000 * (float)0x10000 * 3.0;
if (currententity->trivial_accept)
R_AliasPrepareUnclippedPoints ();
else
R_AliasPreparePoints ();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -