📄 r_polyse.pas
字号:
procedure R_PolysetFillSpans8(pspanpackage: spanpackage_p);
var
color: Integer;
lcount: Integer;
lpdest: PByte;
begin
// FIXME: do z buffering
color := d_aflatcolor;
inc(d_aflatcolor);
while (true) do
begin
lcount := pspanpackage^.count;
if (lcount = -1) then
Exit;
if (lcount <> 0) then
begin
lpdest := pspanpackage^.pdest;
repeat
lpdest^ := color;
inc(integer(lpdest), 1);
dec(lcount);
until lcount <= 0;
end;
inc(Integer(pspanpackage), sizeof(spanpackage_t));
end;
end;
(*
================
R_RasterizeAliasPolySmooth
================
*)
procedure R_RasterizeAliasPolySmooth;
var
initialleftheight: Integer;
initialrightheight: Integer;
plefttop: PIntegerArray;
prighttop: PIntegerArray;
pleftbottom: PIntegerArray;
prightbottom: PIntegerArray;
working_lstepx: Integer;
originalcount: Integer;
height: Integer;
pstart: spanpackage_p;
begin
plefttop := PIntegerArray(pedgetable^.pleftedgevert0);
prighttop := PIntegerArray(pedgetable^.prightedgevert0);
pleftbottom := PIntegerArray(pedgetable^.pleftedgevert1);
prightbottom := PIntegerArray(pedgetable^.prightedgevert1);
initialleftheight := pleftbottom^[1] - plefttop^[1];
initialrightheight := prightbottom^[1] - prighttop^[1];
//
// set the s, t, and light gradients, which are consistent across the triangle
// because being a triangle, things are affine
//
R_PolysetCalcGradients(r_affinetridesc.skinwidth);
//
// rasterize the polygon
//
//
// scan out the top (and possibly only) part of the left edge
//
d_pedgespanpackage := a_spans;
ystart := plefttop^[1];
d_aspancount := plefttop^[0] - prighttop^[0];
// d_ptex := @PByteArray(r_affinetridesc.pskin)^[_SAR(plefttop^[2], 16)+_SAR(plefttop^[3], 16)*r_affinetridesc.skinwidth];
d_ptex := PByte(Integer(r_affinetridesc.pskin) +
_SAR(plefttop^[2], 16) +
_SAR(plefttop^[3], 16) *
r_affinetridesc.skinwidth);
//#if id386ALIAS
{$IFDEF id386}
if (addr(d_pdrawspans) = addr(R_PolysetDrawSpans8_Opaque)) then
begin
d_sfrac := (plefttop^[2] and $FFFF) shl 16;
d_tfrac := (plefttop^[3] and $FFFF) shl 16;
end
else
{$ENDIF}
begin
d_sfrac := plefttop^[2] and $FFFF;
d_tfrac := plefttop^[3] and $FFFF;
end;
d_light := plefttop^[4];
d_zi := plefttop^[5];
d_pdest := @PByteArray(d_viewbuffer)^[ystart * r_screenwidth + plefttop^[0]];
// d_pdest := PByte(Integer(d_viewbuffer) + ystart * r_screenwidth + plefttop^[0]);
d_pz := @PSmallIntArray(d_pzbuffer)^[ystart * Integer(d_zwidth) + plefttop^[0]];
// d_pz := PSmallInt(Integer(d_pzbuffer) + ((ystart * Integer(d_zwidth) + plefttop^[0])*SizeOf(SmallInt)));
if (initialleftheight = 1) then
begin
d_pedgespanpackage^.pdest := d_pdest;
d_pedgespanpackage^.pz := d_pz;
d_pedgespanpackage^.count := d_aspancount;
d_pedgespanpackage^.ptex := d_ptex;
d_pedgespanpackage^.sfrac := d_sfrac;
d_pedgespanpackage^.tfrac := d_tfrac;
// FIXME: need to clamp l, s, t, at both ends?
d_pedgespanpackage^.light := d_light;
d_pedgespanpackage^.zi := d_zi;
inc(Integer(d_pedgespanpackage), SizeOf(spanpackage_t));
end
else
begin
R_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
pleftbottom[0], pleftbottom[1]);
{$ifdef id386}
if (Addr(d_pdrawspans) = Addr(R_PolysetDrawSpans8_Opaque)) then
begin
d_pzbasestep := _SAL((Integer(d_zwidth) + ubasestep), 1);
d_pzextrastep := d_pzbasestep + 2;
end
else
{$endif}
begin
d_pzbasestep := Integer(d_zwidth) + ubasestep;
d_pzextrastep := d_pzbasestep + 1;
end;
d_pdestbasestep := r_screenwidth + ubasestep;
d_pdestextrastep := d_pdestbasestep + 1;
// TODO: can reuse partial expressions here
// for negative steps in x along left edge, bias toward overflow rather than
// underflow (sort of turning the floor () we did in the gradient calcs into
// ceil (), but plus a little bit)
if (ubasestep < 0) then
working_lstepx := r_lstepx - 1
else
working_lstepx := r_lstepx;
d_countextrastep := ubasestep + 1;
d_ptexbasestep := _SAR((r_sstepy + r_sstepx * ubasestep), 16) +
_SAR((r_tstepy + r_tstepx * ubasestep), 16) *
r_affinetridesc.skinwidth;
{$ifdef id386}
if (Addr(d_pdrawspans) = Addr(R_PolysetDrawSpans8_Opaque)) then
begin
d_sfracbasestep := _SAR((r_sstepy + r_sstepx * ubasestep), 16);
d_tfracbasestep := _SAR((r_tstepy + r_tstepx * ubasestep), 16);
end
else
{$endif}
begin
d_sfracbasestep := (r_sstepy + r_sstepx * ubasestep) and $FFFF;
d_tfracbasestep := (r_tstepy + r_tstepx * ubasestep) and $FFFF;
end;
d_lightbasestep := (r_lstepy + working_lstepx) * ubasestep;
d_zibasestep := (r_zistepy + r_zistepx) * ubasestep;
d_ptexextrastep := _SAR((r_sstepy + r_sstepx * d_countextrastep), 16) +
_SAR((r_tstepy + r_tstepx * d_countextrastep), 16) *
r_affinetridesc.skinwidth;
{$ifdef id386}
if (Addr(d_pdrawspans) = Addr(R_PolysetDrawSpans8_Opaque)) then
begin
d_sfracextrastep := _SAL((r_sstepy + r_sstepx*d_countextrastep), 16);
d_tfracextrastep := _SAL((r_tstepy + r_tstepx*d_countextrastep), 16);
end
else
{$endif}
begin
d_sfracextrastep := (r_sstepy + r_sstepx*d_countextrastep) and $FFFF;
d_tfracextrastep := (r_tstepy + r_tstepx*d_countextrastep) and $FFFF;
end;
d_lightextrastep := d_lightbasestep + working_lstepx;
d_ziextrastep := d_zibasestep + r_zistepx;
{$ifdef id386}
if (Addr(d_pdrawspans) = Addr(R_PolysetDrawSpans8_Opaque)) then
begin
R_PolysetScanLeftEdge(initialleftheight);
end
else
{$endif}
begin
R_PolysetScanLeftEdge_C(initialleftheight);
end;
end;
//
// scan out the bottom part of the left edge, if it exists
//
if (pedgetable^.numleftedges = 2) then
begin
plefttop := pleftbottom;
pleftbottom := PIntegerArray(pedgetable^.pleftedgevert2);
height := pleftbottom^[1] - plefttop^[1];
// TODO: make this a function; modularize this function in general
ystart := plefttop^[1];
d_aspancount := plefttop^[0] - prighttop^[0];
d_ptex := @PByteArray(r_affinetridesc.pskin)^[_SAR(plefttop^[2], 16) +
_SAR(plefttop^[3], 16) *
r_affinetridesc.skinwidth];
(*
d_ptex := PByte(Integer(r_affinetridesc.pskin) + _SAR(plefttop^[2],16) +
_SAR(plefttop^[3], 16) * r_affinetridesc.skinwidth);
*)
d_sfrac := 0;
d_tfrac := 0;
d_light := plefttop^[4];
d_zi := plefttop^[5];
d_pdest := @PByteArray(d_viewbuffer)^[ystart * r_screenwidth + plefttop^[0]];
(*
d_pdest := PByte(Integer(d_viewbuffer) + ystart * r_screenwidth + plefttop^[0]);
*)
d_pz := @PSmallIntArray(d_pzbuffer)^[ystart * Integer(d_zwidth) + plefttop^[0]];
(*
d_pz := PSmallInt(Integer(d_pzbuffer) + ystart * Integer(d_zwidth) + plefttop^[0]);
*)
if (height = 1) then
begin
d_pedgespanpackage^.pdest := d_pdest;
d_pedgespanpackage^.pz := d_pz;
d_pedgespanpackage^.count := d_aspancount;
d_pedgespanpackage^.ptex := d_ptex;
d_pedgespanpackage^.sfrac := d_sfrac;
d_pedgespanpackage^.tfrac := d_tfrac;
// FIXME: need to clamp l, s, t, at both ends?
d_pedgespanpackage^.light := d_light;
d_pedgespanpackage^.zi := d_zi;
inc(Integer(d_pedgespanpackage), SizeOf(spanpackage_t));
end
else
begin
R_PolysetSetUpForLineScan(plefttop^[0], plefttop^[1],
pleftbottom^[0], pleftbottom^[1]);
d_pdestbasestep := r_screenwidth + ubasestep;
d_pdestextrastep := d_pdestbasestep + 1;
{$IFDEF id386}
if (Addr(d_pdrawspans) = Addr(R_PolysetDrawSpans8_Opaque)) then
begin
d_pzbasestep := _SAL((Integer(d_zwidth) + ubasestep), 1);
d_pzextrastep := d_pzbasestep + 2;
end
else
{$ENDIF}
begin
d_pzbasestep := Integer(d_zwidth) + ubasestep;
d_pzextrastep := d_pzbasestep + 1;
end;
if (ubasestep < 0) then
working_lstepx := r_lstepx - 1
else
working_lstepx := r_lstepx;
d_countextrastep := ubasestep + 1;
d_ptexbasestep := _SAR((r_sstepy + r_sstepx * ubasestep), 16) +
_SAR((r_tstepy + r_tstepx * ubasestep), 16) *
r_affinetridesc.skinwidth;
{$IFDEF id386}
if (Addr(d_pdrawspans) = Addr(R_PolysetDrawSpans8_Opaque)) then
begin
d_sfracbasestep := _SAL((r_sstepy + r_sstepx * ubasestep), 16);
d_tfracbasestep := _SAL((r_tstepy + r_tstepx * ubasestep), 16);
end
else
{$ENDIF}
begin
d_sfracbasestep := (r_sstepy + r_sstepx * ubasestep) and $FFFF;
d_tfracbasestep := (r_tstepy + r_tstepx * ubasestep) and $FFFF;
end;
d_lightbasestep := r_lstepy + working_lstepx * ubasestep;
d_zibasestep := r_zistepy + r_zistepx * ubasestep;
d_ptexextrastep := _SAR((r_sstepy + r_sstepx * d_countextrastep), 16) +
_SAR((r_tstepy + r_tstepx * d_countextrastep), 16) *
r_affinetridesc.skinwidth;
{$IFDEF id386}
if (Addr(d_pdrawspans) = Addr(R_PolysetDrawSpans8_Opaque)) then
begin
d_sfracextrastep := _SAL(((r_sstepy + r_sstepx * d_countextrastep) and $FFFF), 16);
d_tfracextrastep := _SAL(((r_tstepy + r_tstepx * d_countextrastep) and $FFFF), 16);
end
else
{$ENDIF}
begin
d_sfracextrastep := (r_sstepy + r_sstepx * d_countextrastep) and $FFFF;
d_tfracextrastep := (r_tstepy + r_tstepx * d_countextrastep) and $FFFF;
end;
d_lightextrastep := d_lightbasestep + working_lstepx;
d_ziextrastep := d_zibasestep + r_zistepx;
{$IFDEF id386}
if (Addr(d_pdrawspans) = Addr(R_PolysetDrawSpans8_Opaque)) then
begin
R_PolysetScanLeftEdge(height);
end
else
{$ENDIF}
begin
R_PolysetScanLeftEdge_C(height);
end;
end;
end;
// scan out the top (and possibly only) part of the right edge, updating the
// count field
d_pedgespanpackage := a_spans;
R_PolysetSetUpForLineScan(prighttop^[0], prighttop^[1],
prightbottom^[0], prightbottom^[1]);
d_aspancount := 0;
d_countextrastep := ubasestep + 1;
originalcount := spanpackage_array_p(a_spans)^[initialrightheight].count;
spanpackage_array_p(a_spans)^[initialrightheight].count := -999999; // mark end of the spanpackages
d_pdrawspans(a_spans);
// scan out the bottom part of the right edge, if it exists
if (pedgetable^.numrightedges = 2) then
begin
pstart := @spanpackage_array_p(a_spans)^[initialrightheight];
pstart^.count := originalcount;
d_aspancount := prightbottom^[0] - prighttop^[0];
prighttop := prightbottom;
prightbottom := PIntegerArray(pedgetable^.prightedgevert2);
height := prightbottom^[1] - prighttop^[1];
R_PolysetSetUpForLineScan(prighttop^[0], prighttop^[1],
prightbottom^[0], prightbottom^[1]);
d_countextrastep := ubasestep + 1;
spanpackage_array_p(a_spans)^[initialrightheight + height].count := -999999;
// mark end of the spanpackages
d_pdrawspans(pstart);
end;
end;
(*
================
R_PolysetSetEdgeTable
================
*)
procedure R_PolysetSetEdgeTable;
var
edgetableindex: Integer;
begin
edgetableindex := 0; // assume the vertices are already in
// top to bottom order
//
// determine which edges are right & left, and the order in which
// to rasterize them
//
if (r_p0[1] >= r_p1[1]) then
begin
if (r_p0[1] = r_p1[1]) then
begin
if (r_p0[1] < r_p2[1]) then
pedgetable := @edgetables[2]
else
pedgetable := @edgetables[5];
exit;
end
else
begin
edgetableindex := 1;
end;
end;
if (r_p0[1] = r_p2[1]) then
begin
if (edgetableindex <> 0) then
pedgetable := @edgetables[8]
else
pedgetable := @edgetables[9];
Exit;
end
else
if (r_p1[1] = r_p2[1]) then
begin
if (edgetableindex <> 0) then
pedgetable := @edgetables[10]
else
pedgetable := @edgetables[11];
Exit;
end;
if (r_p0[1] > r_p2[1]) then
inc(edgetableindex, 2);
if (r_p1[1] > r_p2[1]) then
inc(edgetableindex, 4);
pedgetable := @edgetables[edgetableindex];
end;
{$IFNDEF id386}
procedure R_PolysetScanLeftEdge(height: Integer);
begin
end;
{$ENDIF}
initialization
FillChar(r_p0, SizeOf(r_p0), 0);
FillChar(r_p1, SizeOf(r_p1), 0);
FillChar(r_p2, SizeOf(r_p2), 0);
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -