|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 21.03.2010, 19:19 Titel: X11.bi - FB-Imagebuffer darstellen |
|
|
hat jemand eine idee, wie es schneller gehen könnte einen Freebasic-Imagebuffer in einem X11-Fenster zu zeichnen?
bisher sieht das bei mir so aus:
( man benötigt die X11.bi von http://www.alice-dsl.net/d.j.peters/libs/X11.bi )
Code: |
'test02.bas
#include "X11.bi"
#ifndef true
#define true (1<>0)
#endif
#ifndef false
#define false (1<>1)
#endif
#ifndef boolean
#define boolean integer
#endif
'creates graphic context GCs by diffrent colors
Function create_foreground_gc(Byval display As DISPLAY Ptr, _
Byval win As WindowID, _
Byval strRGB As String) As GContext
Dim As XCOLOR col,nearest
Dim As XGCValues gcv
XAllocNamedColor(display,XDefaultColormap(display,XDefaultScreen(display)), _
strRGB,@col, nearest)
gcv.foreground =col.pixel
Return XCreateGC(display,win, GCForeground,gcv)
End Function
Dim As Display Ptr display
Dim As WindowID win
Dim As XSetWindowAttributes setattributes
Dim As GContext red_gc,blue_gc,green_gc
Dim As XEvent report
Dim As ATOM wm_delete
Dim As Boolean blnExit
Dim As Integer screen_num,win_width,win_height
screen 16,32
cls
dim bild as any ptr = imagecreate(400,400,RGB(0,255,0))
line bild, (0,0)-(399,399),RGB(255,0,0),B
line bild, (0,0)-(399,399),RGB(0,0,255)
'open X connection
display = XOpenDisplay()
'use macros
screen_num =DefaultScreen(display)
win_width =DisplayWidth(display,screen_num)
win_height =DisplayHeight(display,screen_num)
setattributes.background_pixel = WhitePixel(display,screen_num)
'create window (last examples it was XCreateSimpleWindow)
win = XCreateWindow(display,RootWindow(display,screen_num), _
0, 0, win_width,win_height, 1, _
DefaultDepth (display,screen_num),InputOutput, _
DefaultVisual(display,screen_num),CWBackPixel, setattributes)
'tell X what for events
XSelectInput(display,win,ClientMessage Or StructureNotifyMask Or ExposuRemask or KeyPressMask or PointerMotionMask) ' or ResizeRedirectMask
'We need the close event from Windowmanager
wm_delete = XInternAtom(display,"WM_DELETE_WINDOW",False)
'register it
XSetWMProtocols(display,win,wm_delete,1)
'three diffrent GC
red_gc =Create_Foreground_GC(display,win,"rgb:ff/00/00")
green_gc=Create_Foreground_GC(display,win,"rgb:00/ff/00")
blue_gc =Create_Foreground_GC(display,win,"rgb:00/00/ff")
'clear and flush the buffer
XFlush (display)
'show the window
XMapWindow(display,win)
'draw a little bit
XDrawLine (display,win,red_gc , 0, 0, 320,199)
XDrawLine (display,win,green_gc,100, 0, 0,199)
XDrawString(display,win,blue_gc ,80,100,"hello",5)
dim c as GContext
dim bildpixel as uinteger
dim ppointer as ubyte ptr
dim rot as ubyte
dim gruen as ubyte
dim blau as ubyte
for x as integer = 0 to 399
for y as integer = 0 to 399
bildpixel = point(x,y,bild)
ppointer = cast(ubyte ptr, @bildpixel)
rot = ppointer[0]
gruen = ppointer[1]
blau = ppointer[2]
c = Create_Foreground_GC(display,win,"rgb:" & hex(rot) & "/" & hex(gruen) & "/" & hex(blau))
XDrawPoint(display, win, c, x,y)
next
next
'update all
XFlush (display)
'our message loop
While blnExit = false
'wait on next event
XNextEvent(display,report)
'what was it
Select Case (report.eventtype)
'an key to exit (only if any makes trouble)
Case KeyPress
Print "KeyPress"
'blnExit=True
Case KeyRelease
Print "KeyRelease"
Case ButtonPress
Print "ButtonPress"
Case ButtonRelease
Print "Button Release"
Case MotionNotify
'print "MotionNotify"
'switch between the colors / GC's
Swap red_gc,green_gc:Swap green_gc,blue_gc
XDrawArc(display,win,red_gc,report.xmotion.x-5,report.xmotion.y-5,10,10,0,360*64)
Case EnterNotify
Print "EnterNotify"
Case LeaveNotify
Print "LeaveNotify"
Case FocusIn
Print "FocusIn"
Case FocusOut
Print "FocusOut"
Case KeymapNotify
Print "KeymapNotify"
Case Expose
Print "Expose";report.XExpose.count
If report.XExpose.count=0 Then
XClearWindow(display,win)
win_width =report.xexpose.Width
win_height=report.xexpose.Height
XDrawLine (display,win,red_gc ,0, 0,win_width,win_height )
XDrawLine (display,win,green_gc,0,win_height\2,win_width,win_height\2)
XDrawString(display,win,blue_gc ,win_width\2-40,win_height\2,"hello",5)
XDrawArc (display,win,blue_gc ,win_width\2-50,win_height\2-50,100,100,0,180*64)
for x as integer = 0 to 399
for y as integer = 0 to 399
bildpixel = point(x,y,bild)
ppointer = cast(ubyte ptr, @bildpixel)
rot = ppointer[0]
gruen = ppointer[1]
blau = ppointer[2]
c = Create_Foreground_GC(display,win,"rgb:" & hex(rot) & "/" & hex(gruen) & "/" & hex(blau))
XDrawPoint(display, win, c, x,y)
next
next
End If
Case GraphicsExpose
Print "GraphicsExpose"
Case NoExpose
Print "Noxpose"
Case VisibilityNotify
Print "VisibiltyNotify"
Case CreateNotify
Print "CreateNotify"
Case DestroyNotify
Print "DestroyNotify"
Case UnmapNotify
Print "UnmapNotify"
Case MapNotify
Print "MapNotify"
Case MapRequest
Print "MapRequest"
Case ReparentNotify
Print "ReparentNotify"
Case ConfigureNotify
Print "ConfigureNotify"
Case ConfigureRequest
Print "ConfigureRequest"
win_width =report.XConfigure.Width
win_height=report.XConfigure.Height
Case GravityNotify
Print "GravityNotify"
Case ResizeRequest
Print "ResizeRequest"
Case CirculateNotify
Print "CirculateNotify"
Case CirculateRequest
Print "CirculateRequest"
Case PropertyNotify
Print "PropertyNotify"
Case SelectionClear
Print "SelectionClear"
Case SelectionRequest
Print "SelectionRequest"
Case SelectionNotify
Print "SelectionNotify"
Case ColormapNotify
Print "ColormapNotify"
'Our registered clientmessage from windowmanager
Case ClientMessage
Print "ClientMessage"
If report.xclient.l(0)=wm_delete Then blnExit=True
Case MappingNotify
Print "MappingNotify"
Case Else
Print "!!! OTHER !!!"
End Select
Wend
'free all resources
XFreeGC(display,red_gc)
XFreeGC(display,green_gc)
XFreeGC(display,blue_gc)
XDestroyWindow(display,win)
'close connection
XCloseDisplay(display)
'thats all for now ;-)
End
|
mein beispiel funktioniert absolut indiskutabel schlecht.. aber ich bekomm das leider nicht besser hin ( .. kann man mit XPutImage irgendwie einen Freebasic-buffer ausgeben? (http://tronche.com/gui/x/xlib/graphics/XPutImage.html)
Und wenn das nicht schon genug wäre, ich verstehe diese api einfach nicht.. was sind GCs? Also GraphicContexts?? Definiert man damit die Farbe oder wie oder was? Eigentlich kann ich englisch einigermaßen, aber das manual der api ist mir echt ein graus..
übrigens sind irgendwie 2 versionen von der X11.bi auf meinem computer gelandet. Bei der einen sind die bool-ausdrücke bereits definiert, in der anderen nicht. .. vielleicht weiss einer wo man die aktuellste version bekommt..
vielen dank schon mal!! |
|
Nach oben |
|
|
micha
Anmeldungsdatum: 09.12.2005 Beiträge: 72
|
Verfasst am: 21.03.2010, 23:05 Titel: |
|
|
So einfach wie Du vermutest ist es aber nicht.
Sicherlich kannst Du RGB Pixel von FreeBASIC in einem X11 image schreiben und zeichnen.
!!! ABER !!!
XImages sind immer in dem Format des Visuals des X Desktops
das kann z.B. RGB oder RGBA sein in verschiedenen bits per pixel also
8,8,8 oder 8,8,8,8 oder 5,5,5 oder 5,6,5 oder 5,5,6 sogar 12,12,12 oder 16,16,8 sind möglich
Daher braucht GTK/QT und FreeBASIC einen einen Konverter/Blitter.
Selbst wenn Du genau weist das Dein aktueller Deskop 24Bit 8:8:8 benutzt
dann wird Dein Programm auf einen Rechner mit 5:6:5 sehr schlecht aussehen
und vermutlich abstürzen weil der 8:8:8 Pixelbuffer größer ist als ein 5:6:5 und übers Ziel hinaus schießen würde.
Einfacher Du nimmst gdk_draw_rgb_image dann brauchst Du dich
nicht um das Konvertieren mehr kümmern.
Probier mal das Beispiel "gdk_image.bas"
zu finden unter freebasic/examples/libraries/Gtk
Wenn Du das Beispiel verstanden hast dann kannst Du auch
FB Images als GDK RGB buffer Zeichnen.
Micha |
|
Nach oben |
|
|
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 22.03.2010, 08:40 Titel: |
|
|
@micha: WOW! Das ist eine selten fundierte Antwort .. das bin ich ja fast gar nicht gewöhnt XD ..
Erstmal auch vielen vielen dank für deine antwort!! .. hm, ok, das dies so schwierig sein könnte hab ich nicht gedacht.
Das beispiel gdk_draw_rgb_image könnte mir tatsächlich weiterhelfen.. meine erste versuche in der richtung habe ich auch mit gtk versucht, war aber kläglich gescheitert XD ..
noch eine frage, wo ist der unterschied zwischen gdk und gtk? |
|
Nach oben |
|
|
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 22.03.2010, 10:11 Titel: |
|
|
@micha: so ein mist.. jetzt steh ich vor nem anderen problem .. die funktion gdk_draw_rgb_image nimmt nur 24-bittige images entgegen. Die Freebasic-buffer sind aber mit alpha kanal, also in 32-bit farbtiefe .. deswegen kann ich die speicherbereiche nicht direkt in einem stück kopieren
kann man das irgendwie mit gdk_draw_rgb_image_dithalign bewerkstelligen?
die referenz http://library.gnome.org/devel/gdk/stable/gdk-GdkRGB.html#gdk-draw-rgb-image-dithalign sagt mir leider nicht viel
der weg gefällt mir aber ansonsten sehr gut!! |
|
Nach oben |
|
|
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
Verfasst am: 22.03.2010, 13:54 Titel: |
|
|
gdk_draw_rgb_32_image()
Das ignoriert den Alphakanal einfach (Padding) |
|
Nach oben |
|
|
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 23.03.2010, 00:16 Titel: |
|
|
KRASS!! VIELEN DANK!! DAS FUNKTIONIERT
Aber weils so viel spaß macht:
ich möchte maus und tastaturevents von drawingarea-widget empfangen. ich weiss aber nicht, wie diese events heissen.
hab in einer referenz zur drawingarea folgendes gefunden:
Mouse and button press signals to respond to input from the user. Use the gtk.Widget.add_events() method to enable events you wish to receive. To receive keyboard events, you will need to set the gtk.CAN_FOCUS flag on the drawing area
(http://www.pygtk.org/docs/pygtk/class-gtkdrawingarea.html)
wie funktioniert diese widget.add_events()-methode? aus der beschreibung werd ich irgendwie nich schlau.. eigentlich bin ich nicht sonderlich begriffstutzig, aber aus englischen referenzen werd ich schnell nich schlau ( |
|
Nach oben |
|
|
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 23.03.2010, 00:34 Titel: |
|
|
hm.. ich glaub ich habs schon ..
mit gtk_widget_add_events(drawarea, GDK_BUTTON_PRESS_MASK) hats geklappt nun reagiert das drawingarea-widget auf "mouse_press_event" |
|
Nach oben |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
|
Nach oben |
|
|
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 12.04.2011, 10:09 Titel: |
|
|
SEHR GEIL!
Vielen vielen dank! Danach hab ich echt lange gesucht!!!!! |
|
Nach oben |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 12.04.2011, 14:36 Titel: |
|
|
kein ding.
du kannst übrigens auch in das XImage direkt schreiben.
Wenn du keine Threads nutzt, sollte das sogar ohne "crash" funzen.
du Musst dazu allerdings etwas tricksen.
Du Erzeugst erst n nofmrales FB.Image, und mit diesem ein XImage.
Anschliessend deallocst du den Datenebreich vom FB.Image und castest per PTR den Datenspeicher des XImage an das FB.Image.
Dann solltest du (sofern screen noch aktiv ist, und nicht "screen 0") ausgeführt wurde, mit Line, PSet, usw. auf das FB.Image zugreifen können, es manipulieren, und mit XPutImage und dem XImage die daten direkt auf das XDisplay schreiben können, ohne nochmal den Header via XCreateImage zu erzeugen.
Is allerdings ne heiße geschichte
Eventuell kannst du auch direkt drauf casten. müsst ich aber erst ma nachlesen, ob das funzen könnte.
leider kann man LINE, PSET, usw. nicht ohne einen aktiven screen benutzen.
alternativ kann ich dir aber seperate funktionen anbieten, die das problem umgehen.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
|
MilkFreeze
Anmeldungsdatum: 22.04.2011 Beiträge: 116
|
Verfasst am: 22.04.2011, 17:05 Titel: |
|
|
Code: | screenres 800,600,32,, GFX_NULL |
Screen-Modus ohne visuelles Feedback. Für "GFX_NULL" geht auch ein simples "-1". Damit funktioniert ThePuppetMasters tipp auch ohne überflüssiges FBGFX-Fenster.
Ich hoffe ich konnte helfen. |
|
Nach oben |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 22.04.2011, 17:11 Titel: |
|
|
hab jetzt nochma nachgesehen. ist so, das xcreateimage keinen datenspeicher für das eigentliche bild erzeugt, sondern selbst auf den bereits mit imagecreate erzeugten datenspeicher castet.
du kansnt also direkt schreiben, ohne den header neu erstellen zu müssen. oder daten zu kopieren.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
|
micha
Anmeldungsdatum: 09.12.2005 Beiträge: 72
|
Verfasst am: 18.07.2011, 23:25 Titel: |
|
|
nur für leute den diesen thread hier später nochmals lesen und den falschen eindruck erhalten es sei doch ganz einfach ein fb image mit der xlib darzustellen.
das dieses nicht so einfach ist hatte ich ja geschrieben
(und gehoft es wäre auch verständlich)
wenn der x server ein anderes format hat als die fb gfx lib
dann kann das nicht gehen.
pixmap's und ximages werden nie automatisch in das passende x server format konvertiert.
(das ist ja der grund warum die fb gfx lib so einen aufwändigen blitter hat)
es gibt nur zwei funktionen die einem die RGB nach x server konvertierung abnimmt und zwar bei ximage xgetpixel und xsetpixel.
es sollte klar sein das ein kopieren vom fb gfx buffer pixel bei pixel viel zu langsam ist.
nochmals zum mitschreiben wen der x server mit 15 oder 16 bit rgb läuft so 5:5:5 oder auch so 5:6:5 dann werden die farben vom 24 8:8.8 bzw. 32 bit 8:8:8:8 eines fb image falsch dargestellt.
das es bei euren experimenten mal klapt liegt nur daran weil dann ein fb image und der x server "zufällig" das gleiche format benutzen.
wär es nicht glauben mag einfach die x session beenden an der console als root in der xorg.conf die bitauflöung z.b auf 16 bit einstellen.
neue x session starten und schauen wie dann das gleiche fb image plötzlich aussieht.
micha
(nicht mit pc geposted daher keine großbuchstaben) |
|
Nach oben |
|
|
ThePuppetMaster
Anmeldungsdatum: 18.02.2007 Beiträge: 1837 Wohnort: [JN58JR]
|
Verfasst am: 19.07.2011, 00:22 Titel: |
|
|
naja... so wie es in der xlib steht, ist xcreateimage eine art "schablone" welche erzeugt wird, um aus unterschiedlichen Formaten auf das derzeit gültige Format auf dem xserver zu casten.
siehe: XCreateImage in der xlib beschreibung.
sprich, wenn man der struktur mitteilt, welches format man verwendet, kann man entsprechend einfach alles auf den xserver casten.
direkt drauf schreiben geht natürlich nicht.
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ]
Zuletzt bearbeitet von ThePuppetMaster am 19.07.2011, 08:29, insgesamt 2-mal bearbeitet |
|
Nach oben |
|
|
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 19.07.2011, 07:40 Titel: |
|
|
@Micha: Heutzutage kann man doch davon ausgehen, dass keiner mehr nen X-Server als Desktop verwendet der eine Farbtiefe < 32bit hat .. und wenn mal ein abgesicherter modus läuft wo eine tiefere Farbtiefe läuft, dann hat man eben pech .. dann läuft das programm bei der farbtiefe nicht.
Evtl könnte man ja vor dem eigentlichen Programm auch die aktuelle farbtiefe abfrage und wenn sie < 32bit ist, dann soll das programm erst gar nicht laufen...
@TPM: Habs leider noch gar nicht versucht, kam leider noch nicht dazu ( |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|