demo old school 2d

Programmation d'applications complexes
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: demo old school 2d

Message par manababel »

les fonctions "cos" et "sin" sont plus rapides qu'avant mais restent assez lentes.
elles sont toujours calculées sur le "fpu". ( Unité de calcul en virgule flottante )
À ma connaissance, ses fonctions n'existent pas en "simds".( mmx , sse ... )

faire ses fonctions en "simds" reviennent à faire ce que j'ai fait, un calcul d'approximation.
l'avantage en "simds", c'est de faire des calculs en parallèle , donc de calculer 4,8, 16 fonctions en même temps.

voici une version de Guillot "threadé"

Code : Tout sélectionner

Global ndt_max=CountCPUs(#PB_System_ProcessCPUs )
Global ndt=1

Global Dim Thread(ndt_max+1)

Global  lg=640
Global  ht=400

Global time.f=0.0
Global amp.f=8.0
Global freq.f=4.0

Global z1.f
Global z2.f
Global z3.f

Structure var
  start.q
  stop.q
EndStructure
Global Dim param.var((ndt_max)*2+1)


Global Dim screen(lg,ht)
; ------------------------------------------------------------
Macro clamp(x)
  If x>255 : x=255 : EndIf
  If x<0 : x=0: EndIf
EndMacro
;------------------------------------------------------------

Global Dim si.f(1023)
Global Dim co.f(1023)
#angleconv=1024.0/2.0/#PI
For i=0 To 1023
    si(i)=Sin(i/#angleconv)
    co(i)=Cos(i/#angleconv)
Next

Procedure.f fcos(x.f)
    i=x*#angleconv
    i & 1023
    ProcedureReturn co(i)
EndProcedure

Procedure.f fsin(x.f)
    i=x*#angleconv
    i & 1023
    ProcedureReturn si(i)
EndProcedure
Procedure.f rfcos(x.f)
    ProcedureReturn fCos(Radian(x))
EndProcedure

Procedure.f rfsin(x.f)
    ProcedureReturn fSin(Radian(x))
EndProcedure

;------------------------------------------------------------
Procedure update_fx1(i)
  start=param(i)\start
  stop=param(i)\stop
  rx.f=0
  gx.f=0
  bx.f=0
  dx.f=0
  dy.f=0
  time = time + 0.005
  If time>=314 : time=0 : EndIf
  For fy=start To stop
    For fx=0 To lg-1
      dx=fx/lg
      dy=(fy/lg - 0.3) * amp
      rx=1-Abs(dy - fcos((dx - time)*freq))
      gx=1-Abs(dy - fcos((dx + time)*freq))
      bx=1-Abs(dy - fcos((dx - time +0.5)*freq))
      rx=(rx*1.0)+(gx*0.5)+(bx*0.5)
      gx=(rx*0.5)+(gx*1.0)+(bx*0.5)
      bx=(rx*0.5)+(gx*0.5)+(bx*1.0)
      m=128
      r=(rx*m)+0
      g=(gx*m)+0
      b=(bx*m)+0
      clamp(r)
      clamp(g)
      clamp(b)
      var = r<<16 + g<<8 + b
      screen(fx,fy)=var
    Next
  Next
EndProcedure
;------------------------------------------------------------
Procedure update_fx2(i)
  start=param(i)\start
  stop=param(i)\stop
z1.f=z1+0.4
z2.f=z2+0.8
z3.f=z3+0.6
  For y=start To stop
    For x=0 To lg-1
      f1=120-Abs(fSin(Radian(x+z1+fSin(Radian(y*4+z1))*120))*120)
      f2=120-Abs(fCos(Radian(y-z2+fSin(Radian(x*4-z1))*120))*120)
      f3=Int(120-Abs(fSin(Radian(x*4+z2+fSin(Radian(x+y+z3))*40))*120))*256
      f4=Int(120-Abs(fCos(Radian(y*4-z2+fSin(Radian(x-y-z1))*40))*120))*256
      f5=Int(120-Abs(fSin(Radian(y*4+z1+fSin(Radian(x-y+z2))*40))*120))*65536
      f6=Int(120-Abs(fCos(Radian(x*4-z1+fSin(Radian(x+y-z2))*40))*120))*65536
      screen(x,y)=f1+f2+f3+f4+f5+f6
    Next
  Next
EndProcedure
;------------------------------------------------------------
Procedure update_fx3(i)
  start=param(i)\start
  stop=param(i)\stop
  freq.f=4.0
  time = time + 0.02
  If t>=314 : t=0 : EndIf     
  For fy=start To stop
    For fx=0 To lg-1
      dx.f=fx/lg
      dy.f=(fy/lg)
      a.f=(fSin((dy *1.5 - time *0.1)*freq)/2)-0.5
      b.f=(fCos((dy *1.5 - time *0.2)*freq)/2)-0.5
      c.f=(fSin((dy *1.5 - time *0.3)*freq)/2)-0.5
      d.f=(fCos((dy *3.5 + time *0.5)*freq)/3)-0.5
      If (dx+a)<>0 : rx.f=0.1/Abs(dx+a) : EndIf
      If (dx+b)<>0 : gx.f=0.1/Abs(dx+b) : EndIf
      If (dx+c)<>0 : bx.f=0.1/Abs(dx+c) : EndIf
      If (dx+d)<>0 : aa.f=0.1/Abs(dx+d) : EndIf
      rx=(rx*1.0)+(gx*0.3)+(bx*0.1)
      gx=(rx*0.1)+(gx*1.0)+(bx*0.3)
      bx=(rx*0.3)+(gx*0.1)+(bx*1.0)
      m=aa*200
      r=(rx*m)+0
      g=(gx*m)+0
      b=(bx*m)+0
      Clamp(r)
      Clamp(g)
      Clamp(b)
      var = r<<16 + g<<8 + b
      screen(fx,fy)=var
    Next
  Next
EndProcedure

;------------------------------------------------------------
Procedure update_fx4(i)
  start=param(i)\start
  stop=param(i)\stop
z1=z1+0.01
z2=z2+0.03
z3=z3+0.02
For y=start To stop
   For x=0 To lg-1
     x1.f=x/lg
     y1.f=y/ht
     f1=120-Abs(fSin(x1+z1+fSin(y1+z1)*6)*120)
     f2=120-Abs(fCos(y1-z2+fSin(x1-z1)*6)*120)
     f3=Int(120-Abs(fSin(x1*4+z2+fSin(x1+y1+z3)*4)*120))*256
     f4=Int(120-Abs(fCos(y1*4-z2+fSin(x1-y1-z1)*4)*120))*256
     f5=Int(120-Abs(fSin(y1*4+z1+fSin(x1-y1+z2)*4)*120))*65536
     f6=Int(120-Abs(fCos(x1*4-z1+fSin(x1+y1-z2)*4)*120))*65536
     var = f1+f2+f3+f4+f5+f6
     screen(x,y)=var
   Next
Next
EndProcedure
;------------------------------------------------------------

Procedure copy()
  StartDrawing(ImageOutput(1))
  buf=DrawingBuffer()
  StopDrawing()
  For y=0 To ht-1
    For x=0 To lg-1
      pos= ((y*lg) + x)<<2
      PokeL( buf + pos, (screen(x,y)))
    Next
  Next
EndProcedure
;------------------------------------------------------------
If OpenWindow(0, 0, 0, lg+20, ht+40, "Exemple...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  Global img = CreateImage(1, lg,ht,32)

  ComboBoxGadget(2, 10, 5, 100, 20)
  For i=0 To 3 : AddGadgetItem (2,-1,"FX"+Str(i+1)) : Next
  ComboBoxGadget(3, lg-100, 5, 100, 20)
  For i=0 To ndt_max-1 : AddGadgetItem (3,-1,Str(i+1)+" Threads") : Next
  SetGadgetState(2, 0)
  SetGadgetState(3, 0) 
  
  Repeat
    var=GetGadgetState(2)
    ndt=GetGadgetState(3)+1
    div=ht/ndt
    Event = WindowEvent()
    t=ElapsedMilliseconds()
    Select var
      Case 0  
        For i=0 To ndt-1
          Param(i)\start=i*div
          Param(i)\stop=(i*div)+div-1
          Thread(i)=CreateThread(@update_fx1(),i)
        Next
        For i=0 To ndt-1
          If Thread(i) : WaitThread(thread(i)):EndIf
        Next
        
      Case 1
        For i=0 To ndt-1
          Param(i)\start=i*div
          Param(i)\stop=(i*div)+div-1
          Thread(i)=CreateThread(@update_fx2(),i)
        Next
        For i=0 To ndt-1
          If Thread(i) : WaitThread(thread(i)):EndIf
        Next
        
      Case 2
        For i=0 To ndt-1
          Param(i)\start=i*div
          Param(i)\stop=(i*div)+div-1
          Thread(i)=CreateThread(@update_fx3(),i)
        Next
        For i=0 To ndt-1
          If Thread(i) : WaitThread(thread(i)):EndIf
        Next
        
      Case 3
        For i=0 To ndt-1
          Param(i)\start=i*div
          Param(i)\stop=(i*div)+div-1
          Thread(i)=CreateThread(@update_fx4(),i)
        Next
        For i=0 To ndt-1
          If Thread(i) : WaitThread(thread(i)):EndIf
        Next
        
    EndSelect
    t=ElapsedMilliseconds()-t
    copy()
    StartDrawing(WindowOutput(0))
    DrawImage(img,10,30)
    ;DrawText(150,5,Str(t)+"  ")
    StopDrawing()   
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()     
          Case 1
            CloseWindow(0)
            End     
        EndSelect   
    EndSelect
  Until Event = #PB_Event_CloseWindow
EndIf
Avatar de l’utilisateur
Guillot
Messages : 522
Inscription : jeu. 25/juin/2015 16:18

Re: demo old school 2d

Message par Guillot »

cette fois on peut doubler la resolution

je pensais pas que c'était si lent les cos et sin
du coup, je vais pouvoir faire des optimisations dans certains de mes pg

une optimisation qui peut aussi avoir son importance:
dans les tableaux à plusieurs dimension, faut faire attention à l'ordre des dimension
en PB les données sont stokées de maniere contigüe sur le dernier indice
ton tableau screen est inversé, je pense pas que ça ai bcp d'importance ici, mais dans le cas routine simple ça peut avoir un gros impact
je pense que c'est lié à la mémoire cache, surtout si le tableau excède sa taille

teste, chez moi, avec les indice dans le bon ordre je vais 5 fois plus vite

Code : Tout sélectionner

#n=8000
Dim t.l(#n,#n)

; pas bien !
ti=ElapsedMilliseconds()
For i=0 To #n
For j=0 To #n
t(j,i)=i+j
Next
Next
t1= ElapsedMilliseconds()-ti


; bien !!!
ti=ElapsedMilliseconds()
For j=0 To #n
For i=0 To #n
t(j,i)=i+j
Next
Next
t2= ElapsedMilliseconds()-ti

OpenConsole()
PrintN(Str(t1))
PrintN(Str(t2))
PrintN("Appuyez sur [Entree] pour quitter")
Input()
manababel
Messages : 135
Inscription : jeu. 14/mai/2020 7:40

Re: demo old school 2d

Message par manababel »

version sans tableau et "suppression" des divisions

Code : Tout sélectionner

Global ndt_max=CountCPUs(#PB_System_ProcessCPUs )
Global ndt=1

Global Dim Thread(ndt_max+1)

Global  lg=640
Global  ht=400

Global time.f=0.0
Global amp.f=8.0
Global freq.f=4.0

Global z1.f
Global z2.f
Global z3.f

Structure var
  start.q
  stop.q
EndStructure
Global Dim param.var((ndt_max)*2+1)

Global img, buf

; ------------------------------------------------------------
Macro clamp(x)
  If x>255 : x=255 : EndIf
  If x<0 : x=0: EndIf
EndMacro
;------------------------------------------------------------

Global Dim si.f(1023)
Global Dim co.f(1023)
#angleconv=1024.0/2.0/#PI
For i=0 To 1023
    si(i)=Sin(i/#angleconv)
    co(i)=Cos(i/#angleconv)
Next

Procedure.f fcos(x.f)
    i=x*#angleconv
    i & 1023
    ProcedureReturn co(i)
EndProcedure

Procedure.f fsin(x.f)
    i=x*#angleconv
    i & 1023
    ProcedureReturn si(i)
EndProcedure

;------------------------------------------------------------
Procedure update_fx1(i)
  start=param(i)\start
  stop=param(i)\stop
  rx.f=0
  gx.f=0
  bx.f=0
  dx.f=0
  dy.f=0
  rx1.f=0
  gx1.f=0
  bx1.f=0
  nlg.f=1/lg
  time = time + 0.005
  If time>=314 : time=0 : EndIf
  For fy=start To stop
    dy=(fy/lg - 0.3) * amp
    For fx=0 To lg-1
      dx=fx*nlg
      rx=1-Abs(dy - fcos((dx - time)*freq))
      gx=1-Abs(dy - fcos((dx + time)*freq))
      bx=1-Abs(dy - fcos((dx - time +0.5)*freq))
      rx1=(rx*0.5)
      gx1=(gx*0.5)
      bx1=(bx*0.5)
      rx=(rx*1.0)+gx1+bx1
      gx=rx1+(gx*1.0)+bx1
      bx=rx1+gx1+(bx*1.0)
      m=128
      r=(rx*m)+0
      g=(gx*m)+0
      b=(bx*m)+0
      clamp(r)
      clamp(g)
      clamp(b)
      var = r<<16 + g<<8 + b
      PokeL((buf+((fy*lg)+fx)<<2),var)
    Next
  Next
EndProcedure
;------------------------------------------------------------
Procedure update_fx2(i)
  start=param(i)\start
  stop=param(i)\stop
  z1.f=z1+0.4
  z2.f=z2+0.8
  z3.f=z3+0.6
  For y=start To stop
    For x=0 To lg-1
      f1=120-Abs(fSin(Radian(x+z1+fSin(Radian(y*4+z1))*120))*120)
      f2=120-Abs(fCos(Radian(y-z2+fSin(Radian(x*4-z1))*120))*120)
      f3=Int(120-Abs(fSin(Radian(x*4+z2+fSin(Radian(x+y+z3))*40))*120))*256
      f4=Int(120-Abs(fCos(Radian(y*4-z2+fSin(Radian(x-y-z1))*40))*120))*256
      f5=Int(120-Abs(fSin(Radian(y*4+z1+fSin(Radian(x-y+z2))*40))*120))*65536
      f6=Int(120-Abs(fCos(Radian(x*4-z1+fSin(Radian(x+y-z2))*40))*120))*65536
      PokeL((buf+((y*lg)+x)<<2),f1+f2+f3+f4+f5+f6)
    Next
  Next
EndProcedure
;------------------------------------------------------------
Procedure update_fx3(i)
  start=param(i)\start
  stop=param(i)\stop
  freq.f=4.0
  time = time + 0.02
  If t>=314 : t=0 : EndIf  
  nlg.f=1/lg
  For fy=start To stop
    dy.f=(fy/lg)
    For fx=0 To lg-1
      dx.f=fx*nlg
      a.f=(fSin((dy *1.5 - time *0.1)*freq)/2)-0.5
      b.f=(fCos((dy *1.5 - time *0.2)*freq)/2)-0.5
      c.f=(fSin((dy *1.5 - time *0.3)*freq)/2)-0.5
      d.f=(fCos((dy *3.5 + time *0.5)*freq)/3)-0.5
      If (dx+a)<>0 : rx.f=0.1/Abs(dx+a) : EndIf
      If (dx+b)<>0 : gx.f=0.1/Abs(dx+b) : EndIf
      If (dx+c)<>0 : bx.f=0.1/Abs(dx+c) : EndIf
      If (dx+d)<>0 : aa.f=0.1/Abs(dx+d) : EndIf
      rx=(rx*1.0)+(gx*0.3)+(bx*0.1)
      gx=(rx*0.1)+(gx*1.0)+(bx*0.3)
      bx=(rx*0.3)+(gx*0.1)+(bx*1.0)
      m=aa*200
      r=(rx*m)+0
      g=(gx*m)+0
      b=(bx*m)+0
      Clamp(r)
      Clamp(g)
      Clamp(b)
      PokeL((buf+((fy*lg)+fx)<<2),r<<16 + g<<8 + b)
    Next
  Next
EndProcedure

;------------------------------------------------------------
Procedure update_fx4(i)
  start=param(i)\start
  stop=param(i)\stop
  z1=z1+0.01
  z2=z2+0.03
  z3=z3+0.02
  nlg.f=1/lg
  For y=start To stop  
    y1.f=y/ht
    pos=buf+lg*y*4
    For x=0 To lg-1
     x1.f=x*nlg
     f1=120-Abs(fSin(x1+z1+fSin(y1+z1)*6)*120)
     f2=120-Abs(fCos(y1-z2+fSin(x1-z1)*6)*120)
     f3=Int(120-Abs(fSin(x1*4+z2+fSin(x1+y1+z3)*4)*120))*256
     f4=Int(120-Abs(fCos(y1*4-z2+fSin(x1-y1-z1)*4)*120))*256
     f5=Int(120-Abs(fSin(y1*4+z1+fSin(x1-y1+z2)*4)*120))*65536
     f6=Int(120-Abs(fCos(x1*4-z1+fSin(x1+y1-z2)*4)*120))*65536
     PokeL((pos+x*4),f1+f2+f3+f4+f5+f6)
   Next
Next
EndProcedure

;------------------------------------------------------------
If OpenWindow(0, 0, 0, lg+20, ht+40, "Exemple...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  img = CreateImage(1, lg,ht,32)
  StartDrawing(ImageOutput(1))
  buf = DrawingBuffer()
  StopDrawing()
  
  ComboBoxGadget(2, 10, 5, 100, 20)
  For i=0 To 3 : AddGadgetItem (2,-1,"FX"+Str(i+1)) : Next
  ComboBoxGadget(3, lg-100, 5, 100, 20)
  For i=0 To ndt_max-1 : AddGadgetItem (3,-1,Str(i+1)+" Threads") : Next
  SetGadgetState(2, 0)
  SetGadgetState(3, 0) 
  
  Repeat
    var=GetGadgetState(2)
    ndt=GetGadgetState(3)+1
    div=ht/ndt
    Event = WindowEvent()
    t=ElapsedMilliseconds()
    Select var
      Case 0  
        For i=0 To ndt-1
          Param(i)\start=i*div
          Param(i)\stop=(i*div)+div-1
          Thread(i)=CreateThread(@update_fx1(),i)
        Next
        For i=0 To ndt-1
          If Thread(i) : WaitThread(thread(i)):EndIf
        Next
        
      Case 1
        For i=0 To ndt-1
          Param(i)\start=i*div
          Param(i)\stop=(i*div)+div-1
          Thread(i)=CreateThread(@update_fx2(),i)
        Next
        For i=0 To ndt-1
          If Thread(i) : WaitThread(thread(i)):EndIf
        Next
        
      Case 2
        For i=0 To ndt-1
          Param(i)\start=i*div
          Param(i)\stop=(i*div)+div-1
          Thread(i)=CreateThread(@update_fx3(),i)
        Next
        For i=0 To ndt-1
          If Thread(i) : WaitThread(thread(i)):EndIf
        Next
        
      Case 3
        For i=0 To ndt-1
          Param(i)\start=i*div
          Param(i)\stop=(i*div)+div-1
          Thread(i)=CreateThread(@update_fx4(),i)
        Next
        For i=0 To ndt-1
          If Thread(i) : WaitThread(thread(i)):EndIf
        Next
        
    EndSelect
    t=ElapsedMilliseconds()-t

    StartDrawing(WindowOutput(0))
    DrawImage(img,10,30)
    ;DrawText(150,5,Str(t)+"  ")
    StopDrawing()   
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()     
          Case 1
            CloseWindow(0)
            End     
        EndSelect   
    EndSelect
  Until Event = #PB_Event_CloseWindow
EndIf
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: demo old school 2d

Message par djes »

Hey ! Ca fait plaisir de voir de tels codes ! Bravo les gars ! :D
Mesa
Messages : 1093
Inscription : mer. 14/sept./2011 16:59

Re: demo old school 2d

Message par Mesa »

Je mets la version avec le "fameux" double repeat dans la boucle car c'est essentiel pour le debbugger surtout pour les petite configuration pc. Sans elle le debugger en a plein ses culottes et fait ramer le programme inutilement.

Et surtout ça vide la boucle windows de l'OS Windows, ce qui empêche des bugs difficiles à trouver.
Je n'en suis pas certains mais il est possible que ce programme sans double repeat plante au bout de plusieurs minutes, en fonction de la quantité de ram et du fichier d'échange.

Code : Tout sélectionner

Global ndt_max=CountCPUs(#PB_System_ProcessCPUs ) 
Global ndt=1 

Global Dim Thread(ndt_max+1) 

Global  lg=640 
Global  ht=400 

Global time.f=0.0 
Global amp.f=8.0 
Global freq.f=4.0 

Global z1.f 
Global z2.f 
Global z3.f 

Structure var 
  start.q 
  stop.q 
EndStructure 
Global Dim param.var((ndt_max)*2+1) 

Global img, buf 

; ------------------------------------------------------------ 
Macro clamp(x) 
  If x>255 : x=255 : EndIf 
  If x<0 : x=0: EndIf 
EndMacro 
;------------------------------------------------------------ 

Global Dim si.f(1023) 
Global Dim co.f(1023) 
#angleconv=1024.0/2.0/#PI 
For i=0 To 1023 
  si(i)=Sin(i/#angleconv) 
  co(i)=Cos(i/#angleconv) 
Next 

Procedure.f fcos(x.f) 
  i=x*#angleconv 
  i & 1023 
  ProcedureReturn co(i) 
EndProcedure 

Procedure.f fsin(x.f) 
  i=x*#angleconv 
  i & 1023 
  ProcedureReturn si(i) 
EndProcedure 

;------------------------------------------------------------ 
Procedure update_fx1(i) 
  start=param(i)\start 
  stop=param(i)\stop 
  rx.f=0 
  gx.f=0 
  bx.f=0 
  dx.f=0 
  dy.f=0 
  rx1.f=0 
  gx1.f=0 
  bx1.f=0 
  nlg.f=1/lg 
  time = time + 0.005 
  If time>=314 : time=0 : EndIf 
  For fy=start To stop 
    dy=(fy/lg - 0.3) * amp 
    For fx=0 To lg-1 
      dx=fx*nlg 
      rx=1-Abs(dy - fcos((dx - time)*freq)) 
      gx=1-Abs(dy - fcos((dx + time)*freq)) 
      bx=1-Abs(dy - fcos((dx - time +0.5)*freq)) 
      rx1=(rx*0.5) 
      gx1=(gx*0.5) 
      bx1=(bx*0.5) 
      rx=(rx*1.0)+gx1+bx1 
      gx=rx1+(gx*1.0)+bx1 
      bx=rx1+gx1+(bx*1.0) 
      m=128 
      r=(rx*m)+0 
      g=(gx*m)+0 
      b=(bx*m)+0 
      clamp(r) 
      clamp(g) 
      clamp(b) 
      var = r<<16 + g<<8 + b 
      PokeL((buf+((fy*lg)+fx)<<2),var) 
    Next 
  Next 
EndProcedure 
;------------------------------------------------------------ 
Procedure update_fx2(i) 
  start=param(i)\start 
  stop=param(i)\stop 
  z1.f=z1+0.4 
  z2.f=z2+0.8 
  z3.f=z3+0.6 
  For y=start To stop 
    For x=0 To lg-1 
      f1=120-Abs(fSin(Radian(x+z1+fSin(Radian(y*4+z1))*120))*120) 
      f2=120-Abs(fCos(Radian(y-z2+fSin(Radian(x*4-z1))*120))*120) 
      f3=Int(120-Abs(fSin(Radian(x*4+z2+fSin(Radian(x+y+z3))*40))*120))*256 
      f4=Int(120-Abs(fCos(Radian(y*4-z2+fSin(Radian(x-y-z1))*40))*120))*256 
      f5=Int(120-Abs(fSin(Radian(y*4+z1+fSin(Radian(x-y+z2))*40))*120))*65536 
      f6=Int(120-Abs(fCos(Radian(x*4-z1+fSin(Radian(x+y-z2))*40))*120))*65536 
      PokeL((buf+((y*lg)+x)<<2),f1+f2+f3+f4+f5+f6) 
    Next 
  Next 
EndProcedure 
;------------------------------------------------------------ 
Procedure update_fx3(i) 
  start=param(i)\start 
  stop=param(i)\stop 
  freq.f=4.0 
  time = time + 0.02 
  If t>=314 : t=0 : EndIf   
  nlg.f=1/lg 
  For fy=start To stop 
    dy.f=(fy/lg) 
    For fx=0 To lg-1 
      dx.f=fx*nlg 
      a.f=(fSin((dy *1.5 - time *0.1)*freq)/2)-0.5 
      b.f=(fCos((dy *1.5 - time *0.2)*freq)/2)-0.5 
      c.f=(fSin((dy *1.5 - time *0.3)*freq)/2)-0.5 
      d.f=(fCos((dy *3.5 + time *0.5)*freq)/3)-0.5 
      If (dx+a)<>0 : rx.f=0.1/Abs(dx+a) : EndIf 
      If (dx+b)<>0 : gx.f=0.1/Abs(dx+b) : EndIf 
      If (dx+c)<>0 : bx.f=0.1/Abs(dx+c) : EndIf 
      If (dx+d)<>0 : aa.f=0.1/Abs(dx+d) : EndIf 
      rx=(rx*1.0)+(gx*0.3)+(bx*0.1) 
      gx=(rx*0.1)+(gx*1.0)+(bx*0.3) 
      bx=(rx*0.3)+(gx*0.1)+(bx*1.0) 
      m=aa*200 
      r=(rx*m)+0 
      g=(gx*m)+0 
      b=(bx*m)+0 
      Clamp(r) 
      Clamp(g) 
      Clamp(b) 
      PokeL((buf+((fy*lg)+fx)<<2),r<<16 + g<<8 + b) 
    Next 
  Next 
EndProcedure 

;------------------------------------------------------------ 
Procedure update_fx4(i) 
  start=param(i)\start 
  stop=param(i)\stop 
  z1=z1+0.01 
  z2=z2+0.03 
  z3=z3+0.02 
  nlg.f=1/lg 
  For y=start To stop   
    y1.f=y/ht 
    pos=buf+lg*y*4 
    For x=0 To lg-1 
      x1.f=x*nlg 
      f1=120-Abs(fSin(x1+z1+fSin(y1+z1)*6)*120) 
      f2=120-Abs(fCos(y1-z2+fSin(x1-z1)*6)*120) 
      f3=Int(120-Abs(fSin(x1*4+z2+fSin(x1+y1+z3)*4)*120))*256 
      f4=Int(120-Abs(fCos(y1*4-z2+fSin(x1-y1-z1)*4)*120))*256 
      f5=Int(120-Abs(fSin(y1*4+z1+fSin(x1-y1+z2)*4)*120))*65536 
      f6=Int(120-Abs(fCos(x1*4-z1+fSin(x1+y1-z2)*4)*120))*65536 
      PokeL((pos+x*4),f1+f2+f3+f4+f5+f6) 
    Next 
  Next 
EndProcedure 

;------------------------------------------------------------ 
If OpenWindow(0, 0, 0, lg+20, ht+40, "Exemple...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
  
  img = CreateImage(1, lg,ht,32) 
  StartDrawing(ImageOutput(1)) 
  buf = DrawingBuffer() 
  StopDrawing() 
  
  ComboBoxGadget(2, 10, 5, 100, 20) 
  For i=0 To 3 : AddGadgetItem (2,-1,"FX"+Str(i+1)) : Next 
  ComboBoxGadget(3, lg-100, 5, 100, 20) 
  For i=0 To ndt_max-1 : AddGadgetItem (3,-1,Str(i+1)+" Threads") : Next 
  SetGadgetState(2, 0) 
  SetGadgetState(3, 0)  
  
  Repeat
    Repeat 
      Event = WindowEvent() 
      Select Event      
        Case #PB_Event_CloseWindow 
          CloseWindow(0) 
          End         
      EndSelect 
    Until Event = 0
    
    
    var=GetGadgetState(2) 
    ndt=GetGadgetState(3)+1 
    DIV=ht/ndt 
   
    t=ElapsedMilliseconds() 
    Select var 
      Case 0   
        For i=0 To ndt-1 
          Param(i)\start=i*DIV 
          Param(i)\stop=(i*DIV)+DIV-1 
          Thread(i)=CreateThread(@update_fx1(),i) 
        Next 
        For i=0 To ndt-1 
          If Thread(i) : WaitThread(thread(i)):EndIf 
        Next 
        
      Case 1 
        For i=0 To ndt-1 
          Param(i)\start=i*DIV 
          Param(i)\stop=(i*DIV)+DIV-1 
          Thread(i)=CreateThread(@update_fx2(),i) 
        Next 
        For i=0 To ndt-1 
          If Thread(i) : WaitThread(thread(i)):EndIf 
        Next 
        
      Case 2 
        For i=0 To ndt-1 
          Param(i)\start=i*DIV 
          Param(i)\stop=(i*DIV)+DIV-1 
          Thread(i)=CreateThread(@update_fx3(),i) 
        Next 
        For i=0 To ndt-1 
          If Thread(i) : WaitThread(thread(i)):EndIf 
        Next 
        
      Case 3 
        For i=0 To ndt-1 
          Param(i)\start=i*DIV 
          Param(i)\stop=(i*DIV)+DIV-1 
          Thread(i)=CreateThread(@update_fx4(),i) 
        Next 
        For i=0 To ndt-1 
          If Thread(i) : WaitThread(thread(i)):EndIf 
        Next 
        
    EndSelect 
    t=ElapsedMilliseconds()-t 
    
    StartDrawing(WindowOutput(0)) 
    DrawImage(img,10,30) 
    DrawText(150,5,Str(t)+" ") 
    StopDrawing()    
    
    Delay(1)
  ForEver
EndIf
M.
Répondre