Diashow per Multiprozessing - Bilder im Hintergrund nachladen

  • Hallo xProfan-Fans!


    Ich habe ein Problem an dem ich langsam verzweifle. Ich möchte eine Diashow für meine Freundin zum Geburtstag programmieren. Das funktioniert soweit auch ganz gut. Zumindest bis zum Nachladen meiner Bilddaten.
    Ich Starte das Programm und lasse über eine Prozedur namens "LOAD meine Bilder nachladen. Die verschiedenen Verzeichnisse in denen sich die Bilder befinden, werden als Parameter, 1,2,3, etc. übergeben.
    Die Dateinamen werden in ein ListBoxItem& eingelesen und ein das Object


    "bild& = Create("hsizedPic",-1, Datei$,1280,1024,1)"


    und dann an ein Array


    "texture%[i% + 1] = oGL("getTextureBMP",bild&,1)"



    übergeben. Während des Einlesens stellt das Hauptbrogramm sämtliche oGL-Animationen ein bis alle Bilder im Speicher gelandet sind und setzt dann seine Arbeit fort. Das ist aber nicht gewünscht. Habe den Tipp bekommen die Bilder im Hintergrund als eigenen Prozess zu laden. Also pExec und die Proc aufgerufen. Doch dann hagelt es Fehler bei den Variablendeklarationen die ja global deklariert waren. Ändere ich das ab, scheitert es am Textur-Array und der OpenGL-Init-Geschichte. Diese kann ich im Prozess nicht Initialisieren.



    Ich poste gerne meinen kompletten Code aber es scheint mir hier ein generelles Verständniss-Problem zu sein. Deshalb die allgemeine Frage, wie Lade ich meine Bilddateien während der Laufzeit nach ohne das sämtliche Animationen anhalten. Es soll ja flüssig laufen. Deshalb wäre ein Ansatz sinnvoll, den nächsten Bildersatz schon nachzuladen, während die Diashow noch läuft.



    Hat jemand eine Idee wie ich das hinbekommen kann?


    Der Geburtstag ist noch 5Monate entfernt aber für die Party für meinen Schatz möchte ich das schon auf die Fünf Beamer schmeißen und für die vielen Gästen in der gemieteten Industriehalle hinbekommen ohne das die - teilweise erfahrenen Computergäste aus den 80'ern an die langen Ladezeiten einer C64-Datasette erinnert werden :lol:


    Also, wenn jemand eine Idee dazu hat oder vor einem ähnlichen Problem gestanden hat, wäre ich um Hilfe wirklich sehr dankbar.

  • Hallo AHT,


    das habe ich schon ausprobiert und das Ergebnis ist das Gleiche in grün. Es ist ja auch keine normale Diashow wo ich die 5 Sekunden Anzeige des Bildes als Nachladezeit nutzen könnte.
    Die oGL-Sequenz sieht aus wie, sagen wir mal ein Demo aus den frühen 90'ern aus Amiga-Zeiten. Oben und unten je eine Laufschrift. Zwischen den Laufschriften werden zwei Bilder eingeblendet - leicht schräg zueinander dargestellt.
    Diese Bilder stehen nicht still. Sie bewegen sich wie zwei Laubblätter im Wind in Form zweier minimalen Lissajouss-Figuren.
    Lade ich selbst nur ein einziges Bild, halten die Laufschriften an und die Bewegungen der Bilder stoppen dann auch ganz kurz. Es läuft also nicht flüssig. Das ist richtig nervig.


    Deshalb die Idee des Nachladens als eigenen Prozess. Aber wie?


    Oder einen anderen Lösungsansatz der den gewünschten Erfolg bringen könnte. In Visual Basic konnte man ja mehrere Timer benutzen. Doch klappt auch das in xProfran nicht so wirklich gut weil der Erfolg auch damit ausbleibt.


    Interessant wäre ja, so meine Vorstellung die Bilder als eigenen Prozess in den Speicher schieben und dann quasi mit Pointern auf den Speicher zugreifen um sie dann dem oGL TextureBMP direkt anzusprechen. Aber dazu habe ich keine Infos gefunden und ..... würde das überhaupt funktionieren?

  • Die einfachste Möglichkeit wäre doch, die ganzen Bilder bei Programmstart
    zu laden, nötigenfalls in ein num. Array, das die Bitmap-Handles enthält.
    Nachteil : Es dauert ein wenig beim Start des Programms.


    Wichtig ist, wenn du in einem Prozess (pExec) die Bilder nachlädst, das
    Bitmaphandle mit pExec mitzugeben. Oder auch halt ein Array mit Bitmap-
    handles. So hatte ich auch schonmal eine Gridbox in meinem Hauptprogramm
    bedient. Um das alles etwas flüssig zu halten, würde ich im Hauptprogramm
    beim Start möglichst viel initialisieren.


    Da man ja nicht weiß, wie lange ein Prozess nachlädt, bzw. wie lange die
    DemoShow im Hauptprogramm läuft, könnte der Prozess das Hauptprogramm
    informieren, wenn es fertig ist. Dieses killt dann den Prozess.


    Machen kann man das schön mit den UserMessages und SendMessage.
    Es ist darauf zu achten, daß das Handle des Hauptfensters (%HWnd) oder
    eines, das mit Create() erzeugt wurde, dem Prozess mitzugeben.


    Ein einfaches Beispiel wäre das hier :

    Hier werden einfach alle Sekunde 10 Zeilen mit Zufallswerten geschickt.
    Wie man sieht, kann man da auch noch die 2 zus. Parameter von Sendmessage
    bestücken und auswerten.


    Vielleicht hilft dir das Beispiel ein wenig.


    PS : Was die OGL - Geschichte betrifft :
    Bin zwar nicht so der Fachmann dafür, aber OGL("Init",.....) erwartet ja zur Initialisierung
    ein Fenster. Wenn man aber jetzt in einem Prozess kein Fenster anzeigen will, kann man
    ja auch ein Fenster mit Null-Koordinaten erstellen, das als Handle dient. Das Fenster ist
    zwar dann da, ist aber wegen der 0 - Koordinaten nicht sichtbar. Oder auch ein ShowWindow
    könnte da helfen.
    Insofern müßte das OGL auch in einem Prozess funktionieren.

    Einmal editiert, zuletzt von H.Brill ()

  • Hab auch mal etwas mit OGL rumgespielt. Ich habe hier der Einfachheit eine Laufschrift genommen und
    den Code in 2 unterschiedliche Procs kopiert. Das könntest du dann mit deinen Intros so machen.

    Wie man sieht, muß man OGL für jeden Prozess neu initialisieren. Wahrscheinlich startet Roland
    bei pExec je eine Instanz vom Interpreter bzw. Profrun32. Man könnte sich das so vorstellen, als
    wenn man ein Programm mit Parametern startet. Daher weiß die mit pExec auferufene Proc nichts
    von der Initialisierung im Hauptprogramm. Genauso, als wenn man eine DLL-Funktion aufrufen würde.
    Diese würde auch nichts darüber wissen.

  • Hallo Fans,


    Erstmal Vielen Dank für die ausführlichen Infos.


    Das mit dem Unsichtbaren Fenster und die Initialisierung von oGL für jeden Prozess wird wohl das Problem gewesen sein.
    Werde das am Wochenende gleich mal ausprobieren und entsprechend ins Programm einbauen. Das eröffnet auch neue
    Möglichkeiten. Während die Bilder Nachladen, kann ich, weil ja eigene Prozesse werkeln, eine andere Animation starten
    bis die Bilder geladen sind und dann mit der Show fortfahren. Sobald das Progamm nach meinen Vorstellungen zufriedenstellend
    läuft, stelle ich den Code mal hier vor. Die Hilfe von euch soll ja auch nicht ohne Gegenleistung sein :) . Jetzt muss ich aber erst auf
    meine nächsten freien Tage warten um damit weiter zu machen.


    In diesem sinne nochmals Vielen Dank für die wertvollen Tipps.

  • Hallo H.Brill!


    Habe Deinen Code mal für meine Zwecke angepasst und einen dritten Prozess hinzugfügt, Mehr sollten es auch nicht werden.
    Dabei ist mir aber aufgefallen, das meine Diashow nun nach einigen Durchläufen immer langsamer wird und den Rechner schließlich lahm legt.
    Habe meinen Prozess wieder entfernt und das Ganze nur mit den Laufschriften mal so 10min laufen lassen. Das Gleiche Problem.
    Das Einzige was ich geändert habe ist die Fenstergröße auf Vollbild.
    Habe mit dem Code etwas gespielt aber es ändert sich nichts. Nach einiger Zeit hängt alles.
    Hast Du eine Ahnung woran das liegt?


    Auf jeden Fall ist mein Problem mit dem Nachladen nun Vergangenheit. Aber wie das im Leben so ist, wirft es manchmal neue Probleme auf.


    Bräuchte da nochmal Hilfe.


    Gruß aus Castrop-Rauxel

  • Hört sich nach einem Speicherleck an.
    Werden alle offenen und nicht mehr benötigten Handles wieder geschlossen?
    Werden nicht mehr benötigte Speicherbereiche wieder freigegeben?

  • Hallo H.Brill!


    Speicherleck?


    Was habe ich denn da vergessen, hmmh.


    Könnt ih mal drüber schauen? Habe hier mal eine meiner Prozeduren die als eigener Task laufen sollen angehängt.
    Die zweite Proc ist identisch. Nur an einer anderen Stelle des Bildschirmes.
    Aufgerufen mit P1& = pExec("|DrawGLScene1", %HWnd)


    Wo liegt da mein Fehler?


    proc DrawGLScene1
    Parameters Hwin&
    Declare TopText$
    Declare pos!, font&, hfont&, rot!, st&, e&

    st& = Create("Static", HWin&, %WinLeft , %WinTop , Width(HWin&, 0), 50)
    oGL("Init", st&, 0, 0, 0, 0)
    hfont& = create("Font", "Courier New", 48, 0, 1, 10, 0)
    font& = oGL("OutlineFont", hfont&, 0.002)
    TopText$ = "Hie mal eine Lorem Ipsum Lauftext etc, blabla"
    deleteobject hfont&


    pos! = 20
    e& = 0


    WhileNot e&
    Case pos! <= -100 : pos! = 20'Text wieder nach rechts
    pos! = pos! - 0.05


    oGL("Clear")
    oGL("Origin", pos!, 0, -1)
    oGL("Color", cos(rot!/20), sin(rot!/25), 1 - 0.5*cos(rot!/17), 1)
    oGL("Move", 0, -0.2, 0)
    oGl("push")
    oGL("Print", font&, TopText$)
    oGl("pop")


    Case rot! = 179 : rot! = 1
    rot! = rot! + 0.5


    oGL("Show")


    If getText$(HWin&) = ""
    OGL("Done")
    e& = 1
    EndIf


    EndWhile
    endproc

  • Hallo Leute,


    das mit dem Speicherleck tritt offenbar bei mir auch auf. Sämtliche Versuche die ich angestrebt habe, scheitern. Offenbar läuft der Grafikspeicher voll und es reagiert nichts mehr. Die einzige Version die nach meinen Vorstellungen läuft ist diese hier.
    Allerdings habe ich das Problem das die Bilder, die nachgeladen werden sollen, mein Programm solange lahm legt, bis alle Bilder geladen sind. Dummerweise hängt die Laufschrift auch für kurze Zeit wenn ich nur zwei Bilder nacheinander lade.
    Wer hat jetzt eine Idee, wie ich die Bilddaten ruckelfrei in die Texturfenster bekomme ohne das mein Programm hängt?


  • Mal gegengefragt :
    Muß es denn unbedingt mit OGL sein ?
    XProfan wäre wahrscheinlich etwas zu langsam für dein Vorhaben.


    Aber es gibt ja noch DLLs, die ähnliches leisten.
    Schau mal, ob du noch die Prospeed.dll findest. Die hat Frank (siehe obiger Post von ihm)
    mit Assembler geschrieben. Die arbeitet auch mit Sprites ähnlich wie
    Texturen.


    Vielleicht ist ja was für dich dabei.


    PS: Wenn du sie nicht mehr findest, mail an mich : H.Brill@t-online.de
    Die hab ich noch auf USB-Platte.

    Einmal editiert, zuletzt von H.Brill ()

  • Die oGL-Anwendung von Kollegen Tango funktioniert aber in 3D, und die 30 Bilder tanzen aus dem Hintergrund in den Vordergrund und wieder zurück, spielen Ringelreihen etc. Ich habe Vergleichbares noch nie gesehen ausser im TV, erzeugt mit sündteuren visuellen Spezialcomputern. Ein sehr anspruchsvolles Projekt mit professionellen Zügen. Kann das die ProSpeed.dll ?


    Auf Profan.net scheint ein Vorschlag das Speicherleck-Problem zu lösen. Allerdings nicht das langsame Laden bzw. die dadurch verursachten hakeligen Tänze der Bilder. Eine Lösungsvariante wäre vielleicht, die Tatsache zu nutzen, daß heute Mehrprozessor-Systeme mit dedizierten Aufgaben versehen werden können. Das ist nicht ganz leicht, da in XProfan die Sache mit dem Threading nicht besonders sicher ist. Dennoch können die einzelnen Prozessoren als "Preferred" angesprochen werden:


    AHT hatte mal einige Tricks dazu gepostet.
    (Hier auch die API dazu).
    Gruss


    P.S.: Welcome back, Frank! Irgendwie habe ich das Gefühl, du warst nie wirklich weg...

    HP255G7:Win10pro2.004,4*AMD Ryzen3200U@2.60GHz,6+2GB-RadeonVega/237GBSSD:intlDVDRW,3xUSB3 ext4TB-HDX,XProfanX3+Xasm/Xpse

    5 Mal editiert, zuletzt von p. specht ()

  • Hallpo Leute!


    Danke für die Tipps und die Anerkennung :)
    Den Tipp mit der ProSpeed-Geschichte schaue ich mir natürlich an. Möglicherweise lassen sich damit die Abläufe ja noch beschleunigen. Besonders das Thema "Sprites" kommt noch auf mich zu.


    Ich habe es soweit in den Griff bekommen und die ganze Sache ein wenig verfeinert. Um das Problem mit dem Nachladen der Bilder und die damit verbundene Wartezeit zu lösen, habe ich schlicht zwei separate Prozesse programmiert. Das Hauptfenster macht eigentlich nicht viel. Lediglich die Laufschrift und ein Demo-Logo das zum Warten auffordert und ein wenig animiert ist damit es nicht so langweilig wird.
    Im Zweiten Prozess laden dann die Bilder. Beide Fenster liegen nun übereinander. Sobald das Laden abgeschlossen ist, hole ich es in den Vordergrund und nichts hakelt oder hängt.
    Das Speicherleck-Problem habe ich so geschickt umgangen, da keine Parameter untereinander ausgetauscht werden. Ist zwar nicht die Beste Lösung aber es läuft super. Beide Prozesse werkeln nun mit je 15% CPU-Last


    Werde das Ganze noch mit mehreren Musikstücken ausstatten. Was mir dabei noch fehlt ist das ein und Ausblenden der Lautstärke.
    Hat jemand eine Idee wie ich die Abspiellautstärke über xProfan verändern kann?


    Ich habe die überarbeitete Fassung einmal angehängt. Ich würde mich freuen, wenn ihr dazu ein paar Optimierungs-Tipps hättett.


    Wer es Ausprobieren möchte, sollte die XPGL-Linien auskomentieren oder eine Datei anlegen "Linie.xpgl" und folgenden Inhalt einfügen.


    / Linie.xpgl


    L;VC;2


    7, 3.4, 0; 1, 1, 0, 1
    -7, 3.4, 0; 1, 0, 1, 1
    7, -3.4, -0; 0, 1, 1, 1
    -7, -3.4, -0; 1, 0, 0, 1


    Das Ganze ins Hauptverzeichnis schmeissen.


    Dann noch ein paar Verzeichnisse Anlegen (auch im Hauptverz. des Programms)


    Order "Bilder" unterordner "1"


    und


    Ordner "Sound"


    eine mp3 umbenennen und als "1.mp3" benennen, im Ordner /Bilder/1 kommen die jpg's (Bildnamen sind egal)

  • Wenn Du eine ge-time-te "fade-in" und "fade-out" - Musikstück-Übergangsfunktion meinst: Die ist mit XProfan selbst m.E. nicht zu machen.


    Dazu kann ich höchstens den Player WINAMP mit entsprechendem Plugin empfehlen. Da geht das recht genau, allerdings würde ich mir trotzdem manuelle Triggerpunkte bei der Bildshow einbauen...


    Gruss

    HP255G7:Win10pro2.004,4*AMD Ryzen3200U@2.60GHz,6+2GB-RadeonVega/237GBSSD:intlDVDRW,3xUSB3 ext4TB-HDX,XProfanX3+Xasm/Xpse

    Einmal editiert, zuletzt von p. specht ()

  • hmmh, ja das wäre eine Möglichkeit, stimmt. Während ich Deinen Vorschlag las, fiel mit abrubt noch eine weitere Möglichkeit ein, so ganz spontan: "ISimpleAudioVolume" über Windows-API.
    werde das gleich mal versuchen.
    Ein getimtes Fade in/out ist nicht geplant weil die mp3's die abgespielt werden aus zwei oder drei Dateien mit jeweils 50min. Spielzeit bestehen. Damit fällt das aus.


    Da es aber möglich sein soll, wärend die Show läuft die Musik zu wechseln, wäre natürlich ein kurzes, langsames FadeOut recht Hilfreich. Denn sonst ist der Wechsel recht extrem und das
    finde ich unprofessionell.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!