Here is a quick demonstration of the code above. The rays drawn on the right of the screen are anti-aliased, the ones on the left are not. You can enable the screenshot flag (see code) to save the results to 'out.bmp' when you hit ESCape to exit. If I comment out the Anti-Aliased line rays I get 1650 fps, but only 24 fps when they are drawn. No debugger enabled. This is on an Athlon XP 2400/Radeon 9700 system. Faster/better techniques? Please share them here.
Code: Select all
; Anti -Aliased line demo by Griz Nov 2004
ExamineDesktops()
Global Done : Done = #False
Global ScreenWidth : ScreenWidth = DesktopWidth(0)
Global screenheight : ScreenHeight=DesktopHeight(0)
Global ScreenDepth : ScreenDepth = DesktopDepth(0)
Global Radius : Radius = ScreenWidth / 4
Global CircleAX : CircleAX = Radius
Global CircleAY : CircleAY = Radius+2
Global CircleBX : CircleBX = Radius*3-2
Global CircleBY : CircleBY = Radius+2
Global Angle : Angle = 180
Global Lcol : Lcol = RGB(255,255,255)
Global ScreenShot : Screen_Shot = #false
Global Fps.f : Fps = 0.0
Global FpsTimerCount : FpsTimerCount = 0
Global CurrentFps.f : CurrentFps = 0.0
Global FpsTimer : FpsTimer = ElapsedMilliseconds()
Procedure Mod(a,b)
If b = 0: b = 1:EndIf
ProcedureReturn a-a/b*b
EndProcedure
Procedure.f DegToRad(deg.f)
ProcedureReturn deg/57.29578
EndProcedure
Procedure.f RadToDeg(rad.f)
ProcedureReturn rad*57.29578
EndProcedure
Procedure.f WrapAngle(value.f)
value.f=mod(value.f,360.0)
If value.f<0.0
value.f=value.f+360.0
EndIf
ProcedureReturn value.f
EndProcedure
Procedure MergePixel(x,y,r,g,b,w)
col = Point(x,y) : r2 = Red(col)
g2 = Green(col) : b2 = Blue(col)
rnew = ((r * w) >> 8) + ((r2 * (255 - w)) >> 8)
gnew = ((g * w) >> 8) + ((g2 * (255 - w)) >> 8)
bnew = ((b * w) >> 8) + ((b2 * (255 - w)) >> 8)
Plot(x,y,RGB(rnew,gnew,bnew))
EndProcedure
Procedure AntiLineXY(x1,y1,x2,y2,col)
r = Red(col)
g = Green(col)
b = Blue(col)
FrontColor(r,g,b)
Plot(x1,y1,col)
Plot(x2,y2,col)
xd = x2 - x1
yd = y2 - y1
If (xd = 0 Or yd = 0)
LineXY(x1,y1,x2,y2)
ProcedureReturn
EndIf
If Abs(xd) > Abs(yd)
If (x1>x2)
tmp = x1: x1 = x2: x2 = tmp
tmp = y1: y1 = y2: y2 = tmp
xd = x2-x1
yd = y2-y1
EndIf
grad = yd * 65536 / xd
yf = y1 * 65536
For x = x1 + 1 To x2 - 1
yf = yf + grad
w = (yf >> 8) & $FF
y = yf >> 16
MergePixel(x,y,r,g,b,255-w)
MergePixel(x,y+1,r,g,b,w)
Next
Else
If (y1 > y2)
tmp = x1: x1 = x2: x2 = tmp
tmp = y1: y1 = y2: y2 = tmp
xd = x2 - x1
yd = y2 - y1
EndIf
grad = xd * 65536 / yd
xf = x1 * 65536
For y = y1 + 1 To y2 - 1
xf = xf + grad
w = (xf >> 8) & $FF
x = xf >> 16
MergePixel(x,y,r,g,b,255-w)
MergePixel(x+1,y,r,g,b,w)
Next
EndIf
EndProcedure
; initialize direct X
If InitSprite()=0 Or InitKeyboard()=0
MessageRequester("Error", "Can't Open Direct X!", 0)
End
EndIf
; open full screen
If OpenScreen(screenwidth, screenheight, screendepth, "Antialiased Line Demo")=0
MessageRequester("Error", "Can't Open Screen!", 0)
End
EndIf
Repeat
ExamineKeyboard()
If KeyboardReleased(#pb_key_escape)
Done = #true
EndIf
ClearScreen(0,0,0)
StartDrawing(ScreenOutput())
; draw lines
For a2 = 0 To 36
a3=WrapAngle(a2*10+angle)
LineXY(CircleAX, CircleAY, CircleAX-Radius*Cos(DegToRad(a3)),CircleAY-Radius*Sin(DegToRad(a3)),lcol)
AntiLineXY(CircleBX, CircleBY, CircleBX-Radius*Cos(DegToRad(a3)),CircleBY-Radius*Sin(DegToRad(a3)),lcol)
Next
; draw frames per second
DrawingMode(1)
FrontColor(128,128,128)
Status$="fps = "+Str(CurrentFps)
Locate((CircleBX - CircleAX)-(TextLength(status$)/2), CircleAY*2)
DrawText(status$)
StopDrawing()
If Done = #True And ScreenShot = #True
g=GrabSprite(#pb_any,0,0,ScreenWidth, ScreenHeight)
SaveSprite(g, "out.bmp")
FreeSprite(g)
EndIf
FlipBuffers(0)
Angle + 1
If Angle > 359
Angle = 0
EndIf
Fps+1
FpsTimerCount = ElapsedMilliseconds()
If FpsTimerCount - FpsTimer => 1000
CurrentFps = Fps
Fps = 0
FpsTimer = ElapsedMilliseconds()
EndIf
Until done=#true
End