📄 r_alias_c.pas
字号:
__asm or edx, ALIAS_Z_CLIP
end_of_loop:
__asm mov dword ptr[edi + FINALVERT_FLAGS], edx
__asm add oldv, DTRIVERTX_SIZE
__asm add newv, DTRIVERTX_SIZE
__asm add fv, FINALVERT_SIZE
__asm dec ecx
__asm jnz top_of_loop
}
{$ELSE}
procedure R_AliasTransformFinalVerts(numpoints: integer; fv: finalvert_p; oldv: dtrivertx_p; newv: dtrivertx_p);
var
i: integer;
temp: integer;
lightcos: single;
plightnormal: vec3_t;
lerped_vert: vec3_t;
begin
for i := 0 to numpoints - 1 do
begin
lerped_vert[0] := r_lerp_move[0] + oldv^.v[0] * r_lerp_backv[0] + newv^.v[0] * r_lerp_frontv[0];
lerped_vert[1] := r_lerp_move[1] + oldv^.v[1] * r_lerp_backv[1] + newv^.v[1] * r_lerp_frontv[1];
lerped_vert[2] := r_lerp_move[2] + oldv^.v[2] * r_lerp_backv[2] + newv^.v[2] * r_lerp_frontv[2];
plightnormal := r_avertexnormals[newv^.lightnormalindex];
// PMM - added double damage shell
if ((currententity^.flags and (RF_SHELL_RED or RF_SHELL_GREEN or RF_SHELL_BLUE or RF_SHELL_DOUBLE or RF_SHELL_HALF_DAM)) <> 0) then
begin
lerped_vert[0] := lerped_vert[0] + plightnormal[0] * POWERSUIT_SCALE;
lerped_vert[1] := lerped_vert[1] + plightnormal[1] * POWERSUIT_SCALE;
lerped_vert[2] := lerped_vert[2] + plightnormal[2] * POWERSUIT_SCALE;
end;
fv^.xyz[0] := DotProduct(lerped_vert, vec3_p(@aliastransform[0])^) + aliastransform[0][3];
fv^.xyz[1] := DotProduct(lerped_vert, vec3_p(@aliastransform[1])^) + aliastransform[1][3];
fv^.xyz[2] := DotProduct(lerped_vert, vec3_p(@aliastransform[2])^) + aliastransform[2][3];
fv.flags := 0;
// lighting
lightcos := DotProduct(plightnormal, r_plightvec);
temp := r_ambientlight;
if (lightcos < 0) then
begin
inc(temp, Trunc(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) then
temp := 0;
end;
fv^.l := temp;
if (fv^.xyz[2] < ALIAS_Z_CLIP_PLANE) then
begin
fv^.flags := fv^.flags or ALIAS_Z_CLIP;
end
else
begin
R_AliasProjectAndClipTestFinalVert(fv);
end;
inc(Integer(fv), SizeOf(finalvert_t));
inc(Integer(oldv), SizeOf(dtrivertx_t));
inc(Integer(newv), SizeOf(dtrivertx_t));
end;
end;
{$ENDIF}
(*
================
R_AliasProjectAndClipTestFinalVert
================
*)
procedure R_AliasProjectAndClipTestFinalVert(fv: finalvert_p);
var
zi: single;
x, y, z: single;
begin
// project points
x := fv^.xyz[0];
y := fv^.xyz[1];
z := fv^.xyz[2];
zi := 1.0 / z;
fv^.zi := Trunc(zi * s_ziscale);
fv^.u := Trunc((x * aliasxscale * zi) + aliasxcenter);
fv^.v := Trunc((y * aliasyscale * zi) + aliasycenter);
if (fv^.u < r_refdef.aliasvrect.x) then
fv^.flags := fv^.flags or ALIAS_LEFT_CLIP;
if (fv^.v < r_refdef.aliasvrect.y) then
fv^.flags := fv^.flags or ALIAS_TOP_CLIP;
if (fv^.u > r_refdef.aliasvrectright) then
fv^.flags := fv^.flags or ALIAS_RIGHT_CLIP;
if (fv^.v > r_refdef.aliasvrectbottom) then
fv^.flags := fv^.flags or ALIAS_BOTTOM_CLIP;
end;
(*
===============
R_AliasSetupSkin
===============
*)
// static
function R_AliasSetupSkin: qboolean;
var
skinnum: integer;
pskindesc: image_p;
begin
if (currententity^.skin <> nil) then
pskindesc := currententity^.skin
else
begin
skinnum := currententity^.skinnum;
if ((skinnum >= s_pmdl^.num_skins) or (skinnum < 0)) then
begin
ri.Con_Printf(PRINT_ALL, 'R_AliasSetupSkin %s: no such skin #%d\n', currentmodel^.name, skinnum);
skinnum:= 0;
end;
pskindesc := currentmodel^.skins[skinnum];
end;
if (pskindesc = nil) then
begin
Result := false;
Exit;
end;
r_affinetridesc.pskin := pskindesc^.pixels[0];
r_affinetridesc.skinwidth := pskindesc^.width;
r_affinetridesc.skinheight := pskindesc^.height;
R_PolysetUpdateTables; // FIXME: precalc edge lookups
Result := true;
end;
(*
================
R_AliasSetupLighting
FIXME: put lighting into tables
================
*)
procedure R_AliasSetupLighting;
var
lighting: alight_t;
lightvec: array[0..2] of single;
light: vec3_t;
i, j: integer;
scale: single;
min: single;
begin
lightvec[0] := -1;
lightvec[1] := 0;
lightvec[2] := 0;
// all components of light should be identical in software
if ((currententity^.flags and RF_FULLBRIGHT) <> 0) then
begin
for i := 0 to 2 do
light[i] := 1.0;
end
else
begin
R_LightPoint(vec3_p(@currententity^.origin)^, light);
end;
// save off light value for server to look at (BIG HACK!)
if ((currententity^.flags and RF_WEAPONMODEL) <> 0) then
r_lightlevel^.value := 150.0 * light[0];
if ((currententity^.flags and RF_MINLIGHT) <> 0) then
begin
for i := 0 to 2 do
begin
if (light[i] < 0.1) then
light[i] := 0.1;
end;
end;
if ((currententity.flags and RF_GLOW) <> 0) then
begin
// bonus items will pulse with time
scale := 0.1 * sin(r_newrefdef.time * 7);
for i := 0 to 2 do
begin
min := light[i] * 0.8;
light[i] := light[i] + scale;
if (light[i] < min) then
light[i] := min;
end;
end;
j := Trunc((light[0] + light[1] + light[2]) * 0.3333 * 255);
lighting.ambientlight := j;
lighting.shadelight := j;
lighting.plightvec := @lightvec;
// clamp lighting so it doesn't overbright as much
if (lighting.ambientlight > 128) then
lighting.ambientlight := 128;
if (lighting.ambientlight + lighting.shadelight > 192) then
lighting.shadelight := 192 - lighting.ambientlight;
// guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have
// to clamp off the bottom
r_ambientlight := lighting.ambientlight;
if (r_ambientlight < LIGHT_MIN) then
r_ambientlight := LIGHT_MIN;
r_ambientlight := (255 - r_ambientlight) shl VID_CBITS;
if (r_ambientlight < LIGHT_MIN) then
r_ambientlight := LIGHT_MIN;
r_shadelight := lighting.shadelight;
if (r_shadelight < 0) then
r_shadelight := 0;
r_shadelight := r_shadelight * VID_GRADES;
// rotate the lighting vector into the model's frame of reference
r_plightvec[0] := DotProduct(vec3_p(lighting.plightvec)^, s_alias_forward);
r_plightvec[1] := -DotProduct(vec3_p(lighting.plightvec)^, s_alias_right);
r_plightvec[2] := DotProduct(vec3_p(lighting.plightvec)^, s_alias_up);
end;
(*
=================
R_AliasSetupFrames
=================
*)
procedure R_AliasSetupFrames(pmdl: dmdl_p);
var
thisframe, lastframe: integer;
begin
thisframe := currententity^.frame;
lastframe := currententity^.oldframe;
if ((thisframe >= pmdl^.num_frames) or (thisframe < 0)) then
begin
ri.Con_Printf(PRINT_ALL, PChar('R_AliasSetupFrames ' + currentmodel^.name + ': no such thisframe ' + IntToStr(thisframe) + #13#10));
thisframe := 0;
end;
if ((lastframe >= pmdl^.num_frames) or (lastframe < 0)) then
begin
ri.Con_Printf(PRINT_ALL, 'R_AliasSetupFrames %s: no such thisframe %d', currentmodel^.name, thisframe);
thisframe := 0;
end;
r_thisframe := daliasframe_p(integer(pmdl) + pmdl^.ofs_frames + (thisframe * pmdl^.framesize));
r_lastframe := daliasframe_p(integer(pmdl) + pmdl^.ofs_frames + (lastframe * pmdl^.framesize));
end;
(*
** R_AliasSetUpLerpData
**
** Precomputes lerp coefficients used for the whole frame.
*)
procedure R_AliasSetUpLerpData(pmdl: dmdl_p; backlerp: single);
var
frontlerp: single;
translation: vec3_t;
vectors: array[0..2] of vec3_t;
i: integer;
begin
frontlerp := 1.0 - backlerp;
(*
** convert entity's angles into discrete vectors for R, U, and F
*)
AngleVectors(vec3_p(@currententity.angles)^, @vectors[0], @vectors[1], @vectors[2]);
(*
** translation is the vector from last position to this position
*)
VectorSubtract(vec3_p(@currententity^.oldorigin)^, vec3_p(@currententity^.origin)^, translation);
(*
** move should be the delta back to the previous frame * backlerp
*)
r_lerp_move[0] := DotProduct(translation, vectors[0]); // forward
r_lerp_move[1] := -DotProduct(translation, vectors[1]); // left
r_lerp_move[2] := DotProduct(translation, vectors[2]); // up
VectorAdd(r_lerp_move, r_lastframe^.translate, r_lerp_move);
for i := 0 to 2 do
begin
r_lerp_move[i] := backlerp * r_lerp_move[i] + frontlerp * r_thisframe^.translate[i];
end;
for i := 0 to 2 do
begin
r_lerp_frontv[i] := frontlerp * r_thisframe^.scale[i];
r_lerp_backv[i] := backlerp * r_lastframe^.scale[i];
end;
end;
(*
================
R_AliasDrawModel
================
*)
procedure R_AliasDrawModel;
var
color: integer;
begin
s_pmdl := dmdl_p(currentmodel^.extradata);
if (r_lerpmodels^.value = 0.0) then
currententity^.backlerp := 0;
if ((currententity^.flags and RF_WEAPONMODEL) <> 0) then
begin
if (r_lefthand^.value = 1.0) then
aliasxscale := -aliasxscale
else
if (r_lefthand^.value = 2.0) then
Exit;
end;
(*
** we have to set our frame pointers and transformations before
** doing any real work
*)
R_AliasSetupFrames(s_pmdl);
R_AliasSetUpTransform;
// see if the bounding box lets us trivially reject, also sets
// trivial accept status
if (Cardinal(R_AliasCheckBBox) = BBOX_TRIVIAL_REJECT) then
begin
if (((currententity^.flags and RF_WEAPONMODEL) <> 0) and (r_lefthand^.value = 1.0)) then
begin
aliasxscale := -aliasxscale;
end;
Exit;
end;
// set up the skin and verify it exists
if (not R_AliasSetupSkin) then
begin
ri.Con_Printf(PRINT_ALL, 'R_AliasDrawModel %s: NULL skin found\n', currentmodel^.name);
Exit;
end;
inc(r_amodels_drawn);
R_AliasSetupLighting;
(*
** select the proper span routine based on translucency
*)
// PMM - added double damage shell
// PMM - reordered to handle blending
if ((currententity^.flags and (RF_SHELL_RED or RF_SHELL_GREEN or RF_SHELL_BLUE or RF_SHELL_DOUBLE or RF_SHELL_HALF_DAM)) <> 0) then
begin
// PMM - added double
color := currententity^.flags and (RF_SHELL_RED or RF_SHELL_GREEN or RF_SHELL_BLUE or RF_SHELL_DOUBLE or RF_SHELL_HALF_DAM);
// PMM - reordered, new shells after old shells (so they get overriden)
if ( color = RF_SHELL_RED ) then
r_aliasblendcolor:= SHELL_RED_COLOR
else
if ( color = RF_SHELL_GREEN ) then
r_aliasblendcolor:= SHELL_GREEN_COLOR
else
if ( color = RF_SHELL_BLUE ) then
r_aliasblendcolor:= SHELL_BLUE_COLOR
else
if ( color = (RF_SHELL_RED or RF_SHELL_GREEN) ) then
r_aliasblendcolor:= SHELL_RG_COLOR
else
if ( color = (RF_SHELL_RED or RF_SHELL_BLUE) ) then
r_aliasblendcolor:= SHELL_RB_COLOR
else
if ( color = (RF_SHELL_BLUE or RF_SHELL_GREEN) ) then
r_aliasblendcolor:= SHELL_BG_COLOR
// PMM - added this .. it's yellowish
else
if ( color = (RF_SHELL_DOUBLE) ) then
r_aliasblendcolor:= SHELL_DOUBLE_COLOR
else
if ( color = (RF_SHELL_HALF_DAM) ) then
r_aliasblendcolor:= SHELL_HALF_DAM_COLOR
// pmm
else
r_aliasblendcolor := SHELL_WHITE_COLOR;
if (currententity^.alpha > 0.33) then
d_pdrawspans := R_PolysetDrawSpansConstant8_66
else
d_pdrawspans := R_PolysetDrawSpansConstant8_33;
end
else
if ((currententity.flags and RF_TRANSLUCENT) <> 0) then
begin
if (currententity.alpha > 0.66) then
d_pdrawspans := R_PolysetDrawSpans8_Opaque
else
if (currententity.alpha > 0.33) then
d_pdrawspans := R_PolysetDrawSpans8_66
else
d_pdrawspans := R_PolysetDrawSpans8_33
end
else
begin
d_pdrawspans := R_PolysetDrawSpans8_Opaque;
end;
(*
** compute this_frame and old_frame addresses
*)
R_AliasSetUpLerpData(s_pmdl, currententity^.backlerp);
if ((currententity^.flags and RF_DEPTHHACK) <> 0) then
// TRANSLATOR'S NOTE: (x* 1.0) to avoid arithmetic overflow
s_ziscale := ($8000 * 1.0) * ($10000 * 1.0) * 3.0
else
s_ziscale := ($8000 * 1.0) * ($10000 * 1.0);
R_AliasPreparePoints;
if ((currententity^.flags and RF_WEAPONMODEL <> 0) and (r_lefthand^.value = 1.0)) then
begin
aliasxscale := -aliasxscale;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -