[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]
(*
> It's not that slow. I can get about 60 good-sized
> poly's in a second on my dinky 386sx-20. It also does
> ^ ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^
> I don't know what a good speed is for polyfills, but this sounds quite
> good! Thanks heaps (and stacks? :^) for the post!
You're welcome. I just now converted it to 99% assembler, 386+, just gotta
test it out.
> One question to follow:
> { fillWord(mem[$A000:0],64000,0); {clear}
> ^^^ ^stick closer ("}") here
> You'll probably recognize the above as the main routine of the polygon
> fill snippet (the tester part). Please note the part I under-careted
> (or -caretted). There is no closing comment before the next opening
> comment. Should the closer be placed where indicated by me? Or
> was the opener a typo?
> Not a big deal, but I want this to work so I can be impressed! :^)
It works like that, at least in TP/BP. The open comment in effect keeps the
compiler from ever seeing the next open brace. So the second brace's closing
brace actually closes the first one. A trick I learned since I started at
deltaComm. No, I actually wanted that commented out, because clearing the
screen between each one slows it down.
Actually, I noticed a strange behaviour in the fill, where if you have one
vertex = (x,y) and the next vertex = (x+40,y+1) then you'll end up with a dot
on one line and the next line entirely filled. Not what was intended. I came up
with a fix for it:
It basically just centers the stairstep zigzag by adding half a step before it
starts.
*)
function lSar(L:longint):longint;assembler;asm
db $66; mov ax,L {mov eax,L}
db $66; sar ax,1 {sar eax,1}
db $66,$0F,$A4,$C2,$10 {shld edx,eax,16}
end;
procedure draw(color:byte);
var i,l,r,lv,rv,top,bottom,topVert:integer; var lstep,lpos,rstep,rpos:fixed;
var ldest,rdest:tPoint; begin
{find top and bottom vertices}
topVert:=numVerts-1;
top:=vertex[topVert].y; bottom:=top;
for i:=numVerts-2 downto 0 do
if (vertex[i].Y < top) then begin
top:=vertex[i].Y;
topVert:=i;
end
else if (vertex[i].Y > bottom) then
bottom:=vertex[i].Y;
if bottom>maxY then bottom:=maxY; {clip bottom}
if top>bottom then exit;
lv:=topVert; rv:=topVert;
ldest:=vertex[topVert]; rdest:=ldest;
i:=top;
repeat
if i<bottom then begin
{
^^^^^^^^^^^^^^^^^^^^^^^^^ keep from getting wierd effects from the
adjustment on the last row.
}
if i>=ldest.y then begin
lpos.f:=0; lpos.i:=ldest.x;
dec(lv); if lv<0 then lv:=numVerts-1;
ldest:=vertex[lv];
if ldest.y=i then begin
if ldest.x<lpos.i then lpos.i:=ldest.x;
lstep.l:=0;
end
else begin
lstep.l:=fixedDiv(ldest.x-lpos.i,ldest.y-i);
inc(lpos.l,lSar(lstep.l));
^^^^^^^^^^^^^^^^^^^^^^^^^^ Center the stairstep pattern
end;
end;
if i>=rdest.y then begin
rpos.f:=0; rpos.i:=rdest.x;
inc(rv); if rv>=numVerts then rv:=0;
rdest:=vertex[rv];
if rdest.y=i then begin
if rdest.x>rpos.i then rpos.i:=rdest.x;
rstep.l:=0;
end
else begin
rstep.l:=fixedDiv(rdest.x-rpos.i,rdest.y-i);
inc(rpos.l,lSar(rStep.l));
^^^^^^^^^^^^^^^^^^^^^^^^^^ Center the stairstep pattern
end;
end;
end;
if i>=minY then begin {clip top}
if lpos.i>minX then l:=lpos.i else l:=minX; {clip left}
if rpos.i<maxX then r:=rpos.i else r:=maxX; {clip right}
if (l<=r) then
fillWord(mem[$A000:i*320+l],r-l+1,color);
end;
inc(lpos.l,lstep.l);
inc(rpos.l,rstep.l);
inc(i);
until i>bottom;
end;
[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]