how to improve 2d performance and some bugs ?

Windows specific forum
mohscorpion
New User
New User
Posts: 4
Joined: Thu Aug 01, 2013 1:07 pm

how to improve 2d performance and some bugs ?

Post by mohscorpion »

hi
i am new to pure basic , i wanted to test some 2d drawing .
i have written a radar sweep like program using this code:

Code: Select all

h = 700
w=700

Structure ray
  r.i
  theta.i
  x.i
  y.i
  sin.f
  cos.f
EndStructure 


Procedure showmap(height,width,rtheta)
  ;Delay(1)
EndProcedure
Procedure.f GSin(winkel.f) 
  ProcedureReturn Sin(winkel*(2*3.14159265/360)) 
EndProcedure 


Procedure.f GCos(winkel.f) 
  ProcedureReturn Cos(winkel*(2*3.14159265/360)) 
EndProcedure 


Dim rays.ray(360)

For t = 0 To 359
  tmp = t
  tmp = tmp -90 
  If (tmp < 0 )
    tmp = tmp + 360
  EndIf
  rtmp.f = Radian(tmp)
  xtmp = (w/2) + r * (Int(GCos(tmp)*100)/100)
  ytmp = ( h/2) + r * (Int(GSin(tmp)*100)/100)
  rays(t)\theta=tmp
  rays(t)\x=xtmp
  rays(t)\y=ytmp
  rays(t)\cos=GCos(tmp)
  rays(t)\sin=GSin(tmp)
  
Next



