home *** CD-ROM | disk | FTP | other *** search
- { Polygon Fills Source file }
- { PHRO! }
- { Phred/OTM }
- { achalfin@uceng.uc.edu }
- { DO NOT DISTRIBUTE THIS SOURCE FILE }
- Unit Polygons;
- {$G+}
-
- Interface
-
- Const
- MinX = 0;
- MinY = 0;
- MaxX = 319;
- MaxY = 199;
-
- Procedure GouraudClipPolygon(x1, y1, x2, y2, x3, y3, C1, C2, C3, PgSeg : Integer);
- Procedure PhongClipPolygon(x1, y1, x2, y2, x3, y3, t1, p1, t2, p2, t3, p3, PgSeg : Integer; EMap : Pointer);
-
- Implementation
-
- Var
- EnvMap : Pointer;
-
-
- Procedure GouraudPoly(X1, Y1, X2, Y2, X3, Y3, C1, C2, C3, PgSeg : Integer);
-
- Var
- xTop, yTop : Integer;
- xBot, yBot : Integer;
- xMid, yMid : Integer;
- cTop, cBot, cMid : Integer;
- Count : Integer;
- xVal1, xStep1 : Integer;
- xVal2, xStep2 : Integer;
- cVal1, cStep1 : Integer;
- DColor : Integer;
- crMid : Integer;
- xrMid : Integer;
- hCount, cVal : Integer;
-
- Begin
- Asm
- Mov ax,Y1
- Mov bx,X1
- Mov cx,Y2
- Mov dx,X2
- Mov si,C1
- Mov di,C2
-
- Mov xTop,bx
- Mov yTop,ax
- Mov xBot,dx
- Mov yBot,cx
- Mov cTop,si
- Mov cBot,di
- Cmp ax,cx
- Jle @Skip2Top
- Mov xTop,dx
- Mov yTop,cx
- Mov xBot,bx
- Mov yBot,ax
- Mov cTop,di
- Mov cBot,si
- @Skip2Top:
- Mov ax,Y3
- Mov bx,X3
- Mov cx,C3
- Cmp ax,yTop
- Jge @CheckY3Bottom
- Mov dx,yTop
- Mov yMid,dx
- Mov dx,xTop
- Mov xMid,dx
- Mov dx,cTop
- Mov cMid,dx
- Mov yTop,ax
- Mov xTop,bx
- Mov cTop,cx
- Jmp @Fini
- @CheckY3Bottom:
- Cmp ax,yBot
- Jle @Y3Mid
- Mov dx,yBot
- Mov yMid,dx
- Mov dx,xBot
- Mov xMid,dx
- Mov dx,cBot
- Mov cMid,dx
- Mov yBot,ax
- Mov xBot,bx
- Mov cBot,cx
- Jmp @Fini
- @Y3Mid:
- Mov yMid,ax
- Mov xMid,bx
- Mov cMid,cx
- @Fini:
- End;
-
- If (yBot-yTop) = 0
- Then Begin
- xrMid := xMid;
- crMid := cMid;
- End
- Else Begin
- xrMid := (yMid-yTop)*(xBot-xTop) Div (yBot-yTop) + xTop;
- crMid := (yMid-yTop)*(cBot-cTop) Div (yBot-yTop) + cTop;
- End;
-
- Asm
- Mov es,PgSeg
- End;
-
- If xMid < XrMid
- Then Begin
- DColor := (crMid-cMid) Shl 8 Div (xrMid-xMid+1);
-
- cVal1 := cTop Shl 8;
- xVal1 := xTop Shl 6;
- xVal2 := xVal1;
- xStep1 := (xMid-xTop) Shl 6 Div (yMid-yTop+1);
- cStep1 := (cMid-cTop) Shl 8 Div (yMid-yTop+1);
- xStep2 := (xBot-xTop) Shl 6 Div (yBot-yTop+1);
- For Count := yTop to yMid do
- Begin
- Asm
- Mov bx,Count
- Mov dx,bx
- Shl bx,6
- Add bh,dl
- Mov di,bx
-
- Mov ax,Word Ptr [xVal1]
- Shr ax,6
- Mov cx,Word Ptr [xVal2]
- Shr cx,6
-
- Add di,ax
-
- Sub cx,ax
- Inc cx
- Js @Exit
- Mov bx,dColor
- Mov ax,cVal1
- Shr cx,1
- Jnc @SkipSingle
- Mov es:[di],ah
- Add ax,bx
- Inc di
- @SkipSingle:
- Jcxz @Exit
- @Looper:
- Mov dl,ah
- Add ax,bx
- Mov dh,ah
- Add ax,bx
- Mov es:[di],dx
- Add di,2
- Dec cx
- Jnz @Looper
- @Exit:
- End;
- Inc(cVal1, cStep1);
- Inc(xVal1, xStep1);
- Inc(xVal2, xStep2);
- End;
-
- xVal2 := xVal2 - xStep2;
-
- cVal1 := cMid Shl 8;
- xVal1 := xMid Shl 6;
- xStep1 := (xBot-xMid) Shl 6 Div (yBot-yMid+1);
- cStep1 := (cBot-cMid) Shl 8 Div (yBot-yMid+1);
- For Count := yMid to yBot do
- Begin
- Asm
- Mov bx,Count
- Mov dx,bx
- Shl bx,6
- Add bh,dl
- Mov di,bx
-
- Mov ax,Word Ptr [xVal1]
- Shr ax,6
- Mov cx,Word Ptr [xVal2]
- Shr cx,6
- Add di,ax
-
- Sub cx,ax
- Inc cx
- Js @Exit
- Jcxz @Exit
- Mov bx,dColor
- Mov ax,cVal1
- Shr cx,1
- Jnc @SkipSingle
- Mov es:[di],ah
- Add ax,bx
- Inc di
- @SkipSingle:
- Jcxz @Exit
- @Looper:
- Mov dl,ah
- Add ax,bx
- Mov dh,ah
- Add ax,bx
- Mov es:[di],dx
- Add di,2
- Dec cx
- Jnz @Looper
- @Exit:
- End;
- Inc(cVal1, cStep1);
- Inc(xVal1, xStep1);
- Inc(xVal2, xStep2);
- End;
- End
- Else Begin
- DColor := (cMid-crMid) Shl 8 Div (xMid-xrMid+1);
-
- cVal1 := cTop Shl 8;
- xVal1 := (xTop) Shl 6;
- xVal2 := xVal1;
- xStep1 := (xBot-xTop) Shl 6 Div (yBot-yTop+1);
- cStep1 := (cBot-cTop) Shl 8 Div (yBot-yTop+1);
- xStep2 := (xMid-xTop) Shl 6 Div (yMid-yTop+1);
-
- For Count := yTop to yMid do
- Begin
- Asm
- Mov bx,Count
- Mov dx,bx
- Shl bx,6
- Add bh,dl
- Mov di,bx
-
- Mov ax,Word Ptr [xVal1]
- Shr ax,6
- Mov cx,Word Ptr [xVal2]
- Shr cx,6
- Add di,ax
-
- Sub cx,ax
- Inc cx
- Js @Exit
- Jcxz @Exit
- Mov bx,dColor
- Mov ax,cVal1
- Shr cx,1
- Jnc @SkipSingle
- Mov es:[di],ah
- Add ax,bx
- Inc di
- @SkipSingle:
- Jcxz @Exit
- @Looper:
- Mov dl,ah
- Add ax,bx
- Mov dh,ah
- Add ax,bx
- Mov es:[di],dx
- Add di,2
- Dec cx
- Jnz @Looper
- @Exit:
- End;
- Inc(cVal1, cStep1);
- Inc(xVal1, xStep1);
- Inc(xVal2, xStep2);
- End;
-
- xVal1 := xVal1 - xStep1;
- cVal1 := cVal1 - cStep1;
- xVal2 := (xMid) Shl 6;
- xStep2 := (xBot-xMid) Shl 6 Div (yBot-yMid+1);
- For Count := yMid to yBot do
- Begin
- Asm
- Mov bx,Count
- Mov dx,bx
- Shl bx,6
- Add bh,dl
- Mov di,bx
-
- Mov ax,Word Ptr [xVal1]
- Shr ax,6
- Mov cx,Word Ptr [xVal2]
- Shr cx,6
-
- Add di,ax
-
- Sub cx,ax
- Inc cx
- Js @Exit
- Jcxz @Exit
- Mov bx,dColor
- Mov ax,cVal1
- Shr cx,1
- Jnc @SkipSingle
- Mov es:[di],ah
- Add ax,bx
- Inc di
- @SkipSingle:
- Jcxz @Exit
- @Looper:
- Mov dl,ah
- Add ax,bx
- Mov dh,ah
- Add ax,bx
- Mov es:[di],dx
- Add di,2
- Dec cx
- Jnz @Looper
- @Exit:
- End;
- Inc(cVal1, cStep1);
- Inc(xVal1, xStep1);
- Inc(xVal2, xStep2);
- End;
- End;
-
- End;
-
- Procedure GouraudClipPolygon(x1, y1, x2, y2, x3, y3, C1, C2, C3, PgSeg : Integer);
-
- Type
- tFlatClip = Record
- x, y, x1, y1 : Integer;
- c, c1 : Integer;
- End;
-
- Var
- FlatList : Array[0..7] of tFlatClip;
- NumVert : Integer;
- Count : Integer;
- ClipVert : Integer;
- V1, V2 : Integer;
-
- Begin
- If (((X1 >= MinX) and (X1 <= MaxX)) and ((Y1 >= MinY) and (Y1 <= MaxY)) and
- ((X2 >= MinX) and (X2 <= MaxX)) and ((Y2 >= MinY) and (Y2 <= MaxY))) and
- ((X3 >= MinX) and (X3 <= MaxX)) and ((Y3 >= MinY) and (Y3 <= MaxY))
- Then Begin
- GouraudPoly(X1, Y1, X2, Y2, X3, Y3, C1, C2, C3, PgSeg);
- Exit;
- End;
- FlatList[0].x := X1;
- FlatList[0].y := Y1;
- FlatList[0].c := C1;
- FlatList[1].x := X2;
- FlatList[1].y := Y2;
- FlatList[1].c := C2;
- FlatList[2].x := X3;
- FlatList[2].y := Y3;
- FlatList[2].c := C3;
- NumVert := 3;
- ClipVert := 0;
- { Clip against left side }
- V1 := NumVert - 1;
- For Count := 0 to (NumVert-1) do
- Begin
- If (FlatList[V1].x >= MinX) and (FlatList[Count].x >= MinX)
- Then Begin
- FlatList[ClipVert].x1 := FlatList[Count].x;
- FlatList[ClipVert].y1 := FlatList[Count].y;
- FlatList[ClipVert].c1 := FlatList[Count].c;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[V1].x >= MinX) and (FlatList[Count].x < MinX)
- Then Begin
- FlatList[ClipVert].x1 := MinX;
- FlatList[ClipVert].y1 := (FlatList[Count].y-FlatList[V1].y)*(MinX-FlatList[v1].x)
- Div (FlatList[Count].x-FlatList[V1].x) + FlatList[V1].y;
- FlatList[ClipVert].c1 := (FlatList[Count].c-FlatList[V1].c)*(MinX-FlatList[v1].x)
- Div (FlatList[Count].x-FlatList[V1].x) + FlatList[V1].c;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[V1].x < MinX) and (FlatList[Count].x >= MinX)
- Then Begin
- FlatList[ClipVert].x1 := MinX;
- FlatList[ClipVert].y1 := (FlatList[Count].y-FlatList[V1].y)*(MinX-FlatList[V1].x)
- Div (FlatList[Count].x-FlatList[V1].x) + FlatList[v1].y;
- FlatList[ClipVert].c1 := (FlatList[Count].c-FlatList[V1].c)*(MinX-FlatList[V1].x)
- Div (FlatList[Count].x-FlatList[V1].x) + FlatList[v1].c;
- ClipVert := ClipVert + 1;
- FlatList[ClipVert].x1 := FlatList[Count].x;
- FlatList[ClipVert].y1 := FlatList[Count].y;
- FlatList[ClipVert].c1 := FlatList[Count].c;
- ClipVert := ClipVert + 1;
- End;
- V1 := Count;
- End;
- NumVert := ClipVert;
- ClipVert := 0;
- { Clip against Right side }
- V1 := NumVert - 1;
- For Count := 0 to (NumVert-1) do
- Begin
- If (FlatList[v1].x1 <= MaxX) and (FlatList[Count].x1 <= MaxX)
- Then Begin
- FlatList[ClipVert].x := FlatList[Count].x1;
- FlatList[ClipVert].y := FlatList[Count].y1;
- FlatList[ClipVert].c := FlatList[Count].c1;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[V1].x1 <= MaxX) and (FlatList[Count].x1 > MaxX)
- Then Begin
- FlatList[ClipVert].x := MaxX;
- FlatList[ClipVert].y := (FlatList[Count].y1-FlatList[V1].y1)*(MaxX-FlatList[v1].x1)
- Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].y1;
- FlatList[ClipVert].c := (FlatList[Count].c1-FlatList[V1].c1)*(MaxX-FlatList[v1].x1)
- Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].c1;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[v1].x1 > MaxX) and (FlatList[Count].x1 <= MaxX)
- Then Begin
- FlatList[ClipVert].x := MaxX;
- FlatList[ClipVert].y := (FlatList[Count].y1-FlatList[V1].y1)*(MaxX-FlatList[v1].x1)
- Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].y1;
- FlatList[ClipVert].c := (FlatList[Count].c1-FlatList[V1].c1)*(MaxX-FlatList[v1].x1)
- Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].c1;
- ClipVert := ClipVert + 1;
- FlatList[ClipVert].x := FlatList[Count].x1;
- FlatList[ClipVert].y := FlatList[Count].y1;
- FlatList[ClipVert].c := FlatList[Count].c1;
- ClipVert := ClipVert + 1;
- End;
- v1 := Count;
- End;
- NumVert := ClipVert;
- ClipVert := 0;
- { Clip against top edge }
- V1 := NumVert - 1;
- For Count := 0 to (NumVert-1) do
- Begin
- If (FlatList[V1].y >= MinY) and (FlatList[Count].y >= MinY)
- Then Begin
- FlatList[ClipVert].x1 := FlatList[Count].x;
- FlatList[ClipVert].y1 := FlatList[Count].y;
- FlatList[ClipVert].c1 := FlatList[Count].c;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[V1].y >= MinY) and (FlatList[Count].y < MinY)
- Then Begin
- FlatList[ClipVert].x1 := (MinY-FlatList[V1].y)*(FlatList[Count].x-FlatList[V1].x)
- Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].x;
- FlatList[ClipVert].c1 := (MinY-FlatList[V1].y)*(FlatList[Count].c-FlatList[V1].c)
- Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].c;
- FlatList[ClipVert].y1 := MinY;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[V1].y < MinY) and (FlatList[Count].y >= MinY)
- Then Begin
- FlatList[ClipVert].x1 := (MinY-FlatList[V1].y)*(FlatList[Count].x-FlatList[V1].x)
- Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].x;
- FlatList[ClipVert].c1 := (MinY-FlatList[V1].y)*(FlatList[Count].c-FlatList[V1].c)
- Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].c;
- FlatList[ClipVert].y1 := MinY;
- ClipVert := ClipVert + 1;
- FlatList[ClipVert].x1 := FlatList[Count].x;
- FlatList[ClipVert].y1 := FlatList[Count].y;
- FlatList[ClipVert].c1 := FlatList[Count].c;
- ClipVert := ClipVert + 1;
- End;
- V1 := Count;
- End;
- NumVert := ClipVert;
- ClipVert := 0;
- V1 := NumVert - 1;
- For Count := 0 to (NumVert-1) do
- Begin
- If (FlatList[V1].y1 <= MaxY) and (FlatList[Count].y1 <= MaxY)
- Then Begin
- FlatList[ClipVert].x := FlatList[Count].x1;
- FlatList[ClipVert].y := FlatList[Count].y1;
- FlatList[ClipVert].c := FlatList[Count].c1;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[V1].y1 <= MaxY) and (FlatList[Count].y1 > MaxY)
- Then Begin
- FlatList[ClipVert].x := (MaxY-FlatList[V1].y1)*(FlatList[Count].x1-FlatList[V1].x1)
- Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].x1;
- FlatList[ClipVert].c := (MaxY-FlatList[V1].y1)*(FlatList[Count].c1-FlatList[V1].c1)
- Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].c1;
- FlatList[ClipVert].y := MaxY;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[V1].y1 > MaxY) and (FlatList[Count].y1 <= MaxY)
- Then Begin
- FlatList[ClipVert].x := (MaxY-FlatList[V1].y1)*(FlatList[Count].x1-FlatList[V1].x1)
- Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].x1;
- FlatList[ClipVert].c := (MaxY-FlatList[V1].y1)*(FlatList[Count].c1-FlatList[V1].c1)
- Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].c1;
- FlatList[ClipVert].y := MaxY;
- ClipVert := ClipVert + 1;
- FlatList[ClipVert].x := FlatList[Count].x1;
- FlatList[ClipVert].y := FlatList[Count].y1;
- FlatList[ClipVert].c := FlatList[Count].c1;
- ClipVert := ClipVert + 1;
- End;
- V1 := Count;
- End;
- NumVert := ClipVert;
-
- V1 := 1;
- V2 := 2;
-
- { Now draw the polygons }
- For Count := 0 to (NumVert - 3) do
- Begin
- GouraudPoly(FlatList[0].x, FlatList[0].y,
- FlatList[V1].x, FlatList[V1].y,
- FlatList[V2].x, FlatList[V2].y,
- FlatList[0].c, FlatList[V1].c,
- FlatList[V2].c, PgSeg);
- V1 := V2;
- V2 := V2 + 1;
- End;
- End;
-
-
- Procedure PhongPoly(X1, Y1, X2, Y2, X3, Y3, p1, t1, p2, t2, p3, t3, PgSeg : Integer);
-
- Var
- xTop, yTop, pTop, tTop : Integer;
- xMid, yMid, pMid, tMid : Integer;
- xBot, yBot, pBot, tBot : Integer;
- xVal1, xStep1, xVal2, xStep2 : Integer;
- tVal1, tStep1 : Integer;
- pVal1, pStep1 : Integer;
- Count : Integer;
- xrMid, prMid, trMid : Integer;
- pVal, tVal : Integer;
- HCount : Integer;
- DPhi, DTheta : Integer;
- Segment : Word;
- yDiver : Integer;
-
- Begin
- If Y1 < Y2
- Then Begin
- yTop := Y1;
- xTop := X1;
- pTop := p1;
- tTop := t1;
- yBot := Y2;
- xBot := X2;
- pBot := p2;
- tBot := t2;
- End
- Else Begin
- yTop := Y2;
- xTop := X2;
- pTop := p2;
- tTop := t2;
- yBot := Y1;
- xBot := X1;
- pBot := p1;
- tBot := t1;
- End;
- If Y3 < yTop
- Then Begin
- yMid := yTop;
- xMid := xTop;
- tMid := tTop;
- pMid := pTop;
- xTop := X3;
- yTop := Y3;
- pTop := p3;
- tTop := t3;
- End
- Else Begin
- If Y3 > yBot
- Then Begin
- yMid := yBot;
- xMid := xBot;
- pMid := pBot;
- tMid := tBot;
- xBot := X3;
- yBot := Y3;
- pBot := p3;
- tBot := t3;
- End
- Else Begin
- yMid := Y3;
- xMid := X3;
- pMid := p3;
- tMid := t3;
- End;
- End;
-
- If yBot-yTop = 0 Then Exit;
-
- Segment := PgSeg;
-
- yDiver := (yMid-yTop) Shl 8 Div (yBot-yTop);
- Asm
- Mov ax,xBot
- Sub ax,xTop
- Mov bx,yDiver
- IMul bx
- Sar ax,8
- Add ax,xTop
- Mov xrMid,ax
-
- Mov ax,pBot
- Sub ax,pTop
- IMul bx
- Sar ax,8
- Add ax,pTop
- Mov prMid,ax
-
- Mov ax,tBot
- Sub ax,tTop
- IMul bx
- Sar ax,8
- Add ax,tTop
- Mov trMid,ax
- End;
-
- { xrMid := (yMid-yTop)*(xBot-xTop) Div (yBot-yTop) + xTop;
- prMid := (yMid-yTop)*(pBot-pTop) Div (yBot-yTop) + pTop;
- trMid := (yMid-yTop)*(tBot-tTop) Div (yBot-yTop) + tTop;
- }
-
- If xMid < xrMid
- Then Begin { 2 edges are on the left side }
- DPhi := (prMid-pMid) Shl 8 Div (xrMid-xMid+1);
- DTheta := (trMid-tMid) Shl 8 Div (xrMid-xMid+1);
-
- xVal1 := xTop Shl 6;
- xVal2 := xVal1;
- tVal1 := tTop Shl 8;
- pVal1 := pTop Shl 8;
-
- xStep1 := (xMid-xTop) Shl 6 Div (yMid-yTop+1);
- tStep1 := (tMid-tTop) Shl 8 Div (yMid-yTop+1);
- pStep1 := (pMid-pTop) Shl 8 Div (yMid-yTop+1);
- xStep2 := (xBot-xTop) Shl 6 Div (yBot-yTop+1);
-
- For Count := yTop to yMid do
- Begin
- { ***** HLine *****}
- Asm
- Mov ax,Segment
- Mov es,ax
-
- Mov ax,xVal1
- Shr ax,6
- Mov cx,xVal2
- Shr cx,6
- Sub cx,ax
- Inc cx
- Js @Exit
- Jcxz @Exit
-
-
- Mov bx,Count
- Mov dx,bx
- Shl bx,6
- Add bh,dl
- Add bx,ax
- Mov di,bx
-
- Mov ax,pVal1
- Mov si,dPhi
- Mov dx,tVal1
-
- Push bp
- Mov bp,dTheta
- Push ds
- Lds bx,EnvMap
-
- Shr cx,1
- Jnc @SkipSingle
- Mov bh,ah
- Mov bl,dh
- Mov ch,ds:[bx]
- Mov es:[di],ch
- Add ax,si
- Add dx,bp
- Inc di
- @SkipSingle:
-
- Xor ch,ch
- Jcxz @SkipLoop
- @Looper:
- Mov bh,ah
- Mov bl,dh
- Mov ch,ds:[bx]
- Mov es:[di],ch
- Add ax,si
- Add dx,bp
- Inc di
- Mov bh,ah
- Mov bl,dh
- Mov ch,ds:[bx]
- Mov es:[di],ch
- Add ax,si
- Add dx,bp
- Inc di
- Dec cl
- Jnz @Looper
- @SkipLoop:
-
- Pop ds
- Pop bp
- @Exit:
-
- End;
- { ***** End HLine ***** }
- xVal1 := xVal1 + xStep1;
- xVal2 := xVal2 + xStep2;
- pVal1 := pVal1 + pStep1;
- tVal1 := tVal1 + tStep1;
- End;
-
-
- xVal2 := xVal2 - xStep2;
- tVal1 := tMid Shl 8;
- pVal1 := pMid Shl 8;
- xVal1 := xMid Shl 6;
- tStep1 := (tBot-tMid) Shl 8 Div (yBot-yMid+1);
- pStep1 := (pBot-pMid) Shl 8 Div (yBot-yMid+1);
- xStep1 := (xBot-xMid) Shl 6 Div (yBot-yMid+1);
-
- For Count := yMid to yBot do
- Begin
- { ***** HLine *****}
- Asm
- Mov ax,Segment
- Mov es,ax
-
- Mov ax,xVal1
- Shr ax,6
- Mov cx,xVal2
- Shr cx,6
- Sub cx,ax
- Inc cx
- Js @Exit
- Jcxz @Exit
-
-
- Mov bx,Count
- Mov dx,bx
- Shl bx,6
- Add bh,dl
- Add bx,ax
- Mov di,bx
-
- Mov ax,pVal1
- Mov si,dPhi
- Mov dx,tVal1
-
- Push bp
- Mov bp,dTheta
- Push ds
- Lds bx,EnvMap
-
- Shr cx,1
- Jnc @SkipSingle
- Mov bh,ah
- Mov bl,dh
- Mov ch,ds:[bx]
- Mov es:[di],ch
- Add ax,si
- Add dx,bp
- Inc di
- @SkipSingle:
-
- Xor ch,ch
- Jcxz @SkipLoop
- @Looper:
- Mov bh,ah
- Mov bl,dh
- Mov ch,ds:[bx]
- Mov es:[di],ch
- Add ax,si
- Add dx,bp
- Inc di
- Mov bh,ah
- Mov bl,dh
- Mov ch,ds:[bx]
- Mov es:[di],ch
- Add ax,si
- Add dx,bp
- Inc di
- Dec cl
- Jnz @Looper
- @SkipLoop:
-
- Pop ds
- Pop bp
- @Exit:
-
- End;
- { ***** End HLine ***** }
- xVal1 := xVal1 + xStep1;
- xVal2 := xVal2 + xStep2;
- pVal1 := pVal1 + pStep1;
- tVal1 := tVal1 + tStep1;
- End;
-
-
- End
- Else Begin { Long Edge on the left side }
- DPhi := (pMid-prMid) Shl 8 Div (xMid-xrMid+1);
- DTheta := (tMid-trMid) Shl 8 Div (xMid-xrMid+1);
-
- xVal1 := xTop Shl 6;
- tVal1 := tTop Shl 8;
- pVal1 := pTop Shl 8;
- xVal2 := xVal1;
- xStep1 := (xBot-xTop) Shl 6 Div (yBot-yTop+1);
- tStep1 := (tBot-tTop) Shl 8 Div (yBot-yTop+1);
- pStep1 := (pBot-pTop) Shl 8 Div (yBot-yTop+1);
- xStep2 := (xMid-xTop) Shl 6 Div (yMid-yTop+1);
- For Count := yTop to yMid do
- Begin
- { ***** HLine *****}
- Asm
- Mov ax,Segment
- Mov es,ax
-
- Mov ax,xVal1
- Shr ax,6
- Mov cx,xVal2
- Shr cx,6
- Sub cx,ax
- Inc cx
- Js @Exit
- Jcxz @Exit
-
-
- Mov bx,Count
- Mov dx,bx
- Shl bx,6
- Add bh,dl
- Add bx,ax
- Mov di,bx
-
- Mov ax,pVal1
- Mov si,dPhi
- Mov dx,tVal1
-
- Push bp
- Mov bp,dTheta
- Push ds
- Lds bx,EnvMap
-
- Shr cx,1
- Jnc @SkipSingle
- Mov bh,ah
- Mov bl,dh
- Mov ch,ds:[bx]
- Mov es:[di],ch
- Add ax,si
- Add dx,bp
- Inc di
- @SkipSingle:
-
- Xor ch,ch
- Jcxz @SkipLoop
- @Looper:
- Mov bh,ah
- Mov bl,dh
- Mov ch,ds:[bx]
- Mov es:[di],ch
- Add ax,si
- Add dx,bp
- Inc di
- Mov bh,ah
- Mov bl,dh
- Mov ch,ds:[bx]
- Mov es:[di],ch
- Add ax,si
- Add dx,bp
- Inc di
- Dec cl
- Jnz @Looper
- @SkipLoop:
-
- Pop ds
- Pop bp
- @Exit:
-
- End;
- { ***** End HLine ***** }
- xVal1 := xVal1 + xStep1;
- xVal2 := xVal2 + xStep2;
- pVal1 := pVal1 + pStep1;
- tVal1 := tVal1 + tStep1;
- End;
-
- tVal1 := tVal1 - tStep1;
- pVal1 := pVal1 - pStep1;
- xVal1 := xVal1 - xStep1;
- xStep2 := (xBot-xMid) Shl 6 Div (yBot-yMid+1);
- For Count := yMid to yBot do
- Begin
- { ***** HLine *****}
- Asm
- Mov ax,Segment
- Mov es,ax
-
- Mov ax,xVal1
- Shr ax,6
- Mov cx,xVal2
- Shr cx,6
- Sub cx,ax
- Inc cx
- Js @Exit
- Jcxz @Exit
-
-
- Mov bx,Count
- Mov dx,bx
- Shl bx,6
- Add bh,dl
- Add bx,ax
- Mov di,bx
-
- Mov ax,pVal1
- Mov si,dPhi
- Mov dx,tVal1
-
- Push bp
- Mov bp,dTheta
- Push ds
- Lds bx,EnvMap
-
- Shr cx,1
- Jnc @SkipSingle
- Mov bh,ah
- Mov bl,dh
- Mov ch,ds:[bx]
- Mov es:[di],ch
- Add ax,si
- Add dx,bp
- Inc di
- @SkipSingle:
-
- Xor ch,ch
- Jcxz @SkipLoop
- @Looper:
- Mov bh,ah
- Mov bl,dh
- Mov ch,ds:[bx]
- Mov es:[di],ch
- Add ax,si
- Add dx,bp
- Inc di
- Mov bh,ah
- Mov bl,dh
- Mov ch,ds:[bx]
- Mov es:[di],ch
- Add ax,si
- Add dx,bp
- Inc di
- Dec cl
- Jnz @Looper
- @SkipLoop:
-
- Pop ds
- Pop bp
- @Exit:
-
- End;
- { ***** End HLine ***** }
- xVal1 := xVal1 + xStep1;
- xVal2 := xVal2 + xStep2;
- pVal1 := pVal1 + pStep1;
- tVal1 := tVal1 + tStep1;
- End;
- End;
-
- End;
-
-
-
-
-
- Procedure PhongClipPolygon(x1, y1, x2, y2, x3, y3, t1, p1, t2, p2, t3, p3, PgSeg : Integer; EMap : Pointer);
-
- Type
- tFlatClip = Record
- x, y, x1, y1 : Integer;
- t, p, t1, p1 : Integer;
- End;
-
- Var
- FlatList : Array[0..7] of tFlatClip;
- NumVert : Integer;
- Count : Integer;
- ClipVert : Integer;
- V1, V2 : Integer;
-
- Begin
- EnvMap := EMap;
- If (((X1 >= MinX) and (X1 <= MaxX)) and ((Y1 >= MinY) and (Y1 <= MaxY)) and
- ((X2 >= MinX) and (X2 <= MaxX)) and ((Y2 >= MinY) and (Y2 <= MaxY))) and
- ((X3 >= MinX) and (X3 <= MaxX)) and ((Y3 >= MinY) and (Y3 <= MaxY))
- Then Begin
- PhongPoly(X1, Y1, X2, Y2, X3, Y3, p1, t1, p2, t2, p3, t3, PgSeg);
- Exit;
- End;
- FlatList[0].x := X1;
- FlatList[0].y := Y1;
- FlatList[0].t := t1;
- FlatList[0].p := p1;
- FlatList[1].x := X2;
- FlatList[1].y := Y2;
- FlatList[1].t := t2;
- FlatList[1].p := p2;
- FlatList[2].x := X3;
- FlatList[2].y := Y3;
- FlatList[2].t := t3;
- FlatList[2].p := p3;
- NumVert := 3;
- ClipVert := 0;
- { Clip against left side }
- V1 := NumVert - 1;
- For Count := 0 to (NumVert-1) do
- Begin
- If (FlatList[V1].x >= MinX) and (FlatList[Count].x >= MinX)
- Then Begin
- FlatList[ClipVert].x1 := FlatList[Count].x;
- FlatList[ClipVert].y1 := FlatList[Count].y;
- FlatList[ClipVert].t1 := FlatList[Count].t;
- FlatList[ClipVert].p1 := FlatList[Count].p;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[V1].x >= MinX) and (FlatList[Count].x < MinX)
- Then Begin
- FlatList[ClipVert].x1 := MinX;
- FlatList[ClipVert].y1 := (FlatList[Count].y-FlatList[V1].y)*(MinX-FlatList[v1].x)
- Div (FlatList[Count].x-FlatList[V1].x) + FlatList[V1].y;
- FlatList[ClipVert].t1 := (FlatList[Count].t-FlatList[V1].t)*(MinX-FlatList[v1].x)
- Div (FlatList[Count].x-FlatList[V1].x) + FlatList[V1].t;
- FlatList[ClipVert].p1 := (FlatList[Count].p-FlatList[V1].p)*(MinX-FlatList[v1].x)
- Div (FlatList[Count].x-FlatList[V1].x) + FlatList[V1].p;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[V1].x < MinX) and (FlatList[Count].x >= MinX)
- Then Begin
- FlatList[ClipVert].x1 := MinX;
- FlatList[ClipVert].y1 := (FlatList[Count].y-FlatList[V1].y)*(MinX-FlatList[V1].x)
- Div (FlatList[Count].x-FlatList[V1].x) + FlatList[v1].y;
- FlatList[ClipVert].t1 := (FlatList[Count].t-FlatList[V1].t)*(MinX-FlatList[V1].x)
- Div (FlatList[Count].x-FlatList[V1].x) + FlatList[v1].t;
- FlatList[ClipVert].p1 := (FlatList[Count].p-FlatList[V1].p)*(MinX-FlatList[V1].x)
- Div (FlatList[Count].x-FlatList[V1].x) + FlatList[v1].p;
- ClipVert := ClipVert + 1;
- FlatList[ClipVert].x1 := FlatList[Count].x;
- FlatList[ClipVert].y1 := FlatList[Count].y;
- FlatList[ClipVert].t1 := FlatList[Count].t;
- FlatList[ClipVert].p1 := FlatList[Count].p;
- ClipVert := ClipVert + 1;
- End;
- V1 := Count;
- End;
- NumVert := ClipVert;
- ClipVert := 0;
- { Clip against Right side }
- V1 := NumVert - 1;
- For Count := 0 to (NumVert-1) do
- Begin
- If (FlatList[v1].x1 <= MaxX) and (FlatList[Count].x1 <= MaxX)
- Then Begin
- FlatList[ClipVert].x := FlatList[Count].x1;
- FlatList[ClipVert].y := FlatList[Count].y1;
- FlatList[ClipVert].t := FlatList[Count].t1;
- FlatList[ClipVert].p := FlatList[Count].p1;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[V1].x1 <= MaxX) and (FlatList[Count].x1 > MaxX)
- Then Begin
- FlatList[ClipVert].x := MaxX;
- FlatList[ClipVert].y := (FlatList[Count].y1-FlatList[V1].y1)*(MaxX-FlatList[v1].x1)
- Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].y1;
- FlatList[ClipVert].t := (FlatList[Count].t1-FlatList[V1].t1)*(MaxX-FlatList[v1].x1)
- Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].t1;
- FlatList[ClipVert].p := (FlatList[Count].p1-FlatList[V1].p1)*(MaxX-FlatList[v1].x1)
- Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].p1;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[v1].x1 > MaxX) and (FlatList[Count].x1 <= MaxX)
- Then Begin
- FlatList[ClipVert].x := MaxX;
- FlatList[ClipVert].y := (FlatList[Count].y1-FlatList[V1].y1)*(MaxX-FlatList[v1].x1)
- Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].y1;
- FlatList[ClipVert].t := (FlatList[Count].t1-FlatList[V1].t1)*(MaxX-FlatList[v1].x1)
- Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].t1;
- FlatList[ClipVert].p := (FlatList[Count].p1-FlatList[V1].p1)*(MaxX-FlatList[v1].x1)
- Div (FlatList[Count].x1-FlatList[v1].x1) + FlatList[v1].p1;
- ClipVert := ClipVert + 1;
- FlatList[ClipVert].x := FlatList[Count].x1;
- FlatList[ClipVert].y := FlatList[Count].y1;
- FlatList[ClipVert].t := FlatList[Count].t1;
- FlatList[ClipVert].p := FlatList[Count].p1;
- ClipVert := ClipVert + 1;
- End;
- v1 := Count;
- End;
- NumVert := ClipVert;
- ClipVert := 0;
- { Clip against top edge }
- V1 := NumVert - 1;
- For Count := 0 to (NumVert-1) do
- Begin
- If (FlatList[V1].y >= MinY) and (FlatList[Count].y >= MinY)
- Then Begin
- FlatList[ClipVert].x1 := FlatList[Count].x;
- FlatList[ClipVert].y1 := FlatList[Count].y;
- FlatList[ClipVert].t1 := FlatList[Count].t;
- FlatList[ClipVert].p1 := FlatList[Count].p;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[V1].y >= MinY) and (FlatList[Count].y < MinY)
- Then Begin
- FlatList[ClipVert].x1 := (MinY-FlatList[V1].y)*(FlatList[Count].x-FlatList[V1].x)
- Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].x;
- FlatList[ClipVert].t1 := (MinY-FlatList[V1].y)*(FlatList[Count].t-FlatList[V1].t)
- Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].t;
- FlatList[ClipVert].p1 := (MinY-FlatList[V1].y)*(FlatList[Count].p-FlatList[V1].p)
- Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].p;
- FlatList[ClipVert].y1 := MinY;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[V1].y < MinY) and (FlatList[Count].y >= MinY)
- Then Begin
- FlatList[ClipVert].x1 := (MinY-FlatList[V1].y)*(FlatList[Count].x-FlatList[V1].x)
- Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].x;
- FlatList[ClipVert].t1 := (MinY-FlatList[V1].y)*(FlatList[Count].t-FlatList[V1].t)
- Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].t;
- FlatList[ClipVert].p1 := (MinY-FlatList[V1].y)*(FlatList[Count].p-FlatList[V1].p)
- Div (FlatList[Count].y-FlatList[V1].y) + FlatList[V1].p;
- FlatList[ClipVert].y1 := MinY;
- ClipVert := ClipVert + 1;
- FlatList[ClipVert].x1 := FlatList[Count].x;
- FlatList[ClipVert].y1 := FlatList[Count].y;
- FlatList[ClipVert].t1 := FlatList[Count].t;
- FlatList[ClipVert].p1 := FlatList[Count].p;
- ClipVert := ClipVert + 1;
- End;
- V1 := Count;
- End;
- NumVert := ClipVert;
- ClipVert := 0;
- V1 := NumVert - 1;
- For Count := 0 to (NumVert-1) do
- Begin
- If (FlatList[V1].y1 <= MaxY) and (FlatList[Count].y1 <= MaxY)
- Then Begin
- FlatList[ClipVert].x := FlatList[Count].x1;
- FlatList[ClipVert].y := FlatList[Count].y1;
- FlatList[ClipVert].t := FlatList[Count].t1;
- FlatList[ClipVert].p := FlatList[Count].p1;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[V1].y1 <= MaxY) and (FlatList[Count].y1 > MaxY)
- Then Begin
- FlatList[ClipVert].x := (MaxY-FlatList[V1].y1)*(FlatList[Count].x1-FlatList[V1].x1)
- Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].x1;
- FlatList[ClipVert].t := (MaxY-FlatList[V1].y1)*(FlatList[Count].t1-FlatList[V1].t1)
- Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].t1;
- FlatList[ClipVert].p := (MaxY-FlatList[V1].y1)*(FlatList[Count].p1-FlatList[V1].p1)
- Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].p1;
- FlatList[ClipVert].y := MaxY;
- ClipVert := ClipVert + 1;
- End;
- If (FlatList[V1].y1 > MaxY) and (FlatList[Count].y1 <= MaxY)
- Then Begin
- FlatList[ClipVert].x := (MaxY-FlatList[V1].y1)*(FlatList[Count].x1-FlatList[V1].x1)
- Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].x1;
- FlatList[ClipVert].t := (MaxY-FlatList[V1].y1)*(FlatList[Count].t1-FlatList[V1].t1)
- Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].t1;
- FlatList[ClipVert].p := (MaxY-FlatList[V1].y1)*(FlatList[Count].p1-FlatList[V1].p1)
- Div (FlatList[Count].y1-FlatList[v1].y1) + FlatList[V1].p1;
- FlatList[ClipVert].y := MaxY;
- ClipVert := ClipVert + 1;
- FlatList[ClipVert].x := FlatList[Count].x1;
- FlatList[ClipVert].y := FlatList[Count].y1;
- FlatList[ClipVert].t := FlatList[Count].t1;
- FlatList[ClipVert].p := FlatList[Count].p1;
- ClipVert := ClipVert + 1;
- End;
- V1 := Count;
- End;
- NumVert := ClipVert;
-
- V1 := 1;
- V2 := 2;
-
- { Now draw the polygons }
- For Count := 0 to (NumVert - 3) do
- Begin
- PhongPoly(FlatList[0].x, FlatList[0].y,
- FlatList[V1].x, FlatList[V1].y,
- FlatList[V2].x, FlatList[V2].y,
- FlatList[0].p, FlatList[0].t,
- FlatList[V1].p, FlatList[V1].t,
- FlatList[V2].p, FlatList[V2].t, PgSeg);
- V1 := V2;
- V2 := V2 + 1;
- End;
- End;
-
- End.