⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 r_polyse.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 4 页
字号:

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 + -