demo old school 2d

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

demo old school 2d

Message par manababel »

Voici 4 programmes qui ne servent à rien.
Si votre écran est mal paramètre , l'effet 2 et 4 ont un rendu "dégalace".

Attention, programme gourmand en resource.

Code : Tout sélectionner

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


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

#c1=0.99940307
#c2=-0.49558072 + 0.09079168
#twopi=2.0*#PI
#two_over_pi= 2.0/#PI
#halfpi=#PI/2.0

Procedure.f fcos(x.f) 
  ;x=Mod(x, #twopi); 
  v.f=x/#twopi
  x = ((( v-(Int(v)) )*#twopi))
  If(x<0):x=-x:EndIf 
  quad=Int(x * #two_over_pi)	
  If quad=0       
    x=(#c1 + x * x * #c2 )
  EndIf
  If quad=1
    x=#PI-x
    x=-(#c1 + x * x * #c2 )
  EndIf
  If quad=2
    x=x-#PI
    x=-(#c1 + x * x * #c2 )
  EndIf
  If quad=3
    x=#twopi-x
    x=(#c1 + x * x * #c2 )
  EndIf 
  ProcedureReturn x
EndProcedure

Procedure.f fsin(x.f) 
  x = #halfpi-x  
  ;x=Mod(x, #twopi); 
  v.f=x/#twopi
  x = ((( v-(Int(v)) )*#twopi))
  If(x<0):x=-x:EndIf 
  quad=Int(x * #two_over_pi)	
  If quad=0       
    x=(#c1 + x * x * #c2 )
  EndIf
  If quad=1
    x=#PI-x
    x=-(#c1 + x * x * #c2 )
  EndIf
  If quad=2
    x=x-#PI
    x=-(#c1 + x * x * #c2 )
  EndIf
  If quad=3
    x=#twopi-x
    x=(#c1 + x * x * #c2 )
  EndIf 
  ProcedureReturn x
EndProcedure

Procedure.f rfcos(x.f) 
  x = x / 180 * #PI ; radian
  ;x=Mod(x, #twopi); 
  v.f=x/#twopi
  x = ((( v-(Int(v)) )*#twopi))
  If(x<0):x=-x:EndIf 
  quad=Int(x * #two_over_pi)	
  If quad=0       
    x=(#c1 + x * x * #c2 )
  EndIf
  If quad=1
    x=#PI-x
    x=-(#c1 + x * x * #c2 )
  EndIf
  If quad=2
    x=x-#PI
    x=-(#c1 + x * x * #c2 )
  EndIf
  If quad=3
    x=#twopi-x
    x=(#c1 + x * x * #c2 )
  EndIf 
  ProcedureReturn x
EndProcedure

Procedure.f rfsin(x.f) 
  x = x / 180 * #PI ; radian
  x = #halfpi-x  
  ;x=Mod(x, #twopi); 
  v.f=x/#twopi
  x = ((( v-(Int(v)) )*#twopi))
  If(x<0):x=-x:EndIf 
  quad=Int(x * #two_over_pi)	
  If quad=0       
    x=(#c1 + x * x * #c2 )
  EndIf
  If quad=1
    x=#PI-x
    x=-(#c1 + x * x * #c2 )
  EndIf
  If quad=2
    x=x-#PI
    x=-(#c1 + x * x * #c2 )
  EndIf
  If quad=3
    x=#twopi-x
    x=(#c1 + x * x * #c2 )
  EndIf 
  ProcedureReturn x
EndProcedure
;------------------------------------------------------------
Procedure update_fx1()
  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=0 To ht-1 
    For fx=0 To lg-1
      dx=fx/lg
      dy=(fy/lg - 0.3) * amp
      rx=1-Abs(dy - fSin((dx - time)*freq))
      gx=1-Abs(dy - fSin((dx + time)*freq))
      bx=1-Abs(dy - fSin((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()
 z1.f=z1+0.4
 z2.f=z2+0.8
 z3.f=z3+0.6
  For y=0 To ht-1 
    For x=0 To lg-1
      f1=120-Abs(rfSin(x+z1+rfSin(y*4+z1)*120)*120)
      f2=120-Abs(rfCos(y-z2+rfSin(x*4-z1)*120)*120)
      f3=Int(120-Abs(rfSin(x*4+z2+rfSin(x+y+z3)*40)*120))*256
      f4=Int(120-Abs(rfCos(y*4-z2+rfSin(x-y-z1)*40)*120))*256
      f5=Int(120-Abs(rfSin(y*4+z1+rfSin(x-y+z2)*40)*120))*65536
      f6=Int(120-Abs(rfCos(x*4-z1+rfSin(x+y-z2)*40)*120))*65536
      screen(x,y)=f1+f2+f3+f4+f5+f6
    Next
  Next
EndProcedure
;------------------------------------------------------------
Procedure update_fx3()
  freq.f=4.0
  time = time + 0.02
  If t>=314 : t=0 : EndIf     
  For fy=0 To ht-1  
    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()
 z1=z1+0.01
 z2=z2+0.03
 z3=z3+0.02
 For y=0 To ht-1
   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
  
  Repeat
    var=GetGadgetState(2) 
    Event = WindowEvent()
    Select var
      Case 0
        update_fx1()
      Case 1
        update_fx2()
      Case 2
        update_fx3()
      Case 3
        update_fx4()
    EndSelect
    
    copy()
    StartDrawing(WindowOutput(0))
    DrawImage(img,10,30)
    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 : 529
Inscription : jeu. 25/juin/2015 16:18

Re: demo old school 2d

Message par Guillot »

tres jolie

je vais regarder si y'a moyen d'optimiser le truc

PS:enlevez le debogueur
Avatar de l’utilisateur
Guillot
Messages : 529
Inscription : jeu. 25/juin/2015 16:18

Re: demo old school 2d

Message par Guillot »

bon j'ai fais des modifs, mais pas vu de difference notable au niveau vitesse
cela dit, y'a 2 modifs interessantes:
pour les modulo
PB utilise un modulo un peu particulier
lorsque le numerateur est négatif il renvoi un nombre negatif (c'est tres chiant)
pour corriger ça t'as juste à ajouter un multiple du dénominateur suffisament grand

Code : Tout sélectionner

x=Mod(x+#pi100, #twopi)  (#pi100=#pi*100)
ça t'évitera ton merdier:

Code : Tout sélectionner

 v.f=x/#twopi
 x = ((( v-(Int(v)) )*#twopi))
 If(x<0):x=-x:EndIf
autre chose, pour convertir ton tableau en bitmap
t'as juste à faire:

Code : Tout sélectionner

StartDrawing(ImageOutput(1))
CopyMemory(@screen(0,0),DrawingBuffer(),ht*lg*4)
StopDrawing()
pas besoin de poke
attention : le 1er indice du tableau correspond aux lignes, le 2é aux colonnes

(peut etre en mettant fsin et fcos dans des tableau on peut optimiser le truc)

Code : Tout sélectionner

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


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

#c1=0.99940307
#c2=-0.49558072 + 0.09079168
#twopi=2.0*#PI
#two_over_pi= 2.0/#PI
#halfpi=#PI/2.0
#pi100=100*#PI ;   <===============

Procedure.f fcos(x.f)
    x=Mod(x+#pi100, #twopi);   <===============
    quad=Int(x * #two_over_pi)   
    Select quad
        Case 0       
            x=(#c1 + x * x * #c2 )
        Case 1
            x=#PI-x
            x=-(#c1 + x * x * #c2 )
        Case 2
            x=x-#PI
            x=-(#c1 + x * x * #c2 )
        Case 3
            x=#twopi-x
            x=(#c1 + x * x * #c2 )
    EndSelect
    ProcedureReturn x
EndProcedure

Procedure.f fsin(x.f)
    x=Mod(#halfpi-x+#pi100, #twopi);   <===============
    quad=Int(x * #two_over_pi)  
    Select quad
        Case 0       
            x=(#c1 + x * x * #c2 )
        Case 1
            x=#PI-x
            x=-(#c1 + x * x * #c2 )
        Case 2
            x=x-#PI
            x=-(#c1 + x * x * #c2 )
        Case 3
            x=#twopi-x
            x=(#c1 + x * x * #c2 )
    EndSelect
    ProcedureReturn x
EndProcedure

Procedure.f rfcos(x.f)
    ProcedureReturn fCos(Radian(x))
EndProcedure

Procedure.f rfsin(x.f)
    ProcedureReturn fSin(Radian(x))
EndProcedure
;------------------------------------------------------------
Procedure update_fx1()
  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=0 To ht-1
    For fx=0 To lg-1
      dx=fx/lg
      dy=(fy/lg - 0.3) * amp
      rx=1-Abs(dy - fSin((dx - time)*freq))
      gx=1-Abs(dy - fSin((dx + time)*freq))
      bx=1-Abs(dy - fSin((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=RGB(r,g,b)
      screen(fy,fx)=var;   <===============
    Next
  Next
EndProcedure
;------------------------------------------------------------
Procedure update_fx2()
z1.f=z1+0.4
z2.f=z2+0.8
z3.f=z3+0.6
  For y=0 To ht-1
    For x=0 To lg-1
      f1=120-Abs(rfSin(x+z1+RfSin(y*4+z1)*120)*120)
      f2=120-Abs(rfCos(y-z2+rfSin(x*4-z1)*120)*120)
      f3=Int(120-Abs(rfSin(x*4+z2+rfSin(x+y+z3)*40)*120))*256
      f4=Int(120-Abs(rfCos(y*4-z2+rfSin(x-y-z1)*40)*120))*256
      f5=Int(120-Abs(rfSin(y*4+z1+rfSin(x-y+z2)*40)*120))*65536
      f6=Int(120-Abs(rfCos(x*4-z1+rfSin(x+y-z2)*40)*120))*65536
      screen(y,x)=f1+f2+f3+f4+f5+f6;   <===============
    Next
  Next
EndProcedure
;------------------------------------------------------------
Procedure update_fx3()
  freq.f=4.0
  time = time + 0.02
  If t>=314 : t=0 : EndIf     
  For fy=0 To ht-1 
    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=RGB(r,g,b)
      screen(fy,fx)=var;   <===============
    Next
  Next
EndProcedure
;------------------------------------------------------------
Procedure update_fx4()
z1=z1+0.01
z2=z2+0.03
z3=z3+0.02
For y=0 To ht-1
   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(y,x)=var;   <===============
   Next
Next
EndProcedure
;------------------------------------------------------------

Procedure copy();   <===============
    StartDrawing(ImageOutput(1))
    CopyMemory(@screen(0,0),DrawingBuffer(),ht*lg*4)
    StopDrawing()
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
 SetGadgetState(2,0)
  Repeat
    var=GetGadgetState(2)
    Event = WindowEvent()
    Select var
      Case 0
        update_fx1()
      Case 1
        update_fx2()
      Case 2
        update_fx3()
      Case 3
        update_fx4()
    EndSelect
   
    copy()
    StartDrawing(WindowOutput(0))
    DrawImage(img,10,30)
    StopDrawing()   
    Select Event 
      Case #PB_Event_Gadget
        Select EventGadget()     
          Case 1
            CloseWindow(0)
            End     
        EndSelect   
    EndSelect
  Until Event = #PB_Event_CloseWindow
EndIf
manababel
Messages : 136
Inscription : jeu. 14/mai/2020 7:40

Re: demo old school 2d

Message par manababel »

Merci pour vos commentaires.

J'ai essayé d'optimiser au mieux.
Votre méthode d'utiliser un modulo et plus lente que d'utiliser une division,
l'idéal serait de pouvoir viré le modulo et la division.
De plus , il faudrait remplacent les procédures "cos" et "Sin" par des macros.

Votre procédure "copy" est bien plus rapide que la mienne.

Vos procédures "cos" et "sin" donnent des résultats différents des miennes .
sur la démo 1, il y a beaucoup plus de jaune.
Avatar de l’utilisateur
venom
Messages : 3072
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: demo old school 2d

Message par venom »

Bonjour, sympa les effets. Merci du partage






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: demo old school 2d

Message par falsam »

manababel a écrit :Attention, programme gourmand en resource
Effectivement mais j'aime bien ces effets :wink:
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Mesa
Messages : 1097
Inscription : mer. 14/sept./2011 16:59

Re: demo old school 2d

Message par Mesa »

On peut améliorer en réécrivant la boucle comme ci dessous mais le mieux serait de remplacer l'image par un sprite et un openwindowscreen qui utiliserait l'acceleration de la cartre graphique.

Code : Tout sélectionner

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 


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

#c1=0.99940307 
#c2=-0.49558072 + 0.09079168 
#twopi=2.0*#PI 
#two_over_pi= 2.0/#PI 
#halfpi=#PI/2.0 

Procedure.f fcos(x.f)  
  ;x=Mod(x, #twopi);  
  v.f=x/#twopi 
  x = ((( v-(Int(v)) )*#twopi)) 
  If(x<0):x=-x:EndIf  
  quad=Int(x * #two_over_pi)    
  If quad=0        
    x=(#c1 + x * x * #c2 ) 
  EndIf 
  If quad=1 
    x=#PI-x 
    x=-(#c1 + x * x * #c2 ) 
  EndIf 
  If quad=2 
    x=x-#PI 
    x=-(#c1 + x * x * #c2 ) 
  EndIf 
  If quad=3 
    x=#twopi-x 
    x=(#c1 + x * x * #c2 ) 
  EndIf  
  ProcedureReturn x 
EndProcedure 

Procedure.f fsin(x.f)  
  x = #halfpi-x   
  ;x=Mod(x, #twopi);  
  v.f=x/#twopi 
  x = ((( v-(Int(v)) )*#twopi)) 
  If(x<0):x=-x:EndIf  
  quad=Int(x * #two_over_pi)    
  If quad=0        
    x=(#c1 + x * x * #c2 ) 
  EndIf 
  If quad=1 
    x=#PI-x 
    x=-(#c1 + x * x * #c2 ) 
  EndIf 
  If quad=2 
    x=x-#PI 
    x=-(#c1 + x * x * #c2 ) 
  EndIf 
  If quad=3 
    x=#twopi-x 
    x=(#c1 + x * x * #c2 ) 
  EndIf  
  ProcedureReturn x 
EndProcedure 

Procedure.f rfcos(x.f)  
  x = x / 180 * #PI ; radian 
                    ;x=Mod(x, #twopi);  
  v.f=x/#twopi 
  x = ((( v-(Int(v)) )*#twopi)) 
  If(x<0):x=-x:EndIf  
  quad=Int(x * #two_over_pi)    
  If quad=0        
    x=(#c1 + x * x * #c2 ) 
  EndIf 
  If quad=1 
    x=#PI-x 
    x=-(#c1 + x * x * #c2 ) 
  EndIf 
  If quad=2 
    x=x-#PI 
    x=-(#c1 + x * x * #c2 ) 
  EndIf 
  If quad=3 
    x=#twopi-x 
    x=(#c1 + x * x * #c2 ) 
  EndIf  
  ProcedureReturn x 
EndProcedure 

Procedure.f rfsin(x.f)  
  x = x / 180 * #PI ; radian 
  x = #halfpi-x   
  ;x=Mod(x, #twopi);  
  v.f=x/#twopi 
  x = ((( v-(Int(v)) )*#twopi)) 
  If(x<0):x=-x:EndIf  
  quad=Int(x * #two_over_pi)    
  If quad=0        
    x=(#c1 + x * x * #c2 ) 
  EndIf 
  If quad=1 
    x=#PI-x 
    x=-(#c1 + x * x * #c2 ) 
  EndIf 
  If quad=2 
    x=x-#PI 
    x=-(#c1 + x * x * #c2 ) 
  EndIf 
  If quad=3 
    x=#twopi-x 
    x=(#c1 + x * x * #c2 ) 
  EndIf  
  ProcedureReturn x 
EndProcedure 
;------------------------------------------------------------ 
Procedure update_fx1() 
  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=0 To ht-1  
    For fx=0 To lg-1 
      dx=fx/lg 
      dy=(fy/lg - 0.3) * amp 
      rx=1-Abs(dy - fSin((dx - time)*freq)) 
      gx=1-Abs(dy - fSin((dx + time)*freq)) 
      bx=1-Abs(dy - fSin((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() 
  z1.f=z1+0.4 
  z2.f=z2+0.8 
  z3.f=z3+0.6 
  For y=0 To ht-1  
    For x=0 To lg-1 
      f1=120-Abs(rfSin(x+z1+rfSin(y*4+z1)*120)*120) 
      f2=120-Abs(rfCos(y-z2+rfSin(x*4-z1)*120)*120) 
      f3=Int(120-Abs(rfSin(x*4+z2+rfSin(x+y+z3)*40)*120))*256 
      f4=Int(120-Abs(rfCos(y*4-z2+rfSin(x-y-z1)*40)*120))*256 
      f5=Int(120-Abs(rfSin(y*4+z1+rfSin(x-y+z2)*40)*120))*65536 
      f6=Int(120-Abs(rfCos(x*4-z1+rfSin(x+y-z2)*40)*120))*65536 
      screen(x,y)=f1+f2+f3+f4+f5+f6 
    Next 
  Next 
EndProcedure 
;------------------------------------------------------------ 
Procedure update_fx3() 
  freq.f=4.0 
  time = time + 0.02 
  If t>=314 : t=0 : EndIf      
  For fy=0 To ht-1   
    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() 
  z1=z1+0.01 
  z2=z2+0.03 
  z3=z3+0.02 
  For y=0 To ht-1 
    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 
  
  Repeat 
    
    Repeat
      ;Gestion des évènements de la fenêtre
      ;====================================
      
      Evenement = WindowEvent()    ; Animation
      
      Select Evenement   
        Case #PB_Event_CloseWindow
          End
          
        Case #PB_Event_Gadget
          Select EventGadget()
            Case 2 
              Select EventType() 
                Case #PB_EventType_Change
                  var=GetGadgetState(2)
                  Select var 
                    Case 0 
                      update_fx1() 
                    Case 1 
                      update_fx2() 
                    Case 2 
                      update_fx3() 
                    Case 3 
                      update_fx4() 
                  EndSelect 
              EndSelect
          EndSelect 
      EndSelect 
    Until Evenement=0
    
    copy() 
    StartDrawing(WindowOutput(0)) 
    DrawImage(img,10,30) 
    StopDrawing()    
    Delay(1)
  ForEver
EndIf 
M.
manababel
Messages : 136
Inscription : jeu. 14/mai/2020 7:40

Re: demo old school 2d

Message par manababel »

Mesa, votre programme modifié ne fonctionne pas, l'image reste fixe.

le goulot d'étranglement ces : les fonctions "cos" sont "sin" qui utilisent soit une division soit un modulo.

L'accélération matérielle de la carte graphique est vraiment plus performante, mais je n'ai pas encore reussi à faire marcher les "pixels shader " en pure basic.
Toutes les sources trouvées ne fonctionnent pas.
Par contre , quand la source est fournie avec l'exécutable, celui-ci fonctionne.

l'exemple fx3 est une traduction d'un programme sur le site
http://glslsandbox.com/
Avatar de l’utilisateur
Ar-S
Messages : 9477
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: demo old school 2d

Message par Ar-S »

Merci pour ces exemples, je trouve l'FX3 vraiment chouette
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Guillot
Messages : 529
Inscription : jeu. 25/juin/2015 16:18

Re: demo old school 2d

Message par Guillot »

à Manabel:
etonnant pour le modulo, ça voudrait dire que la fonction PB est pas optimisée
toi qui maitrise l'ASM tu pourrais pas nous pondre une fonction Int et Mod "mathématique" (cf wikipedia) ?
la difference de couleur provient de la fonction RGB que je pense plus rapide que r<<16 + g<<8 + b. mais j'ai oublié d'inverser R et B
quand à tes fonctions fsin et fcos, ce sont des aproximations des fcts sin et cos, j'ai donc virée les "f", mais pas vu de différences...étonnant, il me semble qu'elles sont maintenant calculées en 1 cycle
Mesa
Messages : 1097
Inscription : mer. 14/sept./2011 16:59

Re: demo old school 2d

Message par Mesa »

oui, maintenant, ça devrait s'animer:

Code : Tout sélectionner

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  


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

#c1=0.99940307  
#c2=-0.49558072 + 0.09079168  
#twopi=2.0*#PI  
#two_over_pi= 2.0/#PI  
#halfpi=#PI/2.0  

Procedure.f fcos(x.f)   
  ;x=Mod(x, #twopi);  
  v.f=x/#twopi  
  x = ((( v-(Int(v)) )*#twopi))  
  If(x<0):x=-x:EndIf   
  quad=Int(x * #two_over_pi)     
  If quad=0         
    x=(#c1 + x * x * #c2 )  
  EndIf  
  If quad=1  
    x=#PI-x  
    x=-(#c1 + x * x * #c2 )  
  EndIf  
  If quad=2  
    x=x-#PI  
    x=-(#c1 + x * x * #c2 )  
  EndIf  
  If quad=3  
    x=#twopi-x  
    x=(#c1 + x * x * #c2 )  
  EndIf   
  ProcedureReturn x  
EndProcedure  

Procedure.f fsin(x.f)   
  x = #halfpi-x    
  ;x=Mod(x, #twopi);  
  v.f=x/#twopi  
  x = ((( v-(Int(v)) )*#twopi))  
  If(x<0):x=-x:EndIf   
  quad=Int(x * #two_over_pi)     
  If quad=0         
    x=(#c1 + x * x * #c2 )  
  EndIf  
  If quad=1  
    x=#PI-x  
    x=-(#c1 + x * x * #c2 )  
  EndIf  
  If quad=2  
    x=x-#PI  
    x=-(#c1 + x * x * #c2 )  
  EndIf  
  If quad=3  
    x=#twopi-x  
    x=(#c1 + x * x * #c2 )  
  EndIf   
  ProcedureReturn x  
EndProcedure  

Procedure.f rfcos(x.f)   
  x = x / 180 * #PI ; radian  
                    ;x=Mod(x, #twopi);  
  v.f=x/#twopi  
  x = ((( v-(Int(v)) )*#twopi))  
  If(x<0):x=-x:EndIf   
  quad=Int(x * #two_over_pi)     
  If quad=0         
    x=(#c1 + x * x * #c2 )  
  EndIf  
  If quad=1  
    x=#PI-x  
    x=-(#c1 + x * x * #c2 )  
  EndIf  
  If quad=2  
    x=x-#PI  
    x=-(#c1 + x * x * #c2 )  
  EndIf  
  If quad=3  
    x=#twopi-x  
    x=(#c1 + x * x * #c2 )  
  EndIf   
  ProcedureReturn x  
EndProcedure  

Procedure.f rfsin(x.f)   
  x = x / 180 * #PI ; radian  
  x = #halfpi-x    
  ;x=Mod(x, #twopi);  
  v.f=x/#twopi  
  x = ((( v-(Int(v)) )*#twopi))  
  If(x<0):x=-x:EndIf   
  quad=Int(x * #two_over_pi)     
  If quad=0         
    x=(#c1 + x * x * #c2 )  
  EndIf  
  If quad=1  
    x=#PI-x  
    x=-(#c1 + x * x * #c2 )  
  EndIf  
  If quad=2  
    x=x-#PI  
    x=-(#c1 + x * x * #c2 )  
  EndIf  
  If quad=3  
    x=#twopi-x  
    x=(#c1 + x * x * #c2 )  
  EndIf   
  ProcedureReturn x  
EndProcedure  
;------------------------------------------------------------  
Procedure update_fx1() 
  
;   tps.q=ElapsedMilliseconds()
  
  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=0 To ht-1   
    For fx=0 To lg-1  
      dx=fx/lg  
      dy=(fy/lg - 0.3) * amp  
      rx=1-Abs(dy - fSin((dx - time)*freq))  
      gx=1-Abs(dy - fSin((dx + time)*freq))  
      bx=1-Abs(dy - fSin((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  
;   Debug ElapsedMilliseconds()-tps
  
EndProcedure  
;------------------------------------------------------------  
Procedure update_fx2()  
  z1.f=z1+0.4  
  z2.f=z2+0.8  
  z3.f=z3+0.6  
  For y=0 To ht-1   
    For x=0 To lg-1  
      f1=120-Abs(rfSin(x+z1+rfSin(y*4+z1)*120)*120)  
      f2=120-Abs(rfCos(y-z2+rfSin(x*4-z1)*120)*120)  
      f3=Int(120-Abs(rfSin(x*4+z2+rfSin(x+y+z3)*40)*120))*256  
      f4=Int(120-Abs(rfCos(y*4-z2+rfSin(x-y-z1)*40)*120))*256  
      f5=Int(120-Abs(rfSin(y*4+z1+rfSin(x-y+z2)*40)*120))*65536  
      f6=Int(120-Abs(rfCos(x*4-z1+rfSin(x+y-z2)*40)*120))*65536  
      screen(x,y)=f1+f2+f3+f4+f5+f6  
    Next  
  Next  
EndProcedure  
;------------------------------------------------------------  
Procedure update_fx3()  
  freq.f=4.0  
  time = time + 0.02  
  If t>=314 : t=0 : EndIf       
  For fy=0 To ht-1    
    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()  
  z1=z1+0.01  
  z2=z2+0.03  
  z3=z3+0.02  
  For y=0 To ht-1  
    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  
  
  Repeat  
    
    Repeat 
      ;Gestion des évènements de la fenêtre 
      ;==================================== 
      
      Evenement = WindowEvent()    ; Animation 
      
      Select Evenement    
        Case #PB_Event_CloseWindow 
          End 
          
        Case #PB_Event_Gadget 
          Select EventGadget() 
            Case 2  
              Select EventType()  
                Case #PB_EventType_Change 
                  var=GetGadgetState(2) 
                  Select var 
                    Case 0 
                      update_fx1() 
                      cas=0
                    Case 1 
                      update_fx2()
                      cas=1
                    Case 2 
                      update_fx3() 
                      cas=2
                    Case 3 
                      update_fx4() 
                      cas=3
                  EndSelect 
              EndSelect 
          EndSelect  
      EndSelect  
    Until Evenement=0 
    
    Select cas
      Case 0
        update_fx1()
      Case 1
        update_fx2()
      Case 2
        update_fx3()
      Case 3
        update_fx4()
    EndSelect
    
;     tps2.q=ElapsedMilliseconds()
    
    copy()  
    StartDrawing(WindowOutput(0))  
    DrawImage(img,10,30)  
    StopDrawing()  
;     Debug ElapsedMilliseconds()-tps2
;     Debug"----"
    Delay(1) 
  ForEver 
EndIf
Oui, je pense aussi que l'optimisation max se ferait avec des calculs en assembleur dans un thread et l'utilsation d'openwindowscreen (pas besoin de sprite).

M.
manababel
Messages : 136
Inscription : jeu. 14/mai/2020 7:40

Re: demo old school 2d

Message par manababel »

J'ai amélioré très sensiblement les fonctions 'cos' et 'sin'.
Il n'y a plus qu'une seule commande 'cos' et 'sin'.
par contre , il y a un bug avec les valeurs negafives.

j'ai déposé ses programmes en purebasic pour que tous ceux qui le veulent, puissent les modifier

voici les temps que j'obtiens
.............cos/sin(pb)............fcos/fsin(old)..........fcos/fsin(new)
fx1..............28........................19........................18
fx2..............107......................94.........................73
fx3..............39........................25.........................25
fx4..............97........................73.........................62

Code : Tout sélectionner

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


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

#c1=1.27323954 
#c2=0.405284735
#twopi=2.0*#PI
#halfpi=#PI/2.0


Procedure.f fcos(i.f)
  If i<0
    i=Abs(i)+#PI
  EndIf
  
  i=i+#halfpi
  a.f=i/#twopi ; i.f=fMod(i,#twopi)
  b.l=Int(a)
  i=(a-b)*#twopi
  i=i-#PI
  
  If i>0 
    a=-1
  Else
    a=1
  EndIf

   i=i* (#c1  +  #c2  * i * a )

  ProcedureReturn -i
EndProcedure

Procedure.f fsin(i.f)
  If i<0
    i=Abs(i)+#PI
  EndIf
  
  a.f=i/#twopi ; i.f=fMod(i,#twopi)
  b.l=Int(a)
  i=(a-b)*#twopi
  i=i-#PI
  
  If i>0 
    a=-1
  Else
    a=1
  EndIf
  
  i=i* (#c1  +  #c2  * i * a )

  ProcedureReturn -i
EndProcedure

;------------------------------------------------------------
Procedure update_fx1()
  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=0 To ht-1
    For fx=0 To lg-1
      dx=fx/lg
      dy=(fy/lg - 0.3) * amp
      rx=1-Abs(dy - fSin((dx - time)*freq))
      gx=1-Abs(dy - fSin((dx + time)*freq))
      bx=1-Abs(dy - fSin((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()
z1.f=z1+0.4
z2.f=z2+0.8
z3.f=z3+0.6
  For y=0 To ht-1
    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()
  freq.f=4.0
  time = time + 0.02
  If t>=314 : t=0 : EndIf     
  For fy=0 To ht-1 
    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()
z1=z1+0.01
z2=z2+0.03
z3=z3+0.02
For y=0 To ht-1
   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
 
  Repeat
    var=GetGadgetState(2)
    Event = WindowEvent()
    t=ElapsedMilliseconds()
    Select var
      Case 0
        update_fx1()
      Case 1
        update_fx2()
      Case 2
        update_fx3()
      Case 3
        update_fx4()
    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
SPH
Messages : 4726
Inscription : mer. 09/nov./2005 9:53

Re: demo old school 2d

Message par SPH »

Bravo :P

Une fois compilé, c'est fluide :idea:
http://HexaScrabble.com/
!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.00 - 64 bits
manababel
Messages : 136
Inscription : jeu. 14/mai/2020 7:40

Re: demo old school 2d

Message par manababel »

les fonctions 'fcos' et 'fsin' en version Asm avec correction des erreurs

Code : Tout sélectionner

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


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

Global Dim var.f(7)
var(0)=1.27323954 ; c1
var(1)=0.405284735; c2
var(2)=#PI/2.0
var(3)=#PI*2
var(4)=#PI
var(5)=1
var(6)=-1

Procedure.f fcos(i.f)
  t=@var()
  If i<0:i=Abs(i):EndIf
  !mov rdx,[p.v_t]
  !movss xmm0,[p.v_i]
  !addss xmm0,[rdx+8];[p.v_halfpi] ; i=i+#halfpi
  !divss xmm0,[rdx+12];[p.v_twopi] ; i.f=i/#twopi 
  !CVtTPS2DQ xmm1,xmm0 ; b=Int(i)
  !CVTDQ2PS xmm1,xmm1 ; b=float(b)
  !subss xmm0,xmm1 ; i=(i-b)
  !mulss xmm0,[rdx+12];[p.v_twopi] ; i=i*#twopi
  !subss xmm0,[rdx+16];[p.v_pi] ; i=i-#PI
  !movss [p.v_i],xmm0 
  If i>0
    !movss xmm1,[rdx+24]
  Else
    !movss xmm1,[rdx+20]
  EndIf
  !movss xmm2,[rdx+04];[p.v_c2]
  !mulss xmm2,xmm0 ; #c2 * i
  !mulss xmm2,xmm1 ; * a
  !addss xmm2,[rdx+00];[p.v_c1] ; *c1
  !mulss xmm2,xmm0 ; * i
  !movss [p.v_i],xmm2
  ProcedureReturn -i
EndProcedure

Procedure.f fsin(i.f)
  t=@var()
  If i<0:i=Abs(i)+#PI:EndIf  
  t=@var()
  !mov rdx,[p.v_t]
  !movss xmm0,[p.v_i]
  !divss xmm0,[rdx+12];[p.v_twopi] ; i.f=i/#twopi 
  !CVtTPS2DQ xmm1,xmm0 ; b=Int(i)
  !CVTDQ2PS xmm1,xmm1 ; b=float(b)
  !subss xmm0,xmm1 ; i=(i-b)
  !mulss xmm0,[rdx+12];[p.v_twopi] ; i=i*#twopi
  !subss xmm0,[rdx+16];[p.v_pi] ; i=i-#PI
  !movss [p.v_i],xmm0
  If i>0
    !movss xmm1,[rdx+24]
  Else
    !movss xmm1,[rdx+20]
  EndIf
  !movss xmm2,[rdx+04];[p.v_c2]
  !mulss xmm2,xmm0 ; #c2 * i
  !mulss xmm2,xmm1 ; * a
  !addss xmm2,[rdx+00];[p.v_c1] ; *c1
  !mulss xmm2,xmm0 ; * i
  !movss [p.v_i],xmm2
  ProcedureReturn -i
EndProcedure

;------------------------------------------------------------
Procedure update_fx1()
  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=0 To ht-1
    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()
z1.f=z1+0.4
z2.f=z2+0.8
z3.f=z3+0.6
  For y=0 To ht-1
    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()
  freq.f=4.0
  time = time + 0.02
  If t>=314 : t=0 : EndIf     
  For fy=0 To ht-1 
    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()
z1=z1+0.01
z2=z2+0.03
z3=z3+0.02
For y=0 To ht-1
   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
 
  Repeat
    var=GetGadgetState(2)
    Event = WindowEvent()
    t=ElapsedMilliseconds()
    Select var
      Case 0
        update_fx1()
      Case 1
        update_fx2()
      Case 2
        update_fx3()
      Case 3
        update_fx4()
    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 : 529
Inscription : jeu. 25/juin/2015 16:18

Re: demo old school 2d

Message par Guillot »

ouai là, on voit la difference
environ 2x plus fluide
moi qui pensait que les fcts sin et cos était executées en 1 cycle...

en passant par des tableaux c'est encore plus rapide (surtout FX4)

Code : Tout sélectionner

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


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

#c1=0.99940307
#c2=-0.49558072 + 0.09079168
#twopi=2.0*#PI
#two_over_pi= 2.0/#PI
#halfpi=#PI/2.0

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()
  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=0 To ht-1
    For fx=0 To lg-1
      dx=fx/lg
      dy=(fy/lg - 0.3) * amp
      rx=1-Abs(dy - fSin((dx - time)*freq))
      gx=1-Abs(dy - fSin((dx + time)*freq))
      bx=1-Abs(dy - fSin((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)
      screen(fy,fx)=RGB(b,g,r);   <===============
    Next
  Next
EndProcedure
;------------------------------------------------------------
Procedure update_fx2()
z1.f=z1+0.4
z2.f=z2+0.8
z3.f=z3+0.6
  For y=0 To ht-1
    For x=0 To lg-1
      f1=120-Abs(rfSin(x+z1+RfSin(y*4+z1)*120)*120)
      f2=120-Abs(rfCos(y-z2+rfSin(x*4-z1)*120)*120)
      f3=Int(120-Abs(rfSin(x*4+z2+rfSin(x+y+z3)*40)*120))*256
      f4=Int(120-Abs(rfCos(y*4-z2+rfSin(x-y-z1)*40)*120))*256
      f5=Int(120-Abs(rfSin(y*4+z1+rfSin(x-y+z2)*40)*120))*65536
      f6=Int(120-Abs(rfCos(x*4-z1+rfSin(x+y-z2)*40)*120))*65536
      screen(y,x)=f1+f2+f3+f4+f5+f6;   <===============
    Next
  Next
EndProcedure
;------------------------------------------------------------
Procedure update_fx3()
  freq.f=4.0
  time = time + 0.02
  If t>=314 : t=0 : EndIf     
  For fy=0 To ht-1
    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)
      screen(fy,fx)=RGB(b,g,r);   <===============
    Next
  Next
EndProcedure
;------------------------------------------------------------
Procedure update_fx4()
z1=z1+0.01
z2=z2+0.03
z3=z3+0.02
For y=0 To ht-1
   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(y,x)=var;   <===============
   Next
Next
EndProcedure
;------------------------------------------------------------

Procedure copy();   <===============
    StartDrawing(ImageOutput(1))
    CopyMemory(@screen(0,0),DrawingBuffer(),ht*lg*4)
    StopDrawing()
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
SetGadgetState(2,0)
  Repeat
    var=GetGadgetState(2)
    Event = WindowEvent()
    Select var
      Case 0
        update_fx1()
      Case 1
        update_fx2()
      Case 2
        update_fx3()
      Case 3
        update_fx4()
    EndSelect
   
    copy()
    StartDrawing(WindowOutput(0))
    DrawImage(img,10,30)
    StopDrawing()   
    Select Event
      Case #PB_Event_Gadget
        Select EventGadget()     
          Case 1
            CloseWindow(0)
            End     
        EndSelect   
    EndSelect
  Until Event = #PB_Event_CloseWindow
EndIf
Répondre