📄 r_edge.pas
字号:
(*
=============
D_MipLevelForScale
=============
*)
function D_MipLevelForScale(scale: Single): Integer;
var
lmiplevel: Integer;
begin
if (scale >= d_scalemip[0]) then
lmiplevel := 0
else
if (scale >= d_scalemip[1]) then
lmiplevel := 1
else
if (scale >= d_scalemip[2]) then
lmiplevel := 2
else
lmiplevel := 3;
if (lmiplevel < d_minmip) then
lmiplevel := d_minmip;
Result := lmiplevel;
end;
(*
==============
D_FlatFillSurface
Simple single color fill with no texture mapping
==============
*)
procedure D_FlatFillSurface(surf: surf_p; color: Integer);
var
span: espan_p;
pdest: PByte;
u, u2: Integer;
begin
// for (span=surf->spans ; span ; span=span->pnext)
span := surf^.spans;
while (span <> nil) do
begin
pdest := PByte(Integer(d_viewbuffer) + r_screenwidth * span^.v);
u := span^.u;
u2 := span^.u + span^.count - 1;
while (u <= u2) do
begin
PByteArray(pdest)^[u] := color;
u := u + 1;
end;
span := span^.pnext;
end;
end;
(*
==============
D_CalcGradients
==============
*)
procedure D_CalcGradients(pface: msurface_p);
var
// pplane : mplane_p;
mipscale: Single;
p_temp1: vec3_t;
p_saxis: vec3_t;
p_taxis: vec3_t;
t: Single;
begin
// pplane := pface^.plane;
mipscale := 1.0 / (1 shl miplevel);
TransformVector(vec3_p(@pface^.texinfo^.vecs[0])^, p_saxis);
TransformVector(vec3_p(@pface^.texinfo^.vecs[1])^, p_taxis);
t := xscaleinv * mipscale;
d_sdivzstepu := p_saxis[0] * t;
d_tdivzstepu := p_taxis[0] * t;
t := yscaleinv * mipscale;
d_sdivzstepv := -p_saxis[1] * t;
d_tdivzstepv := -p_taxis[1] * t;
d_sdivzorigin := p_saxis[2] * mipscale - xcenter * d_sdivzstepu - ycenter * d_sdivzstepv;
d_tdivzorigin := p_taxis[2] * mipscale - xcenter * d_tdivzstepu - ycenter * d_tdivzstepv;
VectorScale(transformed_modelorg, mipscale, p_temp1);
t := $10000 * mipscale;
sadjust := (fixed16_t(Trunc(DotProduct(p_temp1, p_saxis) * $10000 + 0.5))) -
_SAR(_SAL(pface^.texturemins[0], 16), miplevel) + Trunc(pface^.texinfo^.vecs[0][3] * t);
tadjust := (fixed16_t(Trunc(DotProduct(p_temp1, p_taxis) * $10000 + 0.5))) -
_SAR(_SAL(pface^.texturemins[1], 16), miplevel) + Trunc(pface^.texinfo^.vecs[1][3] * t);
(* sadjust := (fixed16_t(Trunc(DotProduct(p_temp1, p_saxis) * $10000 + 0.5))) -
((pface^.texturemins[0] shl 16) shr miplevel)+ Trunc(pface^.texinfo^.vecs[0][3]*t);
tadjust := (fixed16_t(Trunc(DotProduct(p_temp1, p_taxis) * $10000 + 0.5))) -
((pface^.texturemins[1] shl 16) shr miplevel) + Trunc(pface^.texinfo^.vecs[1][3]*t);
*)
// PGM - changing flow speed for non-warping textures.
if (pface^.texinfo^.flags and SURF_FLOWING) <> 0 then
begin
if (pface^.texinfo^.flags and SURF_WARP) <> 0 then
sadjust := sadjust + Trunc($10000 * (-128 * ((r_newrefdef.time * 0.25) - (r_newrefdef.time * 0.25))))
else
sadjust := sadjust + Trunc($10000 * (-128 * ((r_newrefdef.time * 0.77) - (r_newrefdef.time * 0.77))));
end;
// PGM
//
// -1 (-epsilon) so we never wander off the edge of the texture
//
bbextents := _SAR(_SAL(pface^.extents[0], 16), miplevel) - 1;
bbextentt := _SAR(_SAL(pface^.extents[1], 16), miplevel) - 1;
// bbextents := ((pface^.extents[0] shl 16) shr miplevel) - 1;
// bbextentt := ((pface^.extents[1] shl 16) shr miplevel) - 1;
end;
(*
==============
D_BackgroundSurf
The grey background filler seen when there is a hole in the map
==============
*)
procedure D_BackgroundSurf(s: surf_p);
begin
// set up a gradient for the background surface that places it
// effectively at infinity distance from the viewpoint
d_zistepu := 0;
d_zistepv := 0;
d_ziorigin := -0.9;
D_FlatFillSurface(s, Trunc(sw_clearcolor^.value) and $FF);
D_DrawZSpans(s^.spans);
end;
(*
=================
D_TurbulentSurf
=================
*)
procedure D_TurbulentSurf(s: surf_p);
begin
d_zistepu := s^.d_zistepu;
d_zistepv := s^.d_zistepv;
d_ziorigin := s^.d_ziorigin;
pface := s^.msurf;
miplevel := 0;
cacheblock := pface^.texinfo^.image^.pixels[0];
cachewidth := 64;
if (s^.insubmodel) then
begin
// FIXME: we don't want to do all this for every polygon!
// TODO: store once at start of frame
currententity := s^.entity; //FIXME: make this passed in to
// R_RotateBmodel ()
VectorSubtract(r_origin, vec3_p(@currententity^.origin)^, local_modelorg);
TransformVector(local_modelorg, transformed_modelorg);
R_RotateBmodel; // FIXME: don't mess with the frustum,
// make entity passed in
end;
D_CalcGradients(pface);
//============
//PGM
// textures that aren't warping are just flowing. Use NonTurbulent8 instead
if ((pface^.texinfo^.flags and SURF_WARP) = 0) then
NonTurbulent8(s^.spans)
else
Turbulent8(s^.spans);
//PGM
//============
D_DrawZSpans(s^.spans);
if (s^.insubmodel) then
begin
//
// restore the old drawing state
// FIXME: we don't want to do this every time!
// TODO: speed up
//
currententity := nil; // &r_worldentity;
VectorCopy(world_transformed_modelorg, transformed_modelorg);
VectorCopy(base_vpn, vpn);
VectorCopy(base_vup, vup);
VectorCopy(base_vright, vright);
R_TransformFrustum;
end;
end;
(*
==============
D_SkySurf
==============
*)
procedure D_SkySurf(s: surf_p);
begin
pface := s^.msurf;
miplevel := 0;
if (pface^.texinfo^.image = nil) then
Exit;
cacheblock := pface^.texinfo^.image^.pixels[0];
cachewidth := 256;
d_zistepu := s^.d_zistepu;
d_zistepv := s^.d_zistepv;
d_ziorigin := s^.d_ziorigin;
D_CalcGradients(pface);
D_DrawSpans16(s^.spans);
// set up a gradient for the background surface that places it
// effectively at infinity distance from the viewpoint
d_zistepu := 0;
d_zistepv := 0;
d_ziorigin := -0.9;
D_DrawZSpans(s^.spans);
end;
(*
==============
D_SolidSurf
Normal surface cached, texture mapped surface
==============
*)
procedure D_SolidSurf(s: surf_p);
{$IF false}
var
dot: Single;
normal: array[0..2] of Single;
{$IFEND}
begin
d_zistepu := s^.d_zistepu;
d_zistepv := s^.d_zistepv;
d_ziorigin := s^.d_ziorigin;
if (s^.insubmodel) then
begin
// FIXME: we don't want to do all this for every polygon!
// TODO: store once at start of frame
currententity := s^.entity; //FIXME: make this passed in to
// R_RotateBmodel ()
VectorSubtract(r_origin, vec3_p(@currententity^.origin)^, local_modelorg);
TransformVector(local_modelorg, transformed_modelorg);
R_RotateBmodel; // FIXME: don't mess with the frustum,
// make entity passed in
end
else
currententity := @r_worldentity;
pface := s^.msurf;
{$IF True}
miplevel := D_MipLevelForScale(s^.nearzi * scale_for_mip * pface^.texinfo^.mipadjust);
{$ELSE}
begin
if (s^.insubmodel) then
begin
VectorCopy(pface^.plane^.normal, normal);
// TransformVector( pface->plane->normal, normal);
dot := DotProduct(normal, vpn);
end
else
begin
VectorCopy(pface^.plane^.normal, normal);
dot := DotProduct(normal, vpn);
end;
if (pface^.flags and SURF_PLANEBACK) <> 0 then
dot := -dot;
// if (dot > 0) then
// printf( "blah" );
miplevel := D_MipLevelForScale(s^.nearzi * scale_for_mip * pface^.texinfo^.mipadjust);
end;
{$IFEND}
// FIXME: make this passed in to D_CacheSurface
pcurrentcache := D_CacheSurface(pface, miplevel);
cacheblock := pixel_p(@pcurrentcache^.data);
cachewidth := pcurrentcache^.width;
D_CalcGradients(pface);
D_DrawSpans16(s^.spans);
D_DrawZSpans(s^.spans);
if (s^.insubmodel) then
begin
//
// restore the old drawing state
// FIXME: we don't want to do this every time!
// TODO: speed up
//
VectorCopy(world_transformed_modelorg, transformed_modelorg);
VectorCopy(base_vpn, vpn);
VectorCopy(base_vup, vup);
VectorCopy(base_vright, vright);
R_TransformFrustum;
currententity := nil; //&r_worldentity;
end;
end;
(*
=============
D_DrawflatSurfaces
To allow developers to see the polygon carving of the world
=============
*)
procedure D_DrawflatSurfaces;
var
s: surf_p;
begin
s := @PSurf_tArray(surfaces)^[1];
// for (s = &surfaces[1] ; s<surface_p ; s++)
while (Integer(s) < Integer(surface_p)) do
begin
if (s^.spans = nil) then
begin
Inc(Integer(s), SizeOf(surf_t));
continue;
end;
d_zistepu := s^.d_zistepu;
d_zistepv := s^.d_zistepv;
d_ziorigin := s^.d_ziorigin;
// make a stable color for each surface by taking the low
// bits of the msurface pointer
D_FlatFillSurface(s, Integer(s^.msurf) and $FF);
D_DrawZSpans(s^.spans);
Inc(Integer(s), SizeOf(surf_t));
end;
end;
(*
==============
D_DrawSurfaces
Rasterize all the span lists. Guaranteed zero overdraw.
May be called more than once a frame if the surf list overflows (higher res)
==============
*)
procedure D_DrawSurfaces;
var
s: surf_p;
begin
currententity := nil; //&r_worldentity;
VectorSubtract(r_origin, vec3_origin, modelorg);
TransformVector(modelorg, transformed_modelorg);
VectorCopy(transformed_modelorg, world_transformed_modelorg);
if (sw_drawflat^.value = 0.0) then
begin
s := @PSurf_tArray(surfaces)^[1];
while (Integer(s) < Integer(surface_p)) do
begin
if (s^.spans = nil) then
begin
Inc(Integer(s), SizeOf(surf_t));
continue;
end;
r_drawnpolycount := r_drawnpolycount + 1;
if ((s^.flags and (SURF_DRAWSKYBOX or SURF_DRAWBACKGROUND or SURF_DRAWTURB)) = 0) then
D_SolidSurf(s)
else
if (s^.flags and SURF_DRAWSKYBOX) <> 0 then
D_SkySurf(s)
else
if (s^.flags and SURF_DRAWBACKGROUND) <> 0 then
D_BackgroundSurf(s)
else
if (s^.flags and SURF_DRAWTURB) <> 0 then
D_TurbulentSurf(s);
Inc(Integer(s), SizeOf(surf_t));
end;
end
else
D_DrawflatSurfaces;
currententity := nil; //&r_worldentity;
VectorSubtract(r_origin, vec3_origin, modelorg);
R_TransformFrustum;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -