Seite 1 von 1
Sprite Problem
Verfasst: 07.07.2013 23:29
von Joel
Hey,
ich habe ein Thread, der so jede halbe Sekunde ein Bild bekommt, welches er dann Darstellt. Das ganze läuft im Vollbild.
1. Ist das glaube Codemäßig ziemlich schlecht umgesetzt

wäre für optimierungen Dankbar
2. Wenn ich das Fenster mit ESC schließe und dann später den Thread wieder öffne, dann schlägt OpenScreen fehl (0).
Hier der Code:
Code: Alles auswählen
Procedure Arbeit(*wertll)
If Arbeit_Init = 0
UseJPEGImageDecoder()
UseJPEG2000ImageDecoder()
InitSprite()
InitKeyboard()
Arbeit_Init = 5
EndIf
If OpenScreen(1280, 800, 16, "Sprite")
Repeat
If Neuer_Screenshot = 5
If IsSprite(1)
FreeSprite(1)
EndIf
LoadSprite(0, Tempdir$+"fm.jpg", 0)
CopySprite(0,1,0)
FreeSprite(0)
Neuer_Screenshot = 0
EndIf
FlipBuffers()
ClearScreen(RGB(0,0,0))
If IsSprite(1)
DisplaySprite(1, 0, 0)
EndIf
ExamineKeyboard()
Until Key() = #VK_ESCAPE
CloseScreen()
Else
MessageRequester("Error", "Can't open screen !", 0)
EndIf
EndProcedure
Re: Sprite Problem
Verfasst: 08.07.2013 04:21
von KeyKon
Ich finde der Code sieht in der Tat ziemlich gruselig aus^^
So auf die schnelle kann ich nur sagen, dass die Inits sicher nichts im Thread verloren haben.
Aber mir stellt sich die Frage, wieso machst du das in einem Thread, und was willst du überhaupt machen?
Re: Sprite Problem
Verfasst: 08.07.2013 10:12
von Joel
KeyKon hat geschrieben:Ich finde der Code sieht in der Tat ziemlich gruselig aus^^
So auf die schnelle kann ich nur sagen, dass die Inits sicher nichts im Thread verloren haben.
Aber mir stellt sich die Frage, wieso machst du das in einem Thread, und was willst du überhaupt machen?
Naja, das ist ein Sprite, weil die GUI Parallel noch laufen soll. Immer wenn "Nächster_Screenshot = 5" dann wird ein neues Bild geladen und der Wert auf 0 gesetzt. Wenn ESC gedrückt wird, dann wird der Screen geschlossen und der Thread beendet.
Wenn ich per GUI nun den Thread wieder starte, dann ist OpenScreen = 0 . Warum?
Re: Sprite Problem
Verfasst: 08.07.2013 13:27
von KeyKon
Also mein erster Gedanke war ja ein Init hat nix im Thread zu suchen, aber wie du sicher auch schon gemerkt hast funktioniert es garnicht wenn das Init im Main-Code ist.
Daher würde ich darauf tippen, dass das Init im entsprechenden Thread aufgerufen werden muss damit es funktioniert, da Init aber wiederum nicht mehrfach aufgerufen werden darf, musst du diesen einen Thread eben ewig am Leben halten, egal ob der Screen offen ist oder nicht, das funktioniert bei mir beim Testen auch.
Dennoch kann ich nur nochmal erwähnen das ich nicht verstehe warum du das so machst, ich glaube das ist sehr schlechter Stil (wie du ja auch schon selbst gemerkt hast^^)
Meiner Meinung nach ist der Screen dafür da das HauptGUI und damit auch keinen Thread darzustellen, daher würde ich zum einfachen Anzeigen von Bildern ein weiteres Fenster nehmen, das kann man ja auch "Fullscreen" machen indem man BorderLess benutzt und es auf Screengröße aufzieht.
Um deine Gedankengänge evtl. besser zu verstehen wäre im übrigen auch der Hintergrund des Programmteils ganz interessant^^ (Also wozu genau das Programm da ist...)
LG KeyKon
Re: Sprite Problem
Verfasst: 08.07.2013 13:46
von Joel
Das ist ein Programm, das Screenshots darstellt. Es kommen ca. jede Sekunde ein Screenshot an, der dann direkt aktualisiert wird.
Es gibt einmal das Hauptfenster (1) und wenn ich dort auf einen Button drücke werden die Screenshots angezeigt. Wenn ich nun auf ESC drücke, schließt sich der Screen (Thread wird auch beendet) und ich sehe wieder die GUI. Leider kann ich den Thread dann wie gesagt nicht wieder starten.
Bei neuem Screenshot wird eine Variable auf 5 gesetzt. siehe If abfrage...
Kann man das vllt anders besser machen?
Edit: Habe den Code oben etwas bereinigt...
Re: Sprite Problem
Verfasst: 08.07.2013 14:18
von NicTheQuick
Du brauchst gar kein Screen. Du musst wie KeyKon schon sagte nur ein zweites Fenster öffnen anstatt des Screens und das dann so vergrößern, dass es auf dem ganzen Bildschirm angezeigt wird. Dann brauchst du sogar nur deine eine Eventschleife und noch nicht mal einen extra Thread. Den hättest du in deiner Screen-Version übrigens auch nicht gebraucht.

Re: Sprite Problem
Verfasst: 08.07.2013 14:49
von Joel
NicTheQuick hat geschrieben:Du brauchst gar kein Screen. Du musst wie KeyKon schon sagte nur ein zweites Fenster öffnen anstatt des Screens und das dann so vergrößern, dass es auf dem ganzen Bildschirm angezeigt wird. Dann brauchst du sogar nur deine eine Eventschleife und noch nicht mal einen extra Thread. Den hättest du in deiner Screen-Version übrigens auch nicht gebraucht.

Gute Idee, aber jetzt habe ich das Problem, das die Anzeige kurzzeitig immer weiß ist (siehe Code) also der Austausch der Bilder ist nicht mehr flüssig und daher is immer für ganz kurze Zeit wieder der weiße Hintergrund zu sehen, was nicht wirklich schon aussieht.
Hier der Codeteil, in dem das Image aktualisiert wird:
Code: Alles auswählen
If Neuer_Screenshot = 5
If IsImage(0)
FreeImage(0)
EndIf
LoadImage(0, Tempdir$+"fm.jpg")
ImageGadget(1, 0, 0, 1280, 800, ImageID(0) , 0)
Neuer_Screenshot = 0
EndIf
Re: Sprite Problem
Verfasst: 08.07.2013 15:00
von KeyKon
Du darfst halt keine Pause beim Anzeigen machen während du das neue Bild lädst:
Code: Alles auswählen
If Neuer_Screenshot = 5
oldImageIDFullscreen = imageIDFullscreen
imageIDFullscreen = LoadImage(#PB_Any,imagePathFullscreen)
If imageIDFullscreen <> 0
SetGadgetState(gadgetImage,ImageID(imageIDFullscreen))
EndIf
If IsImage(oldImageIDFullscreen)
FreeImage(oldImageIDFullscreen)
EndIf
Neuer_Screenshot = 0
EndIf
Daher erst das alte Bild frei machen wenn das neue schon angezeigt wird.
Wenn du natürlich eine flüssige 60fps Darstellung machen willst kommste so nicht unbedingt weit, das kam aber vorhin noch nicht so aus deinem Post raus^^
Im zweifel muss dann doch ein Screen her, aber ich würde dann eben einen WindowedScreen in meine Main-Loop einbauen...
LG KeyKon
Re: Sprite Problem
Verfasst: 08.07.2013 15:33
von NicTheQuick
Oder man kann dafür auch das CanvasGadget nutzen und dort ganz einfach ein Image drauf zeichnen. Das CanvasGadget unterstützt zudem noch viele Events und nutzt DoubleBuffering.