InitSprite()
OpenWindow(0, 0, 0, h, w, "2DDrawing Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;OpenWindowedScreen(WindowID(0), 0, 0, h, w, 0, 0, 0, #PB_Screen_WaitSynchronization )
CanvasGadget(0,0,0,h,w)
StartDrawing(CanvasOutput(0))

Box(0,0,h,w,$000000)
StopDrawing()
Repeat
  Repeat 
    Event = WindowEvent()
    
    Select Event
      Case #PB_Event_CloseWindow
        Quit = 1
    EndSelect
    
  Until Event = 0
  
  
  r = h / 2
  
  For deg = 0 To 359 Step 1
    StartDrawing(CanvasOutput(0))
    DrawingMode( #PB_2DDrawing_Transparent)
    Circle(w/2,h/2,2,RGB(Random(255), Random(255), Random(255)))
    
    theta = deg
    theta = theta -90 
    If (theta < 0 )
      theta = theta + 360
    EndIf
    rtheta.f = Radian(theta)
    rtheta2.f =Radian(theta+1)
    rtheta3.f =Radian(theta-1)
    r2 = r
    
    LineXY(w/2,h/2,rays(deg+1)\cos*r+w/2,rays(deg+1)\sin*r+h/2,$20f3fa)
    If deg = 0 
      tmpdeg=359 
    Else 
      tmpdeg=deg-1 
    EndIf
    LineXY(w/2,h/2,rays(deg)\cos*r+w/2,rays(deg)\sin*r+h/2,$000000)
    LineXY(w/2,h/2,rays(tmpdeg)\cos*r+w/2,rays(tmpdeg)\sin*r+h/2,$000000)
    For j = 1 To 5
      radius = Random(w/2-1)
      x.i = Int((w/2) + radius * rays(tmpdeg)\cos)
      y.i = Int(( h/2) + radius * rays(tmpdeg)\sin)
      Plot(x,y,RGB(Random(255), Random(255), Random(255)))
    Next
    DrawText(50,650,"theta=" + Str(deg) )
    StopDrawing()
  Next
 Until Quit = 1

there is two problems :
1- it is slow ( i have tried windows screen too)
2- it is supposed for radar to delete previously drawn line when inserting new line but it seems that new line is written with a little different angle ( i guess because of rounding sin and cos )
can any one shed some light on this ?
User avatar
Kukulkan
Addict
Addict
Posts: 1407
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: how to improve 2d performance and some bugs ?

Post by Kukulkan »

You should not call StartDrawing() each time. This eats up most of the speed.

Only the repeat part:

Code: Select all

Repeat
  Repeat
    Event = WindowEvent()
   
    Select Event
      Case #PB_Event_CloseWindow
        Quit = 1
    EndSelect
   
  Until Event = 0
 
 
  r = h / 2
  
  StartDrawing(CanvasOutput(0))
  Box(0,0,h,w,$000000)
  DrawingMode( #PB_2DDrawing_Transparent)
  For deg = 0 To 359 Step 1
    Circle(w/2,h/2,2,RGB(Random(255), Random(255), Random(255)))
   
    theta = deg
    theta = theta -90
    If (theta < 0 )
      theta = theta + 360
    EndIf
    rtheta.f = Radian(theta)
    rtheta2.f =Radian(theta+1)
    rtheta3.f =Radian(theta-1)
    r2 = r
   
    LineXY(w/2,h/2,rays(deg+1)\cos*r+w/2,rays(deg+1)\sin*r+h/2,$20f3fa)
    If deg = 0
      tmpdeg=359
    Else
      tmpdeg=deg-1
    EndIf
    LineXY(w/2,h/2,rays(deg)\cos*r+w/2,rays(deg)\sin*r+h/2,$000000)
    LineXY(w/2,h/2,rays(tmpdeg)\cos*r+w/2,rays(tmpdeg)\sin*r+h/2,$000000)
    For j = 1 To 5
      radius = Random(w/2-1)
      x.i = Int((w/2) + radius * rays(tmpdeg)\cos)
      y.i = Int(( h/2) + radius * rays(tmpdeg)\sin)
      Plot(x,y,RGB(Random(255), Random(255), Random(255)))
    Next
    DrawText(50,650,"theta=" + Str(deg) )
  Next
  StopDrawing()
 Until Quit = 1
To fast to see...

Might be even faster if you do StartDrawing() only once before your GUI loop and stop only after loop was ended...

Kukulkan
mohscorpion
New User
New User
Posts: 4
Joined: Thu Aug 01, 2013 1:07 pm

Re: how to improve 2d performance and some bugs ?

Post by mohscorpion »

the problem is that i have to show moving sweeper to user , i know it slows the program , i wanted to know if is there any solution for this?
User avatar
Kukulkan
Addict
Addict
Posts: 1407
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: how to improve 2d performance and some bugs ?

Post by Kukulkan »

Does this help?

Code: Select all

EnableExplicit

#ScreenWidth = 600
#ScreenHeight = 600
#refresh_every_ms = 20
#radius = 300

Structure structHit
  Radius.i
  Angle.f
  Visibility.i
  Size.i
EndStructure

Global NewList Hits.structHit()

Procedure ShowRadar()

  Protected Angle.f = 0
  Protected Event.i, Quit.i, x.i, Pos.i
  Protected LastRefresh.i
  
  ; generate hits
  For x.i = 1 To 20
    AddElement(Hits())
    Hits()\Radius = Random(#radius, 10)
    Hits()\Angle = Random(2*#PI*1000) / 1000
    Hits()\Visibility = 0 ; first invisible
    Hits()\Size = Random(5,1)
  Next 
  
  OpenWindow(0, 0, 0, #ScreenWidth, #ScreenHeight, "2DDrawing Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

  CanvasGadget(0,0,0,#ScreenWidth,#ScreenHeight)
  ; make black from the beginning
  StartDrawing(CanvasOutput(0))
  Box(0,0,#ScreenWidth,#ScreenHeight, RGB(0,0,0))
  StopDrawing()
  
  StartDrawing(CanvasOutput(0))
  DrawingMode(#PB_2DDrawing_AlphaBlend)
  Repeat
    Event = WindowEvent()
   
    Select Event
      Case #PB_Event_CloseWindow
        Quit = 1
    EndSelect
    
    Angle.f = Angle.f + 0.01
    If Angle.f > 2*#PI
      Angle.f = 0
    EndIf
    
    If ElapsedMilliseconds() > LastRefresh.i + #refresh_every_ms
      StopDrawing()
      StartDrawing(CanvasOutput(0))
      DrawingMode(#PB_2DDrawing_AlphaBlend)
      LastRefresh.i = ElapsedMilliseconds()
    EndIf
    
    ; dim the whole screen
    Box(0,0,#ScreenWidth,#ScreenHeight, RGBA(0,0,0, 3))
    
    ; draw rotating line
    LineXY(#ScreenWidth/2, 
           #ScreenHeight/2, 
           #ScreenWidth/2 + Sin(Angle.f) * #radius, 
           #ScreenHeight/2 + Cos(Angle.f) * #radius, 
           RGBA(0,255,0,200))
    
    ; check hits
    ForEach Hits()
      With Hits()
        If Abs(\Angle - Angle.f) < 0.01
          ; it is a hit on the line, make visible
          Hits()\Visibility = 100 + (\Size * 10) ; bigger hits lasting longer
        EndIf
        If \Visibility > 0
          ; draw visible hits...
          Circle(#ScreenWidth/2 + Sin(\Angle) * \Radius, 
                 #ScreenHeight/2 + Cos(\Angle) * \Radius, 
                 \Size, 
                 RGBA(200,255,200, 255))
          \Visibility = \Visibility - 1
        EndIf
      EndWith
    Next
    
  Until Quit = 1
  StopDrawing()
  
  CloseWindow(0)  
    
EndProcedure

ShowRadar()
Kukulkan
Last edited by Kukulkan on Fri Aug 02, 2013 7:22 am, edited 1 time in total.
mohscorpion
New User
New User
Posts: 4
Joined: Thu Aug 01, 2013 1:07 pm

Re: how to improve 2d performance and some bugs ?

Post by mohscorpion »

it helps but there are several problems :
1- sweeper starts from bottom and goes CCW which i need CW and start from north
2- hits are calculated before sweep which in my case is not , data are gathered from analog to digital data which i tried to simulate with random points
3- also it cleans old hits before end of sweep which in my case i need them for about 5 rounds ( dim very slower )
but thanks very much , i will change my code based on your method and reevaluate
:)
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: how to improve 2d performance and some bugs ?

Post by Danilo »

Try with sprites (windowed screen) instead 2D drawing commands like Line, Box, etc.

10 years old, so it doesn't work anymore out-of-the-box with latest PB: http://purearea.net/pb/CodeArchiv_v393/Graphics/Demos/Radar.pb
Maybe you want to test with 10 years old PB version.

Skeleton of Radar.pb for PB5.20 beta7+ (important, because Sprite3D change):

Code: Select all

; original: http://purearea.net/pb/CodeArchiv_v393/Graphics/Demos/Radar.pb

;#Width  = 1600 
;#Height = 1200 
#Width  = 1280
#Height = 1024
;#Width  = 1024 
;#Height = 768 
;#Width  = 800 
;#Height = 600 

#rotator_speed = 3 

#max_objects = 10 

Structure _OBJ 
  x.l 
  y.l 
  Transparency.l 
  Degree.f 
EndStructure 

NewList Objects._OBJ()


Procedure.f GSin(winkel.f) 
   ProcedureReturn Sin(winkel*(2*3.14159265/360)) 
EndProcedure 


Procedure.f GCos(winkel.f) 
   ProcedureReturn Cos(winkel*(2*3.14159265/360)) 
EndProcedure 


Procedure ObjectSound(x) 
  ;Beep_(800,50) 
EndProcedure 


Procedure MakeSprites() 

  h = #Height-100 

  If CreateSprite(1,512,512)=0 Or CreateSprite(0,512,512)=0 Or CreateSprite(2,256,256)=0 Or CreateSprite(3,h,h)=0 
    CloseScreen() 
    MessageRequester("ERROR","Cant create Sprites !") 
    End 
  EndIf 

  ; Radar rotator (green > black)
  StartDrawing(SpriteOutput(0)) 
    angle.f=90 
    Repeat 
      Line(255,255,GSin(angle)*255.0,GCos(angle)*255,RGB(0,Int(angle*2.8),0)) 
      angle.f - 0.001 
    Until angle <=0 
  StopDrawing() 
  
  ; Radar rotator (green > black) - reverse
  StartDrawing(SpriteOutput(1)) 
    angle.f=0
    Repeat 
      Line(255,255,GSin(angle)*255.0,GCos(angle)*255,RGB(0,Int((90-angle)*2.8),0)) 
      angle.f + 0.001
    Until angle >=90.0
  StopDrawing() 
  
  
  ; Radar objects 
  StartDrawing(SpriteOutput(2)) 
    For a = 127 To 0 Step -1 
      Circle(127,127,a,RGB(255-2*a,255-2*a,255-2*a)) 
    Next a 
  StopDrawing() 
  ZoomSprite(2,32,32) 

  ; Radar chassis 
  StartDrawing(SpriteOutput(3)) 
    Circle(h/2,h/2,h/2,RGB($40,$40,$40)) 
    Circle(h/2,h/2,h/2-10,RGB($00,$00,$00)) 
    DrawingMode(4) 
    For a = 0 To 5 
      Circle(h/2,h/2,h/10*a,RGB($40,$40,$40)) 
    Next a 
    For a = -2 To 2 
      Line(0,h/2+a,h,0,RGB($40,$40,$40)) 
    Next a 
    For a = -2 To 2 
      Line(h/2+a,0,0,h,RGB($40,$40,$40)) 
    Next a 
    For a = 30 To 330 Step 30 
      Line(h/2,h/2,GSin(a)*h/2,GCos(a)*h/2,RGB($40,$40,$40)) 
    Next a 
  StopDrawing() 

EndProcedure 


;- Start 
If InitKeyboard()=0 Or InitSprite()=0
  MessageRequester("ERROR","Cant init DirectX !") 
EndIf 

If OpenScreen(#Width,#Height,32,"Radar")=0 
  If OpenScreen(#Width,#Height,24,"Radar")=0 
    If OpenScreen(#Width,#Height,16,"Radar")=0 
      MessageRequester("ERROR","Cant open screen !") 
EndIf:EndIf:EndIf 
SetFrameRate(60)

MakeSprites() 


;- Init objects
;AddElement(Objects())
;Objects()\x      = (#Width/2-16)  -#Height/4+50 
;Objects()\y      = (#Height/2-16) +#Height/4+50 
;Objects()\Degree = 30 

;- Main loop 
Repeat 
  time = ElapsedMilliseconds()
  ExamineKeyboard()
  If IsScreenActive() And ScreenDeactivated = #False
      If KeyboardReleased(#PB_Key_Space)
          reverse ! 1
      EndIf
    If reverse = 0
        angle.f - #rotator_speed
    Else
        angle.f + #rotator_speed
    EndIf
    If angle < 0:angle+360:EndIf
    If angle > 360:angle-360:EndIf
    ClearScreen(0) 
    SpriteQuality(1) 
    ZoomSprite(reverse,#Height-100,#Height-100) 
    RotateSprite(reverse,angle,#PB_Absolute)
    DisplaySprite(reverse,(#Width-#Height)/2+50,50) 

    ;SpriteBlendingMode(5,2)
    
    ForEach Objects()
        ; display objects
    Next
    
    DisplayTransparentSprite(3,(#Width-#Height)/2+50,50,255) 

  ElseIf ScreenDeactivated = #False 
    ScreenDeactivated = #True 
  ElseIf IsScreenActive() And ScreenDeactivated = #True 
      ScreenDeactivated = #False 
      FlipBuffers() 
      MakeSprites() 
  EndIf 
  FlipBuffers() 
  Repeat:Delay(1):Until ElapsedMilliseconds()-20>=time 
Until KeyboardPushed(#PB_Key_Escape) 
;- End
Added SPACE key to reverse the radar (CW vs CCW).
Removed the objects and blending mode, don't understand what you want to display exactly.
User avatar
Kukulkan
Addict
Addict
Posts: 1407
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: how to improve 2d performance and some bugs ?

Post by Kukulkan »

I agree, sprites will be much more faster and also better looking.

For example, I would recommend a rotating sprite with the fading trail to get the radar-effect. Also some sprites as hits etc.

Best,

Kukulkan
mohscorpion
New User
New User
Posts: 4
Joined: Thu Aug 01, 2013 1:07 pm

Re: how to improve 2d performance and some bugs ?

Post by mohscorpion »

lemme explain more what i am trying to do
my application will be a like a radar , getting data from a network stream based on angle and points to display
so what i get is actually is like 4096 packets containing angle ( from north ) and points .
i am trying to replace .net application with purebasic and show simplicity and performance of purebasic .
so sweeper rotates at different speeds like 48/24/12 rpm and it displays points in each angle .
in my sample program i simulated a 360 angle sweep by 1 degree step and some random points to show (to compare to .net counterpart's performance ).
Post Reply