[Erledigt] Cairo und CanvasGadget

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
E-P-S
Beiträge: 134
Registriert: 30.03.2007 09:39
Kontaktdaten:

[Erledigt] Cairo und CanvasGadget

Beitrag von E-P-S »

Hi zusammen,

ist es irgendwie möglich die CAIRO Funktionen gemeinsam mit einem CanvasGadget zu nutzen - also darauf zu zeichnen?

Im Cairo Beispiel wir der DC eines Fensters zum Zeichnen benutzt, was natürlich den Nachteil mit sich bringt das man dessen Events auswerten und bei einem WM_PAINT Ereignis den Inhalt erneuern muß. Das würde ich gerne umgehen und direkt in ein Canvas zeichnen, nur bekomme ich das überhaupt nicht hin.

Hat das schonmal jemand gemacht und könnte mir weiterhelfen?

Vielen Dank
Zuletzt geändert von E-P-S am 28.03.2013 01:33, insgesamt 1-mal geändert.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Cairo und CanvasGadget

Beitrag von ts-soft »

Keine Ahnung von Cairo, aber wenn Du dort den DC übergehen kannst, sollte dies hier helfen:

Code: Alles auswählen

hDC = StartDrawing(CanvasOutput(#canvas))
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
E-P-S
Beiträge: 134
Registriert: 30.03.2007 09:39
Kontaktdaten:

Re: Cairo und CanvasGadget

Beitrag von E-P-S »

Vielen Dank erstmal für die schnelle Antwort.

Nun ja, das ist so in etwa das Problem, denn man übergibt nicht direkt den DC, sondern aus dem DC wird ein Surface erstellt, welches wiederum dazu dient eine Cairo eigene "Struktur" anzulegen...

Beispiel:

Code: Alles auswählen

OpenWindow(1,10,10,600,620,"",#PB_Window_BorderLess)
  SetWindowColor(1,RGB(255,255,255))
  SetParent_(WindowID(1),WindowID(0))
  
  ; here you can create a surface for our cairo context
  ; in this Case it's the dc of our window 1, you can render
  ; in a gadget, window,  windowedscreen or a cairo surface.
  ; pdf , ps, png, svg files are supported too ;)
  
  su = cairo_win32_surface_create(GetDC_(WindowID(1))) 
  cr = cairo_create(su)
...
Das Problem ist das ich zwar mit deinem Code den DC bekomme, dieser aber bei jedem Aufruf anders ist, sprich - StartDrawing gibt jedesmal nen anderen Zeiger, Pointer was auch immer zurück. Somit stimmen auch SU und CR nicht mehr und müssen immer wieder neu erzeugt und/oder angelegt werden.

Prinzipiell geht das, ich finds nur irgendwie bescheuert und frage mich ob das nicht auch direkter geht.

Gibt es denn einen anderen Weg an den DC des Canvas Gadgets heranzukommen?
Derren
Beiträge: 558
Registriert: 23.07.2011 02:08

Re: Cairo und CanvasGadget

Beitrag von Derren »

Klappt das?

Code: Alles auswählen

su = cairo_win32_surface_create(GetDC_(GadgetID(#Canvas))) 
Ob damit dann aber nicht wieder direkt auf's Gadget gemalt wird, anstatt in den Puffer von PB (so habe ich das mit dem CanvasGadget und dem Vorteil gegenüber direkt aufs Fenster/ImageGadget malen verstanden), musst du mal testen.
Signatur und so
Benutzeravatar
E-P-S
Beiträge: 134
Registriert: 30.03.2007 09:39
Kontaktdaten:

Re: Cairo und CanvasGadget

Beitrag von E-P-S »

Klappt leider nicht.

Ich hab mal ein wenig in der Online Hilfe von Cairo geschmökert und - was ich vorher nicht wusste - es werden bei den beiden Funktionen lediglich Zeiger auf bestimmte Strukturen gesetzt, keine Images o.ä. angelegt (wie ich annahm).

Wie auch immer, mit dieser Erkenntnis hab ich mir dann zwei Prozeduren geschrieben die einfach vor und nach einer Cairo - Zeichenoperation aufgerufen werden. Sozusagen ein StartDrawing und StopDrawing Ersatz. Mit dieser Lösung kann ich durchaus leben.

Hier mal ein Codeschnipsel wie man das anwendet:

Code: Alles auswählen

XIncludeFile "cairo180.pbi"

Enumeration
  #Win
  #Canvas
EndEnumeration

;================================================================================
; Diese Prozedur ist vor jeder Cairo Zeichenoperation aufzurufen
;================================================================================
Procedure cairo_startdrawing( canvas )
  
  Protected su.i, cr.i
  su = cairo_win32_surface_create( StartDrawing( CanvasOutput( canvas ) ) )
  cr = cairo_create( su )
  cairo_surface_destroy( su ) 
  
  ProcedureReturn cr
  
EndProcedure

;================================================================================
; Diese Prozedur ist nach einer Cairo Zeichenoperation aufzurufen
;================================================================================
Procedure cairo_stopdrawing(cr)
  
  StopDrawing()
  cairo_destroy( cr )
  
EndProcedure

If OpenWindow( #Win, 0, 0, 800, 600, "Cairo-Canvas", #PB_Window_SystemMenu | #PB_Window_ScreenCentered )
  
  CanvasGadget( #canvas, 0, 0, 640, 480 )
  
  ;Zeichne was
  cr = cairo_startdrawing( #canvas )
  
    ;cls
    cairo_set_source_rgb (cr, 1, 1, 1)
    cairo_paint (cr)

    cairo_set_source_rgb (cr, 0, 0, 0) 
    
    cairo_move_to (cr, 128.0, 25.6)
    cairo_line_to (cr, 230.4, 230.4)
    cairo_rel_line_to (cr, -102.4, 0.0)
    cairo_curve_to (cr, 51.2, 230.4, 51.2, 128.0, 128.0, 128.0)
    cairo_close_path (cr)
    
    cairo_move_to (cr, 64.0, 25.6)
    cairo_rel_line_to (cr, 51.2, 51.2)
    cairo_rel_line_to (cr, -51.2, 51.2)
    cairo_rel_line_to (cr, -51.2, -51.2)
    cairo_close_path (cr)
    
    cairo_set_line_width (cr, 10.0)
    cairo_set_source_rgb (cr, 0, 0, 1)
    cairo_fill_preserve (cr)
    cairo_set_source_rgb (cr, 0, 0, 0)
    cairo_stroke (cr)
  cairo_stopdrawing(cr)
  
  ;Zeichne nochmal was
  cr = cairo_startdrawing( #canvas )
    cairo_set_source_rgb (cr, 1, 0, 0) 
    xc = 128.0
    yc = 128.0
    
    Dim tdashes.d(4) 
    tdashes(0) = 50
    tdashes(1) = 10.0
    tdashes(2) = 10.0
    tdashes(3) = 10.0
    ndash  = 4
    offset = -50.0
    cairo_set_dash (cr, @tdashes(0), ndash, offset);
    cairo_set_line_width (cr, 2.0)
    cairo_move_to (cr, 428.5, 25.5)
    cairo_line_to (cr, 228.5, 128.5)
    cairo_rel_line_to (cr, -102.4, 0.0)
    cairo_curve_to (cr, 51.2, 230.4, 51.2, 128.0, 128.0, 128.0)
    cairo_stroke (cr)
  cairo_StopDrawing(cr)

Repeat
    events = WaitWindowEvent()
    Select events
      Case #PB_Event_Gadget
        Select EventGadget()
        EndSelect
      Case #PB_Event_CloseWindow  
        quit = 1
    EndSelect 
    
  Until quit = 1
    
EndIf
Vielen Dank.
Zuletzt geändert von E-P-S am 28.03.2013 12:17, insgesamt 1-mal geändert.
Benutzeravatar
Dadido3
Beiträge: 119
Registriert: 24.02.2007 22:15
Kontaktdaten:

Re: [Erledigt] Cairo und CanvasGadget

Beitrag von Dadido3 »

Hallo,

Mal ne kleine Frage/Anmerkung zu dem Codeschnipsel:

Hab ich was übersehen, oder woher bekommt die Prozedur cairo_stopdrawing() die Variable cr?

Code: Alles auswählen

Procedure cairo_stopdrawing()
 
  StopDrawing()
  cairo_destroy( cr )
 
EndProcedure
Nicht dass sich leute, die den Code benutzen, sich später über Memoryleaks wundern ;)
Benutzeravatar
E-P-S
Beiträge: 134
Registriert: 30.03.2007 09:39
Kontaktdaten:

Re: [Erledigt] Cairo und CanvasGadget

Beitrag von E-P-S »

upps...da hast du recht - hab es korrigiert. THX
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: [Erledigt] Cairo und CanvasGadget

Beitrag von Danilo »

Aus einem alten Projekt:

Code: Alles auswählen

Procedure StartCanvasOutput(canvas)
  Shared CanvasOutput_hDC, CanvasOutput_su, CanvasOutput_cr
  CanvasOutput_hDC = StartDrawing( CanvasOutput( canvas ) )
  If CanvasOutput_hDC
    CanvasOutput_su = cairo_win32_surface_create(CanvasOutput_hDC)
    CanvasOutput_cr = cairo_create(CanvasOutput_su)
    ProcedureReturn CanvasOutput_cr
  EndIf
EndProcedure

Procedure StopCanvasOutput()
  Shared CanvasOutput_su, CanvasOutput_cr
  cairo_surface_destroy(CanvasOutput_su)
  cairo_destroy(CanvasOutput_cr)
  StopDrawing()
EndProcedure

Procedure StartSurfaceOutput(surface)
  ProcedureReturn cairo_create(surface)
EndProcedure

Procedure StopSurfaceOutput(cr)
  cairo_destroy(cr)
EndProcedure

Procedure Clear_cr_color(cr,r.f=1.0,g.f=1.0,b.f=1.0)
  cairo_set_source_rgb (cr, r, g, b)
  cairo_paint (cr)
EndProcedure

Procedure Clear_cr(cr)
  cairo_set_operator (cr, #CAIRO_OPERATOR_CLEAR)
  cairo_paint(cr)
EndProcedure
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Antworten