Page 1 of 1

ImageGadget blinking

Posted: Fri Oct 18, 2024 5:42 pm
by AtomUpgrader
that code shows blinking:

Code: Select all

OpenWindow(0, 0, 0, 300, 300, "test", #PB_Window_ScreenCentered)
CreateImage(0, 240, 240, 32) ; only with 32-bits depth
ImageGadget(0, 20, 20, 240, 240, 0)
Repeat
Repeat
e = WindowEvent()
If e = #PB_Event_CloseWindow
End
EndIf
Until Not e
SetGadgetState(0, ImageID(0))
Delay(1)
ForEver
PureBasic 6.03 LTS (Windows - x64)
It is only my problem? Anyone test this please :)

Re: ImageGadget blinking

Posted: Fri Oct 18, 2024 6:40 pm
by spikey
Yes, it flickers but it's unsurprising. You're attempting to update the gadget around 1000 times per second! In practice, you won't achieve this. It takes time to perform an update and even the most advanced gaming monitors available refresh only at 500Hz max. More typical hardware will only be running between 60Hz to 360Hz. You also update the gadget every cycle even though there is no actual change to the content.

If you're trying to animate an image have a look at "ImagePlugin_GIF.pb" in the Examples folder.

Re: ImageGadget blinking

Posted: Fri Oct 18, 2024 7:12 pm
by mk-soft
You can't do it like that.
With SetGadgetState of the ImageGadget, the image is constantly redrawn.

Code: Select all

;-TOP

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(0)
  dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
  ; Resize Gadgets
EndProcedure

Procedure Main()
  Protected dx, dy, image
  
  #WinStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(0, #PB_Ignore, #PB_Ignore, 600, 400, "Test Window", #WinStyle)
    ; MenuBar
    CreateMenu(0, WindowID(0))
    MenuTitle("File")
    
    ; StatusBar
    CreateStatusBar(0, WindowID(0))
    AddStatusBarField(#PB_Ignore)
    
    ; Images
    CreateImage(0, 64, 64, 32, #Red)
    CreateImage(1, 64, 64, 32, #Yellow)
    CreateImage(2, 64, 64, 32, #Green)
    
    ; Gadgets
    dx = WindowWidth(0)
    dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
    ImageGadget(0, 10, 10, 64, 64, ImageID(0), #PB_Image_Border)
    
    ; Bind Events
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), 0)
    
    AddWindowTimer(0, 1, 800)
    
    ; Main Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case 0
              Break
          EndSelect
          
        Case #PB_Event_Menu
          Select EventMenu()
            
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
              
          EndSelect
          
        Case #PB_Event_Timer
          Select EventTimer()
            Case 1
              image + 1
              If image > 2
                image = 0
              EndIf
              SetGadgetState(0, ImageID(image))
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()

Re: ImageGadget blinking

Posted: Fri Oct 18, 2024 11:22 pm
by AtomUpgrader
@mk-soft, So I changed your code a little and the problem has shown itself.

Code: Select all

;-TOP

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(0)
  dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
  ; Resize Gadgets
EndProcedure

Procedure Main()
  Protected dx, dy, image
  
  #WinStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(0, #PB_Ignore, #PB_Ignore, 600, 400, "Test Window", #WinStyle)
    ; MenuBar
    CreateMenu(0, WindowID(0))
    MenuTitle("File")
    
    ; StatusBar
    CreateStatusBar(0, WindowID(0))
    AddStatusBarField(#PB_Ignore)
    
    ; Images
    CreateImage(0, 640, 640, 32, #Black)
    CreateImage(1, 640, 640, 32, #Black)
    CreateImage(2, 640, 640, 32, #Black)
    
    ; Gadgets
    dx = WindowWidth(0)
    dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
    ImageGadget(0, 10, 10, 64, 64, ImageID(0), #PB_Image_Border)
    
    ; Bind Events
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), 0)
    
    AddWindowTimer(0, 1, 20)
    
    ; Main Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case 0
              Break
          EndSelect
          
        Case #PB_Event_Menu
          Select EventMenu()
            
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
              
          EndSelect
          
        Case #PB_Event_Timer
          Select EventTimer()
            Case 1
              image + 1
              If image > 2
                image = 0
              EndIf
              SetGadgetState(0, ImageID(image))
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()

spikey wrote: Fri Oct 18, 2024 6:40 pm Yes, it flickers but it's unsurprising. You're attempting to update the gadget around 1000 times per second! In practice, you won't achieve this. It takes time to perform an update and even the most advanced gaming monitors available refresh only at 500Hz max. More typical hardware will only be running between 60Hz to 360Hz. You also update the gadget every cycle even though there is no actual change to the content.

If you're trying to animate an image have a look at "ImagePlugin_GIF.pb" in the Examples folder.
Nice try, but what about when the depth of the image switches from 32 to 24, the problem disappears? Your explain does not work in my opinion.

Re: ImageGadget blinking

Posted: Sat Oct 19, 2024 9:14 am
by pjay
The Imagegadget always has the potential to flicker regardless of refresh or update rates as it's not double-buffered.

Can you use a Canvasgadget instead?

Re: ImageGadget blinking

Posted: Sat Oct 19, 2024 12:00 pm
by ChrisR
Spikey's explanation sounds very good, as always :)
If this is to point out a behavior (you find inappropriate) between 24 and 32 bit images.
This is probably due to the fact that a transparent image needs to have its background erased before being redrawn, which is probably not required for a 24-bit image.

Re: ImageGadget blinking

Posted: Sat Oct 19, 2024 5:21 pm
by JHPJHP
Post removed.

Re: ImageGadget blinking

Posted: Sun Oct 20, 2024 4:18 am
by AZJIO
1. Update only when necessary, the human eye operates at 120Hz. A frequency value above 120 is unnecessary. And if this is information in the status bar or in the console, then the data should be updated no more than 3 times per second, for example, when displaying file search data, otherwise the text is smeared into a gray background.
2. Reduce the area of ​​the image being updated. For example, if there is text in the center and a number on the left, then create a background with an image of the text and an image of the number on it. If only the number changes, then the area of ​​the changed part will decrease by 100 times and, accordingly, the update engine will redraw it faster. Redraw only when the number has changed. Delay(50) - no flickering, frequency 20 times per second

Code: Select all

size = 220
time = 50
OpenWindow(0, 0, 0, size+40, size+40, "test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateImage(0, size, size, 32) ; only with 32-bits depth
ImageGadget(0, 20, 20, size, size, 0)
; DisableDebugger
Repeat
	Repeat
		e = WindowEvent()
		If e = #PB_Event_CloseWindow
			End
		EndIf
	Until Not e
	SetGadgetState(0, ImageID(0))
	Delay(time)
ForEver

Re: ImageGadget blinking

Posted: Sun Oct 20, 2024 5:06 am
by JHPJHP
Hi AZJIO,

Your example still flickers on my system:
• PureBasic 6.12 LTS (x64) - Debugger Disabled
• Windows 11 Pro 24H2
• 12th Gen Intel(R) Core(TM) i7-1260P 2.10 GHz
• 16.0 GB RAM

Re: ImageGadget blinking

Posted: Sun Oct 20, 2024 8:48 am
by Fred
As said before, imagegadget() isn't double buffered, so for dynamic display it's much better to use a canvasgadget()