2D Drawing: StartDrawing()/StopDrawing() bremsen aus

Für allgemeine Fragen zur Programmierung mit PureBasic.
SBond
Beiträge: 266
Registriert: 22.05.2013 20:35

2D Drawing: StartDrawing()/StopDrawing() bremsen aus

Beitrag von SBond »

Hallo Leute,

ich habe mal eine Frage bezüglich 2D Drawing. Ist es irgendwie möglich auf 2 Grafiken zu zeichnen, ohne dass man jedes mal ein StopDrawing() durchführen muss? ....bzw. sind Threads die einzigen Möglichkeiten?




Folgender Beispiel-Quellcode: Nach jedem Zeichenvorgang, wird StopDrawing()/StartDrawing() ausgeführt
ca. 24000 Werte/Sek. 39 FPS (bei 620 Pixel pro FPS)

Code: Alles auswählen

Declare.i Draw_Graph_1 (iWert.i)
Declare.i Draw_Graph_2 (iWert.i)


Enumeration
	#GUI
	#Image_1
	#Image_2
	#Image_Gadget_1
	#Image_Gadget_2
	#Label
EndEnumeration



OpenWindow(#GUI, 0, 0, 640, 480, "Drawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

TextGadget	(#Label, 10, 10, 600, 18, "")

CreateImage(#Image_1, 620, 200, 24, $FFFFFF)
CreateImage(#Image_2, 620, 200, 24, $FFFFFF)

ImageGadget(#Image_Gadget_1, 10,  60, 620, 200, ImageID(#Image_1))
ImageGadget(#Image_Gadget_2, 10, 270, 620, 200, ImageID(#Image_2))


Global Sin_Counter.d
Global Plottwert.d

Global Status_Graph_1.i
Global Status_Graph_2.i

Global Timer
Global Counter


Repeat
	
	; FPS berechnen und anzeigen
	If ElapsedMilliseconds() - Timer > 1000
		SetGadgetText	(#Label, "[Graph_1]       " + Str(Counter) + " Werte/Sek      " + Str(Counter/620) + " FPS")
		Timer 	= ElapsedMilliseconds()
		Counter = 0
	Else
		Counter + 1
	EndIf
	
	
	; Sinus erzeugen
	Sin_Counter + 0.03035
	Plottwert 	= Sin(Sin_Counter) * 70 + Random(10,0) - Random(10,0) + 100
	
	
	
	; Werte in den ersten Graphen plotten
	StartDrawing(ImageOutput(#Image_1))
	Status_Graph_1 = Draw_Graph_1 (Plottwert)
	StopDrawing()
	
	; Graph 1 in der GUI darstellen, wenn alle Werte gezeichnet wurden
	If Status_Graph_1 = 620
		SetGadgetState(#Image_Gadget_1, ImageID(#Image_1))
	EndIf
	

; 	; Werte in den zweiten Graphen plotten
; 	StartDrawing(ImageOutput(#Image_2))
; 	Status_Graph_2 = Draw_Graph_2 (Plottwert)
; 	StopDrawing()
; 	
; 	; Graph 2 in der GUI darstellen, wenn alle Werte gezeichnet wurden
; 	If Status_Graph_2 = 620
; 		SetGadgetState(#Image_Gadget_2, ImageID(#Image_2))
; 	EndIf
	
	
	; irgendwelche Events
	Select WindowEvent()
		
	Case #PB_Event_CloseWindow
		
		End
		
	EndSelect
	
ForEver

; Beispielgraph 1
Procedure Draw_Graph_1 (iWert.i)
	
	Static 		iX_Position_alt.i
	Static 		iY_Position_alt.i

	If iX_Position_alt > 620
		iX_Position_alt = 0
		Box (0, 0, 620, 200, RGB(255,255,255))
	Else
		LineXY (iX_Position_alt, iY_Position_alt, iX_Position_alt + 1, iWert, RGB(255,0,0))
		iX_Position_alt + 1
		iY_Position_alt = iWert
		ProcedureReturn iX_Position_alt + 1
	EndIf
	
EndProcedure



; Beispielgraph 2
Procedure Draw_Graph_2 (iWert.i)
	
	Static 		iX_Position_alt.i
	Static 		iY_Position_alt.i

	If iX_Position_alt > 620
		iX_Position_alt = 0
		Box (0, 0, 620, 200, RGB(255,255,255))
	Else
		LineXY (iX_Position_alt, iY_Position_alt, iX_Position_alt + 1, iWert, RGB(255,0,0))
		iX_Position_alt + 1
		iY_Position_alt = iWert
		ProcedureReturn iX_Position_alt + 1
	EndIf
	
EndProcedure


Folgender Beispiel-Quellcode: StopDrawing()/StartDrawing() wird nur ausgeführt, wenn eine Grafik Vollständig gezeichnet wurde
Ergebnis: 384000 Werte/Sek 620 FPS

...geht aber nicht bei 2 Grafiken, die gleichzeitig gezeichnet werden sollen

Code: Alles auswählen

Declare.i Draw_Graph_1 (iWert.i)


Enumeration
	#GUI
	#Image_1
	#Image_Gadget_1
	#Label
EndEnumeration



OpenWindow(#GUI, 0, 0, 640, 480, "Drawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

TextGadget	(#Label, 10, 10, 600, 18, "")

CreateImage(#Image_1, 620, 200, 24, $FFFFFF)

ImageGadget(#Image_Gadget_1, 10,  60, 620, 200, ImageID(#Image_1))


Global Sin_Counter.d
Global Plottwert.d

Global Status_Graph_1.i

Global Timer
Global Counter


StartDrawing(ImageOutput(#Image_1))

Repeat
	
	; FPS berechnen und anzeigen
	If ElapsedMilliseconds() - Timer > 1000
		SetGadgetText	(#Label, "[Graph_1]       " + Str(Counter) + " Werte/Sek      " + Str(Counter/620) + " FPS")
		Timer 	= ElapsedMilliseconds()
		Counter = 0
	Else
		Counter + 1
	EndIf
	
	
	; Sinus erzeugen
	Sin_Counter + 0.03035
	Plottwert 	= Sin(Sin_Counter) * 70 + Random(10,0) - Random(10,0) + 100
	
	
	
	; Werte in den ersten Graphen plotten
	Status_Graph_1 = Draw_Graph_1 (Plottwert)
	
	
	; Graph 1 in der GUI darstellen, wenn alle Werte gezeichnet wurden
	If Status_Graph_1 = 620
		StopDrawing()
		SetGadgetState(#Image_Gadget_1, ImageID(#Image_1))
		StartDrawing(ImageOutput(#Image_1))
	EndIf
	
	
	; irgendwelche Events
	Select WindowEvent()
		
	Case #PB_Event_CloseWindow
		
		End
		
	EndSelect
	
ForEver





; Beispielgraph 1
Procedure Draw_Graph_1 (iWert.i)
	
	Static 		iX_Position_alt.i
	Static 		iY_Position_alt.i

	If iX_Position_alt > 620
		iX_Position_alt = 0
		Box (0, 0, 620, 200, RGB(255,255,255))
	Else
		LineXY (iX_Position_alt, iY_Position_alt, iX_Position_alt + 1, iWert, RGB(255,0,0))
		iX_Position_alt + 1
		iY_Position_alt = iWert
		ProcedureReturn iX_Position_alt + 1
	EndIf
	
EndProcedure

Zwischen 24K Werte/Sek und 384K Werte/Sek ist ja schon ein starker unterschied. Wie kann ich so ein Leistungseinbruch vermeiden?

...noch so eine Nebenfrage. Gibt es so etwas wie "IsDrawing()" ? Makros die ich dazu im Internet gefunden habe, haben immer irgendwelche Fehlermeldungen erzeugt :(

viele Grüße,
SBond
41 6c 73 6f 20 77 65 6e 6e 20 64 75 20 73 6f 20 76 69 65 6c 20 4c 61 6e 67 65 77 65 69 6c 65 20 68 61 73 74 2c 20 64 61 6e 6e 20 6b 61 6e 6e 73 74 20 64 75 20 61 75 63 68 20 67 6c 65 69 63 68 20 7a 75 20 6d 69 72 20 6b 6f 6d 6d 65 6e 20 75 6e 64 20 61 62 77 61 73 63 68 65 6e 2e

:D
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: 2D Drawing: StartDrawing()/StopDrawing() bremsen aus

Beitrag von NicTheQuick »

Es gibt noch DrawingBuffer() und Konsorten. Vielleicht wirst du da fündig.
Christian+
Beiträge: 213
Registriert: 13.07.2008 10:05
Computerausstattung: Windows 8.1 Pro
AMD Phenom II X4 955 @ 3.2 GHz
4GB RAM
NVIDIA GeForce GTX 660

Re: 2D Drawing: StartDrawing()/StopDrawing() bremsen aus

Beitrag von Christian+ »

NicTheQuick hat recht DrawingBuffer() wird wohl die einzige Möglichkeit sein um das ohne Threads oder Libs wie GDI+ und so noch schneller zu bekommen.

Ich habe mal kurz deinen Code angepasst und ein kleines Beispiel gebastelt das zumindest bei mir immerhin schon 7 mal schneller ist und vermutlich noch weitere Optimierungsmöglichkeiten bietet.
Ist natürlich nicht so komfortabel, da ohne das Start- und StopDrawing nicht auf die Zeichenbefehle zugreifen werden kann und somit nur geeignet wenn man da keine so komplexen braucht.

Code: Alles auswählen

Structure BufferImage
  Image.i
  Buffer.i
  Width.i
  Height.i
  BGR.i
  ReversedY.i
EndStructure

Procedure CreateBufferImage(Width, Height, Color)
  Protected *Image.BufferImage = AllocateMemory(SizeOf(BufferImage))
  *Image\Image = CreateImage(#PB_Any, Width, Height, 32, Color)
  StartDrawing(ImageOutput(*Image\Image))
  *Image\Buffer = DrawingBuffer()
  If DrawingBufferPixelFormat() & #PB_PixelFormat_32Bits_BGR
    *Image\BGR = #True
  EndIf
  If DrawingBufferPixelFormat() & #PB_PixelFormat_ReversedY
    *Image\ReversedY = #True
  EndIf
  StopDrawing()
  *Image\Width = Width
  *Image\Height = Height
  ProcedureReturn *Image
EndProcedure

Macro RGB2BGR(_ColorRGB)
  (_ColorRGB & $FF000000) | ((_ColorRGB & $FF0000) >> 16) | (_ColorRGB & $FF00) | ((_ColorRGB & $FF) << 16)
EndMacro

Macro BufferImagePlot(_Image, _x, _y, _Color)
  If (_x) >= 0 And (_y) >= 0 And ((_x) + (_y) * _Image\Width) < _Image\Width * _Image\Height
    If *Image\ReversedY
      If *Image\BGR
        PokeL(_Image\Buffer + ((_x) + (_Image\Height - 1 - (_y)) * _Image\Width) << 2, RGB2BGR(_Color))
      Else
        PokeL(_Image\Buffer + ((_x) + (_Image\Height - 1 - (_y)) * _Image\Width) << 2, _Color)   
      EndIf
    Else
      If *Image\BGR
        PokeL(_Image\Buffer + ((_x) + (_y) * _Image\Width) << 2, RGB2BGR(_Color))
      Else
        PokeL(_Image\Buffer + ((_x) + (_y) * _Image\Width) << 2, _Color)
      EndIf
    EndIf
  EndIf
EndMacro

Macro BufferImagePlotRawColor(_Image, _x, _y, _Color)
  ;Schnellere Varainte die _Color bereits in der zum Image passenden RGB bzw. BGR Form erwartet!
  If (_x) >= 0 And (_y) >= 0 And ((_x) + (_y) * _Image\Width) < _Image\Width * _Image\Height
    If *Image\ReversedY
      PokeL(_Image\Buffer + ((_x) + (_Image\Height - 1 - (_y)) * _Image\Width) << 2, _Color)   
    Else
      PokeL(_Image\Buffer + ((_x) + (_y) * _Image\Width) << 2, _Color)
    EndIf
  EndIf
EndMacro

Procedure BresenhamLine(*image.BufferImage, x1.i, y1.i, x2.i, y2.i, color.i)
  Protected dy.i = y2 - y1
  Protected dx.i = x2 - x1
  Protected stepx.i, stepy.i, fraction.i
  If dy < 0 : dy = -dy : stepy = -1 : Else : stepy = 1 : EndIf
  If dx < 0 : dx = -dx : stepx = -1 : Else : stepx = 1 : EndIf
  dy = dy << 1
  dx = dx << 1
  If *Image\BGR : color = RGB2BGR(color) : EndIf 
  BufferImagePlotRawColor(*image, x1, y1, color)
  If dx > dy
    fraction = dy - (dx >> 1)
    While x1 <> x2 
      If fraction >= 0
        y1 + stepy
        fraction - dx
      EndIf
      x1 + stepx
      fraction + dy
      BufferImagePlotRawColor(*image, x1, y1, color)
    Wend
  Else 
    fraction = dx - (dy >> 1)
    While y1 <> y2
      If fraction >= 0
        x1 + stepx
        fraction - dy
      EndIf
      y1 + stepy
      fraction + dx
      BufferImagePlotRawColor(*image, x1, y1, color)
    Wend
  EndIf
EndProcedure
 
Declare.i Draw_Graph_1 (iWert.i)
Declare.i Draw_Graph_2 (iWert.i)


Enumeration
   #GUI
   #Image_Gadget_1
   #Image_Gadget_2
   #Label
EndEnumeration



OpenWindow(#GUI, 0, 0, 640, 480, "Drawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

SmartWindowRefresh(#GUI, #True)

TextGadget   (#Label, 10, 10, 600, 18, "")

Global *Image1.BufferImage = CreateBufferImage(620, 200, $FFFFFF)
Global *Image2.BufferImage = CreateBufferImage(620, 200, $FFFFFF)

ImageGadget(#Image_Gadget_1, 10,  60, 620, 200, ImageID(*Image1\Image))
ImageGadget(#Image_Gadget_2, 10, 270, 620, 200, ImageID(*Image2\Image))

Global Sin_Counter.d
Global Plottwert.d

Global Status_Graph_1.i
Global Status_Graph_2.i

Global Timer
Global Counter


Repeat
   
   ; FPS berechnen und anzeigen
   If ElapsedMilliseconds() - Timer > 1000
      SetGadgetText   (#Label, "[Graph_1]       " + Str(Counter) + " Werte/Sek      " + Str(Counter/620) + " FPS")
      Timer    = ElapsedMilliseconds()
      Counter = 0
   Else
      Counter + 1
   EndIf
   
   
   ; Sinus erzeugen
   Sin_Counter + 0.03035
   Plottwert    = Sin(Sin_Counter) * 70 + Random(10,0) - Random(10,0) + 100
   
   
   
   ; Werte in den ersten Graphen plotten
   ;StartDrawing(ImageOutput(#Image_1))
   Status_Graph_1 = Draw_Graph_1 (Plottwert)
   ;StopDrawing()
   
   ; Graph 1 in der GUI darstellen, wenn alle Werte gezeichnet wurden
   If Status_Graph_1 = 620
      SetGadgetState(#Image_Gadget_1, ImageID(*Image1\Image))
   EndIf
   

   ; Werte in den zweiten Graphen plotten
   ;StartDrawing(ImageOutput(#Image_2))
   Status_Graph_2 = Draw_Graph_2 (Plottwert)
   ;StopDrawing()
   
   ; Graph 2 in der GUI darstellen, wenn alle Werte gezeichnet wurden
   If Status_Graph_2 = 620
      SetGadgetState(#Image_Gadget_2, ImageID(*Image2\Image))
   EndIf
   
   ; irgendwelche Events
   Select WindowEvent()
      
   Case #PB_Event_CloseWindow
      
      End
      
   EndSelect
   
ForEver

; Beispielgraph 1
Procedure Draw_Graph_1 (iWert.i)
   
   Static       iX_Position_alt.i
   Static       iY_Position_alt.i

   If iX_Position_alt > 620
      iX_Position_alt = 0
      ;Box (0, 0, 620, 200, RGB(255,255,255))
      FillMemory(*Image1\Buffer, 620*200*4, RGBA(255,255,255,255), #PB_Long)
   Else
      BresenhamLine(*Image1, iX_Position_alt, iY_Position_alt, iX_Position_alt + 1, iWert, RGBA(255,0,0,255))
      ;LineXY (iX_Position_alt, iY_Position_alt, iX_Position_alt + 1, iWert, RGB(255,0,0))
      iX_Position_alt + 1
      iY_Position_alt = iWert
      ProcedureReturn iX_Position_alt + 1
   EndIf
   
EndProcedure



; Beispielgraph 2
Procedure Draw_Graph_2 (iWert.i)
   
   Static       iX_Position_alt.i
   Static       iY_Position_alt.i

   If iX_Position_alt > 620
      iX_Position_alt = 0
      ;Box (0, 0, 620, 200, RGB(255,255,255))
      FillMemory(*Image2\Buffer, 620*200*4, RGBA(255,255,255,255), #PB_Long)
   Else
      BresenhamLine(*Image2, iX_Position_alt, iY_Position_alt, iX_Position_alt + 1, iWert, RGBA(255,0,0,255))
      ;LineXY (iX_Position_alt, iY_Position_alt, iX_Position_alt + 1, iWert, RGB(255,0,0))
      iX_Position_alt + 1
      iY_Position_alt = iWert
      ProcedureReturn iX_Position_alt + 1
   EndIf
   
EndProcedure
Zuletzt geändert von Christian+ am 14.02.2014 09:32, insgesamt 2-mal geändert.
Windows 8.1 Pro 64Bit | AMD Phenom II X4 955 @ 3.2 GHz | 4GB RAM | NVIDIA GeForce GTX 660
SBond
Beiträge: 266
Registriert: 22.05.2013 20:35

Re: 2D Drawing: StartDrawing()/StopDrawing() bremsen aus

Beitrag von SBond »

sehr gut :D

...ich glaube auf so etwas wäre ich nicht so schnell gekommen. ...und mit BresenhamLine schon gar nicht.

vielen Dank :)
Ich denke damit kann ich schon wesentlich besser arbeiten ^^
41 6c 73 6f 20 77 65 6e 6e 20 64 75 20 73 6f 20 76 69 65 6c 20 4c 61 6e 67 65 77 65 69 6c 65 20 68 61 73 74 2c 20 64 61 6e 6e 20 6b 61 6e 6e 73 74 20 64 75 20 61 75 63 68 20 67 6c 65 69 63 68 20 7a 75 20 6d 69 72 20 6b 6f 6d 6d 65 6e 20 75 6e 64 20 61 62 77 61 73 63 68 65 6e 2e

:D
Christian+
Beiträge: 213
Registriert: 13.07.2008 10:05
Computerausstattung: Windows 8.1 Pro
AMD Phenom II X4 955 @ 3.2 GHz
4GB RAM
NVIDIA GeForce GTX 660

Re: 2D Drawing: StartDrawing()/StopDrawing() bremsen aus

Beitrag von Christian+ »

Ich habe den Code nochmal angepasst BresenhamLine sollte nun ein wenig schneller sein. Außerdem wird nun #PB_PixelFormat_ReversedY beachtet denn das kann sonst zu gespiegelten Images führen wenn auf dem jeweiligen Rechner Images mir ReversedY erstellt werden. Hatte ich für das Beispiel ignoriert sollte man aber auf alle Fälle beachten, da man sich nie sicher sein kann ob PB auf dem jeweiligen OS ein Image mir ReversedY oder nicht anlegt genau wie auch durchaus RGB und BGR Mode vorkommen können.
Windows 8.1 Pro 64Bit | AMD Phenom II X4 955 @ 3.2 GHz | 4GB RAM | NVIDIA GeForce GTX 660
Benutzeravatar
mk-soft
Beiträge: 3844
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: 2D Drawing: StartDrawing()/StopDrawing() bremsen aus

Beitrag von mk-soft »

:allright:
Habe aber etwas umgebaut.

Man kann zwar nicht Gadgets aus Thread anlegen, aber aktuallisieren.
Das zeichnen liegt in eine Thread und ist etwas mit "Delay(5)" ausgebremst. Komme so aber immer noch aus 50 FPS.
Ausserdem kann man das Fenster verschieben ohne das die Grafik unterbrochen wird.

Code: Alles auswählen

Structure BufferImage
  Image.i
  Buffer.i
  Width.i
  Height.i
  BGR.i
  ReversedY.i
EndStructure

Procedure CreateBufferImage(Width, Height, Color)
  Protected *Image.BufferImage = AllocateMemory(SizeOf(BufferImage))
  *Image\Image = CreateImage(#PB_Any, Width, Height, 32, Color)
  StartDrawing(ImageOutput(*Image\Image))
  *Image\Buffer = DrawingBuffer()
  If DrawingBufferPixelFormat() & #PB_PixelFormat_32Bits_BGR
    *Image\BGR = #True
  EndIf
  If DrawingBufferPixelFormat() & #PB_PixelFormat_ReversedY
    *Image\ReversedY = #True
  EndIf
  StopDrawing()
  *Image\Width = Width
  *Image\Height = Height
  ProcedureReturn *Image
EndProcedure

Macro RGB2BGR(_ColorRGB)
  (_ColorRGB & $FF000000) | ((_ColorRGB & $FF0000) >> 16) | (_ColorRGB & $FF00) | ((_ColorRGB & $FF) << 16)
EndMacro

Macro BufferImagePlot(_Image, _x, _y, _Color)
  If (_x) >= 0 And (_y) >= 0 And ((_x) + (_y) * _Image\Width) < _Image\Width * _Image\Height
    If *Image\ReversedY
      If *Image\BGR
        PokeL(_Image\Buffer + ((_x) + (_Image\Height - 1 - (_y)) * _Image\Width) << 2, RGB2BGR(_Color))
      Else
        PokeL(_Image\Buffer + ((_x) + (_Image\Height - 1 - (_y)) * _Image\Width) << 2, _Color)   
      EndIf
    Else
      If *Image\BGR
        PokeL(_Image\Buffer + ((_x) + (_y) * _Image\Width) << 2, RGB2BGR(_Color))
      Else
        PokeL(_Image\Buffer + ((_x) + (_y) * _Image\Width) << 2, _Color)
      EndIf
    EndIf
  EndIf
EndMacro

Macro BufferImagePlotRawColor(_Image, _x, _y, _Color)
  ;Schnellere Varainte die _Color bereits in der zum Image passenden RGB bzw. BGR Form erwartet!
  If (_x) >= 0 And (_y) >= 0 And ((_x) + (_y) * _Image\Width) < _Image\Width * _Image\Height
    If *Image\ReversedY
      PokeL(_Image\Buffer + ((_x) + (_Image\Height - 1 - (_y)) * _Image\Width) << 2, _Color)   
    Else
      PokeL(_Image\Buffer + ((_x) + (_y) * _Image\Width) << 2, _Color)
    EndIf
  EndIf
EndMacro

Procedure BresenhamLine(*image.BufferImage, x1.i, y1.i, x2.i, y2.i, color.i)
  Protected dy.i = y2 - y1
  Protected dx.i = x2 - x1
  Protected stepx.i, stepy.i, fraction.i
  If dy < 0 : dy = -dy : stepy = -1 : Else : stepy = 1 : EndIf
  If dx < 0 : dx = -dx : stepx = -1 : Else : stepx = 1 : EndIf
  dy = dy << 1
  dx = dx << 1
  If *Image\BGR : color = RGB2BGR(color) : EndIf
  BufferImagePlotRawColor(*image, x1, y1, color)
  If dx > dy
    fraction = dy - (dx >> 1)
    While x1 <> x2
      If fraction >= 0
        y1 + stepy
        fraction - dx
      EndIf
      x1 + stepx
      fraction + dy
      BufferImagePlotRawColor(*image, x1, y1, color)
    Wend
  Else
    fraction = dx - (dy >> 1)
    While y1 <> y2
      If fraction >= 0
        x1 + stepx
        fraction - dy
      EndIf
      y1 + stepy
      fraction + dx
      BufferImagePlotRawColor(*image, x1, y1, color)
    Wend
  EndIf
EndProcedure
 
Declare.i Draw_Graph_1 (iWert.i)
Declare.i Draw_Graph_2 (iWert.i)


Enumeration
   #GUI
   #Image_Gadget_1
   #Image_Gadget_2
   #Label
EndEnumeration

Global *Image1.BufferImage = CreateBufferImage(620, 200, $FFFFFF)
Global *Image2.BufferImage = CreateBufferImage(620, 200, $FFFFFF)

Global Sin_Counter.d
Global Plottwert.d

Global Status_Graph_1.i
Global Status_Graph_2.i

Global Timer
Global Counter


Global exit

Procedure thGraph(dummy)
  
  Repeat
    
     ; FPS berechnen und anzeigen
   If ElapsedMilliseconds() - Timer > 1000
      SetGadgetText   (#Label, "[Graph_1]       " + Str(Counter) + " Werte/Sek      " + Str(Counter/620) + " FPS")
      Timer    = ElapsedMilliseconds()
      Counter = 0
   Else
      Counter + 1
   EndIf
   
   
   ; Sinus erzeugen
   Sin_Counter + 0.03035
   Plottwert    = Sin(Sin_Counter) * 70 + Random(10,0) - Random(10,0) + 100
   
   
   
   ; Werte in den ersten Graphen plotten
   ;StartDrawing(ImageOutput(#Image_1))
   Status_Graph_1 = Draw_Graph_1 (Plottwert)
   ;StopDrawing()
   
   ; Graph 1 in der GUI darstellen, wenn alle Werte gezeichnet wurden
   If Status_Graph_1 = 620
     SetGadgetState(#Image_Gadget_1, ImageID(*Image1\Image))
     Delay(5)
   EndIf
   

   ; Werte in den zweiten Graphen plotten
   ;StartDrawing(ImageOutput(#Image_2))
   Status_Graph_2 = Draw_Graph_2 (Plottwert)
   ;StopDrawing()
   
   ; Graph 2 in der GUI darstellen, wenn alle Werte gezeichnet wurden
   If Status_Graph_2 = 620
     SetGadgetState(#Image_Gadget_2, ImageID(*Image2\Image))
     Delay(5)
   EndIf
   
 Until exit
 
EndProcedure


OpenWindow(#GUI, 0, 0, 640, 480, "Drawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

SmartWindowRefresh(#GUI, #True)

TextGadget   (#Label, 10, 10, 600, 18, "")

ImageGadget(#Image_Gadget_1, 10,  60, 620, 200, ImageID(*Image1\Image))
ImageGadget(#Image_Gadget_2, 10, 270, 620, 200, ImageID(*Image2\Image))

Global thread = CreateThread(@thGraph(), 0)

Repeat
   
   
   ; irgendwelche Events
   Select WaitWindowEvent()
     
   Case #PB_Event_CloseWindow
     
     exit = 1
     
   EndSelect
   
   If IsThread(thread) = 0
     Break
   EndIf
     
ForEver

; Beispielgraph 1
Procedure Draw_Graph_1 (iWert.i)
   
   Static       iX_Position_alt.i
   Static       iY_Position_alt.i

   If iX_Position_alt > 620
      iX_Position_alt = 0
      ;Box (0, 0, 620, 200, RGB(255,255,255))
      FillMemory(*Image1\Buffer, 620*200*4, RGBA(255,255,255,255), #PB_Long)
   Else
      BresenhamLine(*Image1, iX_Position_alt, iY_Position_alt, iX_Position_alt + 1, iWert, RGBA(255,0,0,255))
      ;LineXY (iX_Position_alt, iY_Position_alt, iX_Position_alt + 1, iWert, RGB(255,0,0))
      iX_Position_alt + 1
      iY_Position_alt = iWert
      ProcedureReturn iX_Position_alt + 1
   EndIf
   
EndProcedure



; Beispielgraph 2
Procedure Draw_Graph_2 (iWert.i)
   
   Static       iX_Position_alt.i
   Static       iY_Position_alt.i

   If iX_Position_alt > 620
      iX_Position_alt = 0
      ;Box (0, 0, 620, 200, RGB(255,255,255))
      FillMemory(*Image2\Buffer, 620*200*4, RGBA(255,255,255,255), #PB_Long)
   Else
      BresenhamLine(*Image2, iX_Position_alt, iY_Position_alt, iX_Position_alt + 1, iWert, RGBA(255,0,0,255))
      ;LineXY (iX_Position_alt, iY_Position_alt, iX_Position_alt + 1, iWert, RGB(255,0,0))
      iX_Position_alt + 1
      iY_Position_alt = iWert
      ProcedureReturn iX_Position_alt + 1
   EndIf
   
EndProcedure
FF :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
walbus
Beiträge: 137
Registriert: 03.03.2013 20:50

Re: 2D Drawing: StartDrawing()/StopDrawing() bremsen aus

Beitrag von walbus »

:)
Zuletzt geändert von walbus am 07.02.2015 22:57, insgesamt 3-mal geändert.
SBond
Beiträge: 266
Registriert: 22.05.2013 20:35

Re: 2D Drawing: StartDrawing()/StopDrawing() bremsen aus

Beitrag von SBond »

oh man...

vielen Dank :)

Ich fühle mich, als wäre ich noch grün hinter den Ohren. Ich bin immer wieder erstaunt welche Lösungen hier gezeigt werden. ...wie lange muss man programmieren, um so ein Niveau zu erreichen? Ich programmiere ab und an ein wenig, aber irgendwie spüre ich keine Verbesserung meiner Programmierkenntnisse.
41 6c 73 6f 20 77 65 6e 6e 20 64 75 20 73 6f 20 76 69 65 6c 20 4c 61 6e 67 65 77 65 69 6c 65 20 68 61 73 74 2c 20 64 61 6e 6e 20 6b 61 6e 6e 73 74 20 64 75 20 61 75 63 68 20 67 6c 65 69 63 68 20 7a 75 20 6d 69 72 20 6b 6f 6d 6d 65 6e 20 75 6e 64 20 61 62 77 61 73 63 68 65 6e 2e

:D
matbal
Beiträge: 261
Registriert: 30.03.2011 20:53

Re: 2D Drawing: StartDrawing()/StopDrawing() bremsen aus

Beitrag von matbal »

@SBond

Die Lösung von walbus ist eingentlich nicht ganz korrekt. Die beiden Grafiken werden nicht parallel gezeichnet sondern abwechselnd. Also die ersten 620 Punkte in die erste Grafik, dann die nächsten 620 Punkte in die zweite Grafik.

Das abwechselnde Zeichnen bekommt man auch ohne Tricks genügend schnell hin.

Wirklich parallel muß ja auch nicht gezeichnet werden, wenn du die Grafiken doch erst anzeigst, nachdem du alle 620 Punkte zusammen hast. Du brauchst eigentlich nur das Konzept ein wenig ändern: In deiner Mal-Funktion sammelst du einfach alle Punkte in einem Array, bis du die benötigten 620 Punkte zusammen hast, und malst dann die ganze Grafik am Stück.
walbus
Beiträge: 137
Registriert: 03.03.2013 20:50

Re: 2D Drawing: StartDrawing()/StopDrawing() bremsen aus

Beitrag von walbus »

:)
Zuletzt geändert von walbus am 07.02.2015 22:58, insgesamt 1-mal geändert.
Antworten