Page 1 sur 1

Image, drawing et optimisation

Publié : sam. 12/oct./2013 13:39
par blendman
Salut

J'aimerais optimiser ce code, afin que ça rame moins.
Si vous avez des idées d'optimisations possible, ça m'intéresse :)

Code : Tout sélectionner

;{ Enumeration

#PanelToolW = 105

Enumeration ; images
  
  #ImageFond
  #Calque1
  #Calque2
  #Calque3 
  #ImageAffichage
  
EndEnumeration


Enumeration ;Gadgets
  
  #Canvas
  #G_BrushSize
  #G_BrushScatter
  #G_BrushColor
  #G_BrushAlpha
  
EndEnumeration


;}

;{ Structures
Structure St_Brush
  Scatter.w
  Size.w
  Color.i
  Alpha.i
EndStructure
Global Brush.St_Brush

Brush\Scatter = 2
Brush\Color   = RGBA(0,0,0,255)
Brush\Size    = 5
Brush\Alpha   = 255
;}

;{ procedures

Procedure ThickLine(x1, y1, x2, y2, size, color=0)
  ; BY BP - forum english
  
  Protected dx, dy, e2.f, err, s_x, s_y, a_err
  
  If size < 1 : size = 1 : EndIf
  
  size - 1
  dx = Abs(x2 - x1) : dy = Abs(y2 - y1) : err = dx - dy 
  
  If x1 < x2 : s_x = 1 : Else : s_x = -1 : EndIf
  If y1 < y2 : s_y = 1 : Else : s_y = -1 : EndIf
  
  Repeat
    
    ; add scatter 
    rndY = Random(Brush\Scatter) - Random(Brush\Scatter)
    rndX = Random(Brush\Scatter) - Random(Brush\Scatter)
    
    ; drawing
    Circle(x1 + rndX, y1 + rndY, size, color)
    
    If x1 = x2 And y1 = y2 : Break : EndIf
    e2 = err + err ;* Brush\Size * Brush\Pass/100 
    
    If e2 > -dy
      err - dy
      x1 + s_x      
    EndIf
    
    If e2 < dx 
      err + dx 
      y1 + s_y      
    EndIf
    
  ForEver
EndProcedure

Macro UpdateDrawing()
  
  If StartDrawing(CanvasOutput(#Canvas))
    ; draw background
    DrawImage(ImageID(#ImageFond), 0, 0)
    
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawAlphaImage(ImageID(#calque1), 0, 0)
    StopDrawing()
  EndIf
  
EndMacro

;}


;{ openwindow

If OpenWindow(0, 0, 0, 1000, 600, "Drawing Optimisation", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  
  If ContainerGadget(#PB_Any, 0, 0, #PanelToolW-5, 600, #PB_Container_Single)
    
    TrackBarGadget(#G_BrushSize,    2, 50, #PanelToolW-10, 20, 1, 50)
    TrackBarGadget(#G_BrushScatter, 2, 80, #PanelToolW-10, 20, 0, 50)
    TrackBarGadget(#G_BrushAlpha, 2, 110, #PanelToolW-10, 20, 0, 255)
    ButtonGadget(#G_BrushColor,     1, 140,#PanelToolW-10, 20, "Color")
    
    CloseGadgetList()
  EndIf
  
  
  ; If ScrollAreaGadget(#PB_Any, #PanelToolW , 0, WindowWidth(0) - #PanelToolW - 5,  WindowHeight(0), 1000, 1000) 
  If CanvasGadget(#Canvas, #PanelToolW, 0, 800, 600) :   EndIf
  
  ; CloseGadgetList()
  ; EndIf
  
  
  ;{ the layers, images...
  If CreateImage(#calque1, 800, 600, 32, #PB_Image_Transparent)  :  EndIf
  
  
  ; background layer
  If CreateImage(#ImageFond, 800, 600, 32) And StartDrawing(ImageOutput(#ImageFond))
    #box_size=7
    Box(0, 0, 800, 600, $FFFFFF)
    For y=0 To 600 Step #box_size * 2
      For x=0 To 800 Step #box_size * 2
        Box(x, y, #box_size, #box_size, $C0C0C0)
        Box(x+#box_size, y+#box_size, #box_size, #box_size, $C0C0C0)
      Next
    Next
    StopDrawing()
  EndIf
  
  
  
  ; drawing layer
  If CreateImage(#ImageAffichage, 800, 600, 32) And StartDrawing(ImageOutput(#ImageFond))
    DrawImage(ImageID(#ImageFond), 0, 0)
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawAlphaImage(ImageID(#calque1), 0, 0)
    StopDrawing()
  EndIf
  
  SmartWindowRefresh(0, 1)

  ;}
  
  UpdateDrawing()
  ;}
  
  Repeat
    
    Event       = WaitWindowEvent()
    EventGadget = EventGadget()
    EventType   = EventType()
    
    Select event
        
      Case #PB_Event_Gadget
        
        Select EventGadget
            
          Case #G_BrushSize
            brush\Size = GetGadgetState(#G_BrushSize)
            
          Case #G_BrushScatter
            brush\Scatter = GetGadgetState(#G_BrushScatter)
            
          Case #G_BrushColor
            color = ColorRequester(brush\color)
            Brush\Color = RGBA(Red(color), Green(color), Blue(color), brush\alpha)
            
          Case #G_BrushAlpha
            brush\Alpha = GetGadgetState(#G_BrushAlpha)
            Brush\Color = RGBA(Red(Brush\Color), Green(Brush\Color), Blue(Brush\Color), brush\alpha)
            
            
          Case #canvas
            
            Select eventType
                
              Case #PB_EventType_LeftButtonDown
                
                X = WindowMouseX(0) - #PanelToolW
                Y = WindowMouseY(0) 
                
                StartX = WindowMouseX(0) - #PanelToolW
                StartY = WindowMouseY(0) 
                paint = 1
                
                
              Case #PB_EventType_LeftButtonUp 
                paint = 0
                
                
              Case #PB_EventType_MouseMove 
                
                If paint
                  
                  StartX = WindowMouseX(0) - #PanelToolW
                  StartY = WindowMouseY(0)
                  
                  
                  If StartDrawing(ImageOutput(#calque1))
                    
                    DrawingMode(#PB_2DDrawing_AlphaBlend)                                    
                    ThickLine(StartX, StartY, X, Y, Brush\Size, Brush\color)
                    
                    StopDrawing()
                  EndIf
                  
                  X = WindowMouseX(0) - #PanelToolW
                  Y = WindowMouseY(0)
                  
                  UpdateDrawing()
                  
                EndIf                  
                
            EndSelect      
            
        EndSelect
                   
    EndSelect
        
    
  Until event =#PB_Event_CloseWindow
  
EndIf

Re: Image, drawing et optimisation

Publié : sam. 12/oct./2013 14:46
par G-Rom
sous kde , a peine 5% d'utilisation processeur lors du dessin.
0% quand on ne fait rien. Pour optimiser encore plus ton application, il faudra passé par le GPU pour les opérations de dessins.

Re: Image, drawing et optimisation

Publié : sam. 12/oct./2013 17:21
par blendman
G-Rom a écrit :sous kde , a peine 5% d'utilisation processeur lors du dessin.
0% quand on ne fait rien. Pour optimiser encore plus ton application, il faudra passé par le GPU pour les opérations de dessins.
sous win8, moi, j'ai 50% d'utilisation lorsque je dessine :cry: .

Niveau optimisation, je pense qu'il faut un système de Tile, et je ne dessine que sur celle où la souris se trouve + celles aux alentours, comme ce que j'avais testé ici :
http://www.purebasic.fr/french/viewtopi ... =6&t=13903

Re: Image, drawing et optimisation

Publié : sam. 12/oct./2013 17:42
par Backup
blendman a écrit :sous win8, moi, j'ai 50% d'utilisation lorsque je dessine :cry: .
t'a un pc en carton ?
chez moi sur mon portable c'est maxi 12 ...

essaye deja de mettre

Code : Tout sélectionner

Event       = WaitWindowEvent(20)
au lieu de

Code : Tout sélectionner

Event       = WaitWindowEvent()
ça peut aider a faire tomber l'occupation processeur

Re: Image, drawing et optimisation

Publié : sam. 12/oct./2013 17:52
par blendman
Dobro a écrit :t'a un pc en carton ?
oui, c'est un packard bell :mrgreen:
Il est silencieux, mais niveau perf, ça rame vite..
essaye deja de mettre

Code : Tout sélectionner

Event       = WaitWindowEvent(20)
au lieu de

Code : Tout sélectionner

Event       = WaitWindowEvent()
ça ne change rien quand je dessine, je reste à 50%.
Packard bell pourri je te dis ^^

Re: Image, drawing et optimisation

Publié : sam. 12/oct./2013 18:17
par Ar-S
Je monte à + de 40 petit à petit lorsque le bouton de la souris est pressé.
C'est vrai que c'est dur lourd.
Tu as essayé de mettre ton UpdateDrawing() dans un thread ?

Re: Image, drawing et optimisation

Publié : sam. 12/oct./2013 18:19
par Backup
et avec les Thread ?

met toi en Threadsafe ;)

Code : Tout sélectionner

;{ Enumeration

#PanelToolW = 105

Enumeration ; images
	
	#ImageFond
	#Calque1
	#Calque2
	#Calque3
	#ImageAffichage
	
EndEnumeration


Enumeration ;Gadgets
	
	#Canvas
	#G_BrushSize
	#G_BrushScatter
	#G_BrushColor
	#G_BrushAlpha
	
EndEnumeration
Structure Thick
	x1.i
	y1.i
	x2.i
	y2.i
	size.i
	color.i
EndStructure
global Thick.Thick

;}

;{ Structures
Structure St_Brush
	Scatter.w
	Size.w
	Color.i
	Alpha.i
EndStructure
Global Brush.St_Brush

Brush\Scatter = 2
Brush\Color   = RGBA(0,0,0,255)
Brush\Size    = 5
Brush\Alpha   = 255
;}

;{ procedures

Procedure ThickLine(*bidon)
	StartDrawing(ImageOutput(#calque1))                   
		DrawingMode(#PB_2DDrawing_AlphaBlend) 
		x1.i=Thick\x1.i
		y1.i=Thick\y1.i
		x2.i=Thick\x2.i
		y2.i=Thick\y2.i
		size=Thick\size.i
		color=Thick\color.i
		; BY BP - forum english
		Protected dx, dy, e2.f, err, s_x, s_y, a_err
		If size < 1 : size = 1 : EndIf
		size - 1
		dx = Abs(x2 - x1) : dy = Abs(y2 - y1) : err = dx - dy
		If x1 < x2 : s_x = 1 : Else : s_x = -1 : EndIf
		If y1 < y2 : s_y = 1 : Else : s_y = -1 : EndIf
		Repeat
			; add scatter
			rndY = Random(Brush\Scatter) - Random(Brush\Scatter)
			rndX = Random(Brush\Scatter) - Random(Brush\Scatter)
			; drawing
			Circle(x1 + rndX, y1 + rndY, size, color)
			If x1 = x2 And y1 = y2 : Break : EndIf
			e2 = err + err ;* Brush\Size * Brush\Pass/100
			If e2 > -dy
				err - dy
				x1 + s_x     
			EndIf
			
			If e2 < dx
				err + dx
				y1 + s_y     
			EndIf
		ForEver
	StopDrawing()
EndProcedure

Macro UpdateDrawing()
	If StartDrawing(CanvasOutput(#Canvas))
		; draw background
		DrawImage(ImageID(#ImageFond), 0, 0)
		DrawingMode(#PB_2DDrawing_AlphaBlend)
		DrawAlphaImage(ImageID(#calque1), 0, 0)
		StopDrawing()
	EndIf
EndMacro

;}


;{ openwindow

If OpenWindow(0, 0, 0, 1000, 600, "Drawing Optimisation", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) 
	If ContainerGadget(#PB_Any, 0, 0, #PanelToolW-5, 600, #PB_Container_Single)   
		TrackBarGadget(#G_BrushSize,    2, 50, #PanelToolW-10, 20, 1, 50)
		TrackBarGadget(#G_BrushScatter, 2, 80, #PanelToolW-10, 20, 0, 50)
		TrackBarGadget(#G_BrushAlpha, 2, 110, #PanelToolW-10, 20, 0, 255)
		ButtonGadget(#G_BrushColor,     1, 140,#PanelToolW-10, 20, "Color")   
		CloseGadgetList()
	EndIf
	
	
	; If ScrollAreaGadget(#PB_Any, #PanelToolW , 0, WindowWidth(0) - #PanelToolW - 5,  WindowHeight(0), 1000, 1000)
	If CanvasGadget(#Canvas, #PanelToolW, 0, 800, 600) :   EndIf 
	; CloseGadgetList()
	; EndIf 
	;{ the layers, images...
	If CreateImage(#calque1, 800, 600, 32, #PB_Image_Transparent)  :  EndIf 
	; background layer
	If CreateImage(#ImageFond, 800, 600, 32) And StartDrawing(ImageOutput(#ImageFond))
		#box_size=7
		Box(0, 0, 800, 600, $FFFFFF)
		For y=0 To 600 Step #box_size * 2
			For x=0 To 800 Step #box_size * 2
				Box(x, y, #box_size, #box_size, $C0C0C0)
				Box(x+#box_size, y+#box_size, #box_size, #box_size, $C0C0C0)
			Next
		Next
	StopDrawing()
EndIf



; drawing layer
If CreateImage(#ImageAffichage, 800, 600, 32) And StartDrawing(ImageOutput(#ImageFond))
	DrawImage(ImageID(#ImageFond), 0, 0)
	DrawingMode(#PB_2DDrawing_AlphaBlend)
	DrawAlphaImage(ImageID(#calque1), 0, 0)
StopDrawing()
EndIf

SmartWindowRefresh(0, 1)


;}

UpdateDrawing()
;}


Repeat

Event       = WaitWindowEvent()
EventGadget = EventGadget()
EventType   = EventType()

Select event       
	Case #PB_Event_Gadget       
	Select EventGadget           
		Case #G_BrushSize
		brush\Size = GetGadgetState(#G_BrushSize)           
		Case #G_BrushScatter
		brush\Scatter = GetGadgetState(#G_BrushScatter)           
		Case #G_BrushColor
		color = ColorRequester(brush\color)
		Brush\Color = RGBA(Red(color), Green(color), Blue(color), brush\alpha)           
		Case #G_BrushAlpha
		brush\Alpha = GetGadgetState(#G_BrushAlpha)
		Brush\Color = RGBA(Red(Brush\Color), Green(Brush\Color), Blue(Brush\Color), brush\alpha)          
		Case #canvas           
		Select eventType               
			Case #PB_EventType_LeftButtonDown               
			X = WindowMouseX(0) - #PanelToolW
			Y = WindowMouseY(0)               
			StartX = WindowMouseX(0) - #PanelToolW
			StartY = WindowMouseY(0)
			paint = 1
			Case #PB_EventType_LeftButtonUp
			paint = 0
			Case #PB_EventType_MouseMove
			If paint                 
				StartX = WindowMouseX(0) - #PanelToolW
				StartY = WindowMouseY(0)               
				
				Thick\x1.i=startx
				Thick\y1.i=StartY
				Thick\x2.i=x
				Thick\y2.i=y
				Thick\size.i=Brush\Size
				Thick\color.i=Brush\color
				Mutex = CreateMutex()
				LockMutex(Mutex)
				thread1=CreateThread(@ThickLine() , *bidon)
				WaitThread(thread1)
				UnlockMutex(Mutex)
				
				
			EndIf                 
			X = WindowMouseX(0) - #PanelToolW
			Y = WindowMouseY(0)                 
			UpdateDrawing()                 
			
		EndSelect    
	EndSelect                   
EndSelect


Until event =#PB_Event_CloseWindow

EndIf

; 

; EPB

Re: Image, drawing et optimisation

Publié : sam. 12/oct./2013 18:29
par blendman
sur mon PC en carton, avec le thread, je suis toujours à 50% et ça ramouille toujours autant ^^.

Re: Image, drawing et optimisation

Publié : sam. 12/oct./2013 18:37
par Backup
pardon , j'ai corrigé le code ..

retest (Threadsafe on )

pour info , chez moi ça depasse pas 5.... !
(meme pas en mode jeux :lol: ) .. en mode de base bureautique

Re: Image, drawing et optimisation

Publié : sam. 12/oct./2013 19:02
par blendman
Dobro a écrit :pardon , j'ai corrigé le code ..

retest (Threadsafe on )
yep, j'avais déjà corrigé ^^

pour info , chez moi ça depasse pas 5 !
j'ai un pc en carton, je te dis :D
Cela dit, c'est très bien pour tester des softs, et ce n'est pas tellement le problème du cpu qui me gène uniquement, c'est plus le fait que ça rame (c'est sans doute lié oui ^^)

Re: Image, drawing et optimisation

Publié : sam. 12/oct./2013 19:16
par G-Rom
Thread ou pas thread, cela ne changera pas grand chose, parallélisé se genre d'application ne sert à rien dans ce cas.
Ce qu'il te faut, c'est un accès plus bas niveau, du genre directx ou opengl ( je te conseil le second ) & d'utilisé les ressource GPU par le biais des unité de texture & les opération par le biais de shader, mais si tu as un pc en carton sans GPU, tu n'aura aucun résultat significatif.

Re: Image, drawing et optimisation

Publié : sam. 12/oct./2013 19:36
par Backup
il me semble qu'en WindowedScreen on est plus rapide quand meme (prends moins de ressources )
est-ce grace a l'appel Directx implicite ?

Re: Image, drawing et optimisation

Publié : sam. 12/oct./2013 20:36
par G-Rom
plus rapide par rapport à quoi ? le fullScreen ? pas du tout. L'ordonnanceur aura même tendance à privilégié les applications en plein écran.
Dans son code, aucun appel à directx n'est fait de manière implicite, tout est software, a moins que le canvas bénéficie de l'accélération matériel , ce que j'en doute.

Re: Image, drawing et optimisation

Publié : sam. 12/oct./2013 23:26
par Backup
G-Rom a écrit :plus rapide par rapport à quoi ? le fullScreen ? pas du tout. L'ordonnanceur aura même tendance à privilégié les applications en plein écran.
Dans son code, aucun appel à directx n'est fait de manière implicite, tout est software, a moins que le canvas bénéficie de l'accélération matériel , ce que j'en doute.
je recommence :

il me semble qu'en WindowedScreen on est plus rapide quand meme ( au sens ou ça prends moins de ressources )
est-ce grace a l'appel Directx implicite ?
lorsque je parle de windowedscreen , je parle aussi de fullscreen ....

il me semble que ça utilise implicitement le Directx ... me trompais-je ??
je pense que le canvas, reste plus lent de par la gestion des events pour la souris ....

c'est pourquoi je lui conseil d'utiliser le Screen (ou le Windowedscreen())
c'est ce que j'ai toujours fait jusqu'a maintenant pour mes programmes .. ( par exemple , Pure_anaglyphe,Barbouilles,PureGolo ... )
je trouve que ça prends presque pas de temps machine contrairement au Canvas ...

en esperant avoir eté plus clair :)

Re: Image, drawing et optimisation

Publié : sam. 12/oct./2013 23:38
par G-Rom
Autant pour moi , j'ai mal lu ton topic , tu parlais bien de screen en mode fenetré , bien sur que ce sera plus rapide.