I optimized Simon's code a while back and didn't think to post it till now...
My version of the function is about 4x faster than Simon's, and it's all because Rect is slower than Writepixelfast when doing lots of little horizontal lines. With writepixelfast, I can lock the buffer once before I draw the triangle, whereas with rect it has to lock and unlock the buffer every call.
; poly.bb
; by simon@...
; fastpoly by sswift
Dim xval(20)
Dim yval(20)
Graphics 640,480,16
SetBuffer BackBuffer()
Color 255,0,255
T1 = MilliSecs()
For Loop = 0 To 1000
Triangle(-10,-10, 180,20, 230,220)
Next
T2 = MilliSecs()
T3 = MilliSecs()
For Loop = 0 To 1000
FastTriangle(-10,-10, 180,20, 230,220)
Next
T4 = MilliSecs()
Color 255,255,255
Text 16, 16, T2-T1
Text 16, 32, T4-T3
Flip
WaitKey
End
Function Triangle(x0,y0,x1,y1,x2,y2)
xval(0)=x0
yval(0)=y0
xval(1)=x1
yval(1)=y1
xval(2)=x2
yval(2)=y2
poly(3)
End Function
Function FastTriangle(x0,y0,x1,y1,x2,y2)
xval(0)=x0
yval(0)=y0
xval(1)=x1
yval(1)=y1
xval(2)=x2
yval(2)=y2
FastPoly(3)
End Function
Function Quad(x0,y0,x1,y1,x2,y2,x3,y3)
xval(0)=x0
yval(0)=y0
xval(1)=x1
yval(1)=y1
xval(2)=x2
yval(2)=y2
xval(3)=x3
yval(3)=y3
poly(4)
End Function
Function poly(vcount)
; get clipping region
width=GraphicsWidth()
height=GraphicsHeight()
; find top verticy
b=vcount-1
y=yval(0)
While c<>b
c=c+1
yy=yval(c)
If yy<y y=yy d=c
Wend
c=d
t=c
; draw top to bottom
While y<height
; get left gradient
If y=yval(c)
While y=yval(c)
x0=xval(c) Shl 16
c=c+1
If c>b c=a
If c=t Return
If y>yval(c) Return
Wend
h=yval(c)-y
g0=((xval(c) Shl 16)-x0)/h
EndIf
; get right gradient
If y=yval(d)
While y=yval(d)
x1=xval(d) Shl 16
d=d-1
If d<a d=b
If y>yval(d) Return
Wend
h=yval(d)-y
g1=((xval(d) Shl 16)-x1)/h
EndIf
; calc horizontal span
x=x1 Sar 16
w=((x0 Sar 16)-x)+1
; draw down to next vert
If (w>0 And y>-1 And x<width And x+w>0)
If x<0 w=w+x x=0 ;crop left
If x+w>width w=width-x ;crop right
Rect x,y,w,1
EndIf
; next
x0=x0+g0
x1=x1+g1
y=y+1
Wend
End Function
Function FastPoly(vcount)
RGBColor = ColorBlue() Or (ColorGreen() Shl 8) Or (ColorRed() Shl 16) Or ($ff000000)
; get clipping region
width=GraphicsWidth()
height=GraphicsHeight()
; Lock the current drawing buffer.
LockBuffer()
; find top verticy
b=vcount-1
y=yval(0)
While c<>b
c=c+1
yy=yval(c)
If yy<y y=yy d=c
Wend
c=d
t=c
; draw top to bottom
While y<height
; get left gradient
If y=yval(c)
While y=yval(c)
x0=xval(c) Shl 16
c=c+1
If c>b c=a
If c=t Goto Finish
If y>yval(c) Goto Finish
Wend
h=yval(c)-y
g0=((xval(c) Shl 16)-x0)/h
EndIf
; get right gradient
If y=yval(d)
While y=yval(d)
x1=xval(d) Shl 16
d=d-1
If d<a d=b
If y>yval(d) Goto Finish
Wend
h=yval(d)-y
g1=((xval(d) Shl 16)-x1)/h
EndIf
; calc horizontal span
x=x1 Sar 16
w=((x0 Sar 16)-x)+1
; draw down to next vert
If (w > 0) And (y > -1) And (x < width) And ((x+w) > 0)
;crop left
If x < 0
w=w+x
x=0
EndIf
;crop right
If (x+w) > width
w=width-x
EndIf
; Draw scanline.
For Lx = x To (x+w)
WritePixelFast Lx, y, RGBColor
Next
EndIf
; next
x0=x0+g0
x1=x1+g1
y=y+1
Wend
.Finish
; Unlock the draw buffer.
UnlockBuffer()
End Function
|