March 05, 2021, 07:29:52 AM

Author Topic: [bb] Anti-aliased line by MikeK [ 1+ years ago ]  (Read 428 times)

Offline BlitzBot

[bb] Anti-aliased line by MikeK [ 1+ years ago ]
« on: June 29, 2017, 12:28:39 AM »
Title : Anti-aliased line
Author : MikeK
Posted : 1+ years ago

Description : The code below contains the actual anti-aliased line routine as well as a very small demo that shows the visual result and measures drawing speed.  See comments for usage details.

Lines are plenty fast enough for non-real-time use (e.g., predrawing graphics) and can even be used in real time as long as the number of pixels drawn per frame time is fairly small. A few short rotating lines on a HUD display, for instance, should take under a millisecond.  The routine spends most of its time doing ReadPixel and WritePixel, so there isn't much chance for further optimization.


Code :
Code: BlitzBasic
  1. ; Anti-aliased lines demo & routine.   By Mike Keith, Feb 2002
  2. ;
  3. ;  To use anti-aliased lines in your program, just take the two lines below (between ===),
  4. ;  which set up a 256-byte lookup table, and the two functions after End.
  5. ;
  6. ;  AntiLine(x1,y1,x2,y2) draws a line from (x1,y1) to (x2,y2) in the
  7. ;  current drawing color to the currently selected buffer.
  8. ;
  9. ;  You can Lock and Unlock the buffer used (before and after batches of calls to AntiLine)
  10. ;  to gain some additional speed, as is done in the sample code below, which draws
  11. ;  the same pattern using regular and anti-aliased lines, so you can see the visual difference.
  12.  
  13. Graphics 800,600,32,1
  14.  
  15. ;==================================================
  16. ;  Lookup table required for Anti-aliased line routine.
  17. Dim AlineTable%(64)
  18.  
  19. InitAlineTable   ; You MUST do this once to initialize table
  20. ;==================================================
  21.  
  22.  
  23. SetBuffer BackBuffer()
  24. For y=0 To 599
  25.         z = y*255/599
  26.         Color z/2,z/3,0
  27.         Line 0,y,799,y
  28. Next
  29.  
  30. Color 0,255,255
  31. t1 = MilliSecs()
  32. For i=0 To 360 Step 5
  33.         dx = 150*Sin(i)
  34.         dy = 150*Cos(i)
  35.         Line 160+dx,300+dy,160-dx,300-dy
  36. Next
  37. t2 = MilliSecs()
  38.  
  39. Color 0,0,0
  40. Text 50,535,"Regular lines"
  41. Text 50,550,"Took "+Str$(t2-t1)+" ms"
  42.  
  43. If 1
  44. LockBuffer BackBuffer()
  45. Color 0,255,255
  46. t3 = MilliSecs()
  47. For i=0 To 360 Step 5
  48.         dx = 150*Sin(i)
  49.         dy = 150*Cos(i)
  50.         AntiLine(600+dx,300+dy,600-dx,300-dy)
  51. Next
  52. t4 = MilliSecs()
  53. UnlockBuffer BackBuffer()
  54. EndIf
  55.  
  56. Color 0,0,0
  57. Text 500,535,"Anti-aliased lines"
  58. Text 500,550,"Took "+Str$(t4-t3)+" ms"
  59.  
  60. Flip
  61.  
  62. While Not(KeyHit(1))
  63. Wend
  64.  
  65. End
  66.  
  67.  
  68.  
  69. ;=========================================================
  70. ;  Here are the actual Anti-aliased line functions
  71. ;--------------------------------------------------------------------------
  72. Function AntiLine(x1%, y1%, x2%, y2%)
  73.  
  74.         xd = x2-x1
  75.         yd = y2-y1
  76.        
  77.         If (xd = 0 Or yd = 0)
  78.                 Line(x1,y1,x2,y2)
  79.                 Return
  80.         EndIf
  81.  
  82.         r = ColorRed() Shl 16
  83.         g = ColorGreen() Shl 8
  84.         b = ColorBlue()
  85.        
  86.         WritePixel x1,y1,r+g+b
  87.         WritePixel x2,y2,r+g+b
  88.        
  89.         If (Abs(xd) > Abs(yd))
  90.                 If (x1 > x2)
  91.                         tmp = x1: x1 = x2: x2 = tmp
  92.                         tmp = y1: y1 = y2: y2 = tmp
  93.                         xd = x2-x1
  94.                         yd = y2-y1
  95.                 EndIf
  96.                
  97.                 grad = yd*65536/xd
  98.                 yf = y1*65536
  99.                
  100.                 For x=x1+1 To x2-1
  101.                         yf = yf + grad         
  102.                         w = (yf Sar 10) And $3f
  103.                         y = yf Sar 16
  104.                        
  105.                         MergePixel(x,y,r,g,b,63-w)
  106.                         MergePixel(x,y+1,r,g,b,w)
  107.                
  108.                 Next
  109.         Else
  110.                 If (y1 > y2)
  111.                         tmp = x1: x1 = x2: x2 = tmp
  112.                         tmp = y1: y1 = y2: y2 = tmp
  113.                         xd = x2-x1
  114.                         yd = y2-y1
  115.                 EndIf
  116.                
  117.                 grad = xd*65536/yd
  118.                 xf = x1*65536
  119.                
  120.                 For y=y1+1 To y2-1
  121.                         xf = xf + grad         
  122.                         w = (xf Sar 10) And $3f
  123.                         x = xf Sar 16
  124.                        
  125.                         MergePixel(x,y,r,g,b,63-w)
  126.                         MergePixel(x+1,y,r,g,b,w)
  127.                        
  128.                 Next
  129.         EndIf
  130.  
  131. End Function
  132.  
  133. ;--------------------------------------------------------------------------
  134. Function MergePixel(x,y,r,g,b,w)
  135.  
  136.         w = AlineTable(w)
  137.         pix = ReadPixel(x,y)
  138.  
  139.         ro = pix And $ff0000
  140.         go = pix And $ff00
  141.         bo = pix And $ff
  142.        
  143.         rnew = (ro + ((w*(r-ro)) Sar 8)) And $ff0000
  144.         gnew = (go + ((w*(g-go)) Sar 8)) And $ff00
  145.         bnew = bo + ((w*(b-bo)) Sar 8)
  146.        
  147.         WritePixel x,y,rnew+gnew+bnew
  148.  
  149. End Function
  150.  
  151. ;--------------------------------------------------------------------------
  152. Function InitAlineTable()
  153.  
  154.         For i=0 To 63
  155.                 ALineTable(i) = (Sqr(Float(4*i))*16)*.4 + (4*i)*.6
  156.         Next
  157.  
  158. End Function


Comments :


TAS(Posted 1+ years ago)

 Very nicely done, I wonder if there is way to extent to lines wider than 1 pixel?


Nate the Great(Posted 1+ years ago)

 wow nicely done and very fast thanks!


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal