BitBlt-Analogon mit GTK

In dieser Linux-Ecke dürfen nur Themen rund um Linux geschrieben werden.
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
blbltheworm
Beiträge: 217
Registriert: 22.09.2004 19:36
Wohnort: Auf der schönen Schwäbischen Alb

BitBlt-Analogon mit GTK

Beitrag von blbltheworm »

Hallo zusammen,

ich hab seit langem mal wieder angefangen zu programmieren und bin mittlerweile von WinXP auf Ubuntu umgestiegen.
Nun arbeite ich gerade an einen Projekt mit einer "Zeichenfunktion" (einfaches zeichnen von zwei Linien in ein vorhandenes Bild).
Dies wollte ich eigentlich über ein ImageGaget() machen (Bild laden mit StartDrawing() manipulieren und via SetGadgetState() anzeigen).

Das Problem:
Es ruckelt extrem.
Meine Vermutung ist, dass der Flaschenhals die interne Handhabung von SetGadgetState() ist, denn mein kleines Testprogramm:

Code: Alles auswählen

OpenWindow(1,400,500,400,700,"Test",#PB_Window_SystemMenu)
TreeGadget(2,10,335,380,200)

For a = 0 To 10
    AddGadgetItem (2, -1, "Node "+Str(a), 0, 0)        ; benutzen Sie ImageID(x) als 4. Parameter
    AddGadgetItem(2, -1, "Sub-Item 1", 0, 1)     ; diese sind auf dem ersten Sublevel
Next


test=CreateImage(#PB_Any ,300,200)
ImageGadget(1,50,125,300,200,ImageID(test))
dir.l=1
y=100
Repeat
  StartDrawing(ImageOutput(test))
    Box(0,0,300,200,0)
    Circle(x,y,30,RGB(255,0,0))
    StopDrawing()
    ;StartDrawing(WindowOutput(1))
    ;  DrawImage(ImageID(test),50,125)
    ;StopDrawing()
    SetGadgetState(1,ImageID(test))
    x=x+10*dir
    If x >= 300-30
      dir = -1
    ElseIf x - 30 <= 0
      dir = 1
    EndIf
    
    Delay(10)
    event=WaitWindowEvent()
    If event = #PB_Event_Gadget
      Select EventGadget()
        Case 2
          MessageRequester("Testbox","Eintrag: " + GetGadgetItemText(2,GetGadgetState(2)))
      EndSelect
      EndIf
Until event = #PB_Event_CloseWindow
läuft flüssig, solang die Maus nicht über dem Gadget ist (was bei einem Zeichenfeld etwas unpraktisch ist).
Ruckelfrei ginge es, wenn ich das Bild direkt auf das Fenster zeichne (siehe auskommentierten Teil), das finde ich jedoch unschön.

Unter Windows würde ich in diesem Fall einfach mittels BitBlt() direkt den Grafikspeicher des Gadgets manipulieren,
aber wie geht das unter Linux und GTK?
Benutzeravatar
MarkusOhm
Beiträge: 46
Registriert: 16.08.2009 15:06
Computerausstattung: Asus EeePc 904HD 900MHz Intel-Graphik-Chip-915GM WindowsXP + UbuntuLucid

Re: BitBlt-Analogon mit GTK

Beitrag von MarkusOhm »

Code: Alles auswählen

OpenWindow(1,400,500,400,700,"Test",#PB_Window_SystemMenu)
TreeGadget(2,10,335,380,200)

For a = 0 To 10
    AddGadgetItem (2, -1, "Node "+Str(a), 0, 0)        ; benutzen Sie ImageID(x) als 4. Parameter
    AddGadgetItem(2, -1, "Sub-Item 1", 0, 1)     ; diese sind auf dem ersten Sublevel
Next
 global  test=CreateImage(#PB_Any ,300,200)
ImageGadget(1,50,125,300,200,ImageID(test))
Global run=1
Global neu=0
Procedure Image(teste)
  Debug "threat gestartet"
  Shared run
  Shared test
  Shared neu
dir.l=1
y=100
While run=1
  While neu=0
StartDrawing(ImageOutput(test))
    Box(0,0,300,200,0)
    Circle(x,y,30,RGB(255,0,0))
    StopDrawing()
    ;StartDrawing(WindowOutput(1))
    ;  DrawImage(ImageID(test),50,125)
    ;StopDrawing()
    
    x=x+10*dir
    If x >= 300-30
      dir = -1
    ElseIf x - 30 <= 0
      dir = 1
    EndIf
    neu=1
  Wend
   Delay(2)
 Wend
 x=0
 dir=0
 y=0
  Debug "threat geschlossen"
  EndProcedure

Threat=CreateThread(@Image(),1)
Repeat
  If neu=1
    SetGadgetState(1,ImageID(test))
    neu=0
   EndIf
    Delay(10)
    event=WindowEvent()
    If event = #PB_Event_Gadget
      Select EventGadget()
        Case 2
          MessageRequester("Testbox","Eintrag: " + GetGadgetItemText(2,GetGadgetState(2)))
      EndSelect
      EndIf
    Until event = #PB_Event_CloseWindow
    run=0
    Delay(10)
    End
Wie sieht es mit threats aus habe leider nur einen langsamen Einkerner ...
im test ging es einigermasen
Asus EeePc 904HD 900MHz Intel-Graphik-Chip-915GM WindowsXP + UbuntuLucid
Benutzeravatar
blbltheworm
Beiträge: 217
Registriert: 22.09.2004 19:36
Wohnort: Auf der schönen Schwäbischen Alb

Re: BitBlt-Analogon mit GTK

Beitrag von blbltheworm »

Hi,

danke für deinen Vorschlag, aber das ändert leider nichts an der Ruckelorgie.

Hatt noch jemand weitere Vorschläge, oder weiß ein vernünftiges GTK-Tutorial für PB?
Benutzeravatar
FosJonas
Beiträge: 121
Registriert: 12.11.2008 19:31

Re: BitBlt-Analogon mit GTK

Beitrag von FosJonas »

Fals du PB 4.60 nutzt kannst du auch das CanvasGadget nehmen, zumindest bei mir hat das Ruckeln damit aufgehört:

Code: Alles auswählen

OpenWindow(1,400,500,400,700,"Test",#PB_Window_SystemMenu)
TreeGadget(2,10,335,380,200)

For a = 0 To 10
    AddGadgetItem (2, -1, "Node "+Str(a), 0, 0)        ; benutzen Sie ImageID(x) als 4. Parameter
    AddGadgetItem(2, -1, "Sub-Item 1", 0, 1)     ; diese sind auf dem ersten Sublevel
Next


CanvasGadget(1,50,125,300,200)
dir.l=1
y=100
Repeat
  T1 = ElapsedMilliseconds()
  StartDrawing(CanvasOutput(1))
    Box(0,0,300,200,0)
    Circle(x,y,30,RGB(255,0,0))
    StopDrawing()
    ;StartDrawing(WindowOutput(1))
    ;  DrawImage(ImageID(test),50,125)
    ;StopDrawing()
    
    x=x+10*dir
    If x >= 300-30
      dir = -1
    ElseIf x - 30 <= 0
      dir = 1
    EndIf
    
    event=WaitWindowEvent(1)
    If event = #PB_Event_Gadget
      Select EventGadget()
        Case 2
          MessageRequester("Testbox","Eintrag: " + GetGadgetItemText(2,GetGadgetState(2)))
      EndSelect
    EndIf
    
    T2 = ElapsedMilliseconds()
    If T2-T1 <= 1000/60
      Delay(17-(T2-T1))
    EndIf
    
Until event = #PB_Event_CloseWindow
Purebasic 5.10 | Kubuntu 12.04 (64 bit) | Opera 12.01 | Nvidia GT 9800
Xubuntu 12.04 (64 bit) | Intel HD Graphis (Onboard)
Benutzeravatar
blbltheworm
Beiträge: 217
Registriert: 22.09.2004 19:36
Wohnort: Auf der schönen Schwäbischen Alb

Re: BitBlt-Analogon mit GTK

Beitrag von blbltheworm »

Hi,

danke für den Tipp mit dem Canvas(). Ich hab zwar noch PB 4.51, er hat mir dennoch weitergeholfen, da ich hier drüber gestolpert bin.
Die Lösung die ich jetzt verwende geht dann folgendermaßen (falls es jemand interessiert):

Zuerst eine GtkWidget zu Beginn definieren:

Code: Alles auswählen

*widget.GtkWidget
Und das Imagegadget wie folgt erzeugen:

Code: Alles auswählen

*widget = ImageGadget(1,50,125,300,200,ImageID(test))
Anstelle des SetGadgetState() kommt dann ein:

Code: Alles auswählen

gdk_draw_pixbuf_(*widget\window,*widget\style\fg_gc,ImageID(test),0,0,0,0,*widget\allocation\width,*widget\allocation\height,0,0,0)
Vielleicht hilft es ja jemandem weiter.
Antworten