Seite 1 von 1

Canvas - weiße Flitzer vermeiden

Verfasst: 25.05.2012 19:37
von Lambda
Wenn man ein größeres Canvas zu rendern hat in dem dann auchnoch relativ viel zu berechnen/zeichnen ist, entsteht beim verändern der größe schnell mal "weiße Flitzer". Ich hoffe ihr wisst was ich damit mein.

Meine Frage ist jetzt, wie kann man die am besten vermeiden? Je nachdem in welchem modus sich mein Lap befindet sind die Flitzer deutlicher oder kaum bemerkbar.

Könnte man mit #WM_SETREDRAW was erreichen? (oder zumindest mal die Grundfarbe(weiß) ändern)

Re: Canvas - weiße Flitzer vermeiden

Verfasst: 25.05.2012 19:52
von STARGÅTE
Ich weiß was du meinst.
Zum einen kannst du SmartWindowRefresh() nutzen.
Zum anderen wäre dein "Zeichnen" schneller, wenn du bei einem ReSize-Event vom Fenster auch nur den Bereich im Gadget neuzeichnest, der sich auch verändert hat.
Ansonsten ist deine Zeichnung einfach zu langsam (Debugger an oder aus ?)

Vielleicht kannst du ja mal ein Beispiel schicken, wo man das flackern eindeutig sieht.

PS: Bei meinem TabBarGadget gibt es dieses Flackern auch, aber erst wenn das gadget wirklich riesig wird.

Re: Canvas - weiße Flitzer vermeiden

Verfasst: 25.05.2012 20:05
von Lambda
Ein Beispiel geht leider nicht, es ist auch wie gesagt unterschiedlich. Wenn ich Illustrator laufen hab schaltet mein Lap das Aero Theme ab, jetzt ist das Flackern sehr deutlich.

SmartWindowRefresh() ist deutlich besser, aber wenn ich z.B mit GDI arbeite und allein schon 1 größeres Bild render -> wieder deutliches Flackern.

Re: Canvas - weiße Flitzer vermeiden

Verfasst: 25.05.2012 20:15
von Danilo

Code: Alles auswählen

    SendMessage_(GadgetID,#WM_SETREDRAW,#False,0)

        ; resize und redraw

    SendMessage_(GadgetID,#WM_SETREDRAW,#True,0)
    InvalidateRect_(GadgetID,#WM_SETREDRAW,0,1)
#False sperrt das Neuzeichnen:

Code: Alles auswählen

  If OpenWindow(0, 0, 0, 220, 220, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CanvasGadget(0, 10, 10, 200, 200)

    SendMessage_(GadgetID(0),#WM_SETREDRAW,#False,0)
    
    Repeat
      Event = WaitWindowEvent()
          
      If Event = #PB_Event_Gadget And EventGadget() = 0 
        If EventType() = #PB_EventType_LeftButtonDown Or (EventType() = #PB_EventType_MouseMove And GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton)
          If StartDrawing(CanvasOutput(0))
            x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
            y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
            Circle(x, y, 10, RGB(Random(255), Random(255), Random(255)))
            StopDrawing()
          EndIf
        EndIf
      EndIf    
      
    Until Event = #PB_Event_CloseWindow
  EndIf
EDIT: Während #WM_SETREDRAW gesperrt ist, geht CanvasOutput() nicht.

Was Du mal probieren kannst: Zeichne auf ein Bild statt auf das CanvasGadget
und setze danach die neue Größe des CanvasGadget und Dein neues Bild.

Code: Alles auswählen

        SendMessage_(GadgetID(0),#WM_SETREDRAW,#False,0)
          ResizeGadget(0,10,10,400,400)
          SetGadgetAttribute(0,#PB_Canvas_Image,ImageID(0))
        SendMessage_(GadgetID(0),#WM_SETREDRAW,#True,0)
        InvalidateRect_(GadgetID(0),0,1)
Zeichnen und dann F1 drücken zum anzeigen:

Code: Alles auswählen

  If OpenWindow(0, 0, 0, 420, 420, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CanvasGadget(0, 10, 10, 200, 200)
    
    CreateImage(0,400,400)
    
    AddKeyboardShortcut(0,#PB_Shortcut_F1,1)
    
    Repeat
      Event = WaitWindowEvent()
          
      If Event = #PB_Event_Gadget And EventGadget() = 0 
        If EventType() = #PB_EventType_LeftButtonDown Or (EventType() = #PB_EventType_MouseMove) ;And GetGadgetAttribute(0, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton)
          If StartDrawing(ImageOutput(0))
            x = GetGadgetAttribute(0, #PB_Canvas_MouseX)*2
            y = GetGadgetAttribute(0, #PB_Canvas_MouseY)*2
            Circle(x, y, 10, RGB(Random(255), Random(255), Random(255)))
            StopDrawing()
          EndIf
        EndIf
      ElseIf Event = #PB_Event_Menu
        SendMessage_(GadgetID(0),#WM_SETREDRAW,#False,0)
          ResizeGadget(0,10,10,400,400)
          SetGadgetAttribute(0,#PB_Canvas_Image,ImageID(0))
        SendMessage_(GadgetID(0),#WM_SETREDRAW,#True,0)
        InvalidateRect_(GadgetID(0),0,1)
      EndIf    
      
    Until Event = #PB_Event_CloseWindow
  EndIf

Re: Canvas - weiße Flitzer vermeiden

Verfasst: 30.05.2012 21:20
von dige
Was genau macht eigentlich SmartWindowRefresh() ? Ich kann keinen Unterschied
feststellen. Aktuell habe ich das Problem, das mit der neusten Version PB4.61
ständig ein Flacker Effekt bei der Darstellung von ImageGadgets auftreten.
Sogar wenn man die Alt-Taste drückt.

Da dieses Verhalten definitiv erst ab Version v4.61 auftritt, habe ich es als
Bug gepostet: http://www.purebasic.fr/english/viewtop ... =4&t=50110

Re: Canvas - weiße Flitzer vermeiden

Verfasst: 30.05.2012 21:47
von ts-soft
SmartWindowRefresh verwendet mehrere Verfahren um das Flackern beim Resizen zu mildern.
Dafür ruckelt es dann beim Resizen :mrgreen:
Was da genau gemacht wird weiß ich allerdings nicht, aber evtl. wird dem Style #WS_CLIPCHILDREN oder ähnlich hinzugefügt,
oder das Neuzeichnen wird kurzfristig deaktiviert usw.

Aber bei Flackern der ImageGadgets wird das wohl eher nicht helfen, es sei denn, die werden Ständig resized.

Gruß
Thomas

Re: Canvas - weiße Flitzer vermeiden

Verfasst: 07.06.2012 00:01
von Deluxe0321
Ich nutze direkt nach OpenWindow(X,Y,Z)

Code: Alles auswählen

SmartWindowRefresh(WindowID.i,#True)
und beim size event (#PB_Event_SizeWindow)

Code: Alles auswählen

  If Event = #PB_Event_SizeWindow
    ;ResizeGadget(X,Y,Z) etc..
    RedrawWindow_(WindowID(WindowID), 0, 0, #RDW_UPDATENOW) 
  EndIf  
Schon flackert und stockt nix mehr, außer das Webgadget(), das hängt !immer! hinterher.

Grüße

Edit: direkt nach dem posten gesehen, der Thread ist schon "alt", sry ;)