habe ein zeit problem hier, ich muss so schnell wie es geht, nen PNG (8 Bit Farbe) Stream laden und diesen in eine OpenGL Texture Uploaden.
Den Stream lese ich aus einem 25 GB file, welches ich mit FileSeek (Relative) und FileRead auslese.
Das ganze läuft in echtzeit ab, genauer gesagt alle 40 ms.
Ob du da auch direkt den ScanLine Pointer übergeben kannst weiß ich nicht. Ich kopiere die immer erst noch in einen temporären Buffer. Das dauert aber normal keine Millisekunde. Wobei ich da allen ernstes befürchte, dass die das png Format das Genik brechen wird. PNG ist ein recht aufwendiges Format und das zu dekomprimieren dauert ein bisschen.
Noch eine kleine Anmerkung. Du zeichnest dein Bild auf ein 24 Bit Bitmap. Du könntest aber praktischerweise ein 32 Bit Bitmap nehmen. Das kann man schneller hochladen. Habe vor kurzem mal getestet wie schnell glTexImage2D da so ist. Das ist bei mir ein Unterschied von 3 zu 20 ms für ein 512x512 Bild in RGBA und RGB.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Ich habe mal die Bilder in Links umgewandelt. Die waren doch ein wenig arg groß.
Die Luminance Textur sieht recht merkwürdig aus! Was isn das für ein PNG? Ich hoffe du hast es als Graustufen Bild abgespeichert und nicht als paletten Bild. Das sieht für mich nämlich fast so aus. Wobei ich jetzt (nachdem ich dein erstes Post noch mal durch gelesen habe) auch irgendwie das Gefühl bekomme etwas nicht ganz verstanden zu haben. Oder anders verstehen wollte. Wobei 256 Bit Texturen schon verwirrend ist.
Also es gibt auch die möglichkeit Palettenbilder zu benutzen. Zu mindest war das mal vorgesehen. Hat sich aber nie durchgesetzt und wird somit auch nicht unterstützt und in Zukunft wohl auch nicht. Die einzigen Texturen die du benutzen kannst sind RGB, Luminance und Alpha (und Float). Und das alles in den wildesten Kombinationen. Bitte mich nicht aufhängen wenn da jetzt eine fehlt. Luminance ist aber keine Palette sondern lediglich Graustufen. Aber wo ich das Bild sehe, denke ich nicht, dass das von dir gewünscht ist.
RGB/RGBA macht auf Atis nen gewaltigen unterschied. Wobei du aber auch nicht nur das Bitmap ändern musst sondern OpenGL auch sagen musst, dass sich das Format geändert hat. Wenn das noch auf RGB steht schmeißt er dir den Alphakanal weg. Dann dauert natürlich wieder.
Wobei du bei PNGs natürlich mit Scanlines auch die RGB Daten bekommen kannst. Also direkt auslesen und dann übergeben.
Eine andere Möglichkeit wäre evtl DXT1 also DDSs mit der Kompression DXT1. Wenn du das ohne Alphakanal abspeicherst, dann sieht es noch ganz gut aus und du kannst es so direkt hochladen. Also nichts mit umformen etc. Das dürfte das Datenvolumen aber mal eben verdoppeln, wenn nicht sogar noch mehr. Und es sieht nicht besser aus als mit PNGs.
Warum ließt du deine Daten zu erst von Platte in einen MemoryStream. Geht es dadurch schneller?
Ich würde außerdem versuchen mir die Abfrage auf NPOT zu ersparen. Das Target kannst du Problemlos in eine Variable packen und bei der Initialisierung kannst du auch die Texturkoordinaten in ein Array packen. Also entweder 0..1 oder 0..width. Dann musst du nicht ständig Abfragen was ist. Dürfte aber nicht vor gegen dein Problem unternehmen.
Was isn das für ein PNG? Ich hoffe du hast es als Graustufen Bild abgespeichert und nicht als paletten Bild. Das sieht für mich nämlich fast so aus.
Also es ist ein 720x576 und 256 Farben PNG, sprich es ist nen 256 Farben Paletten PNG. Wurde aus einem 24 Bit (RGB) PNG erstellt.
Zitat:
RGB/RGBA macht auf Atis nen gewaltigen unterschied.
Hier nicht, da wir hier nur NVIDIA karten haben, (GeForce1 und GeForce 6800 GT)
Zitat:
Warum ließt du deine Daten zu erst von Platte in einen MemoryStream. Geht es dadurch schneller?
Ansonsten kann ich das Original PNG Bild nicht laden, bzw. Dekomprimieren da man ja nur mit TStreams arbeiten kann. Aber die sache mit TMemoryStream ist recht schnell.
Zitat:
Ich würde außerdem versuchen mir die Abfrage auf NPOT zu ersparen.
Hab ich grad berücksichtigt, habe den code oben entsprechend auch geändert.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Kannst du mal ausprobieren wie schnell du eine Textur hochladen kannst? Bzw. würde ich dir generell auch mal empfehlen. Um alles was irendwie etwas zeit benötigt mal mit dem PerformanceCounter mal zu testen. Um auch einfach mal zu sehen wo das eigentlich Problem ist. Und welche Stellen wie viel zeit benötigen. Um dann auch mal systemematisch ein bisschen rumprobieren zu können. In dem Zusammenhang würde mich auch mal interessieren wie schnell bei dir das Hochladen geht. Also in RGB und RGBA.
Du könntest doch deine Datei mit einem TFileStream öffnen, den Stream positionieren und dann an LoadFromStream übergeben? FileStream hat, wenn ich mich nicht vertue, einen Cache eingebaut um auch mehr Daten am Stück zu lesen. Wobei der ja eigentlich auch nur wieder auf FileOpen zugreift. Na ja. Ist eigentlich auch egal.
Ich würde mal versuchen systematisch zu messen wo wie viel Zeit verlohren geht und wo das meiste Optimierungspotential vorhanden ist. Bis auf das was ich dir gesagt wüsste ich jetzt sonst auch nicht man sonst noch groß tun kann. Ich denke aber auch mal, dass die PNG Dekomprimierung auch ein wenig Zeit in Anspruch nehmen wird.
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
OpenGL selbst kann doch auch kompremierte Daten behandeln. Wäre es nicht eine Möglichkeit die Daten so zu packen wie es OpenGL auch macht, und das dekodieren direkt von der GraKa machen zu lassen?
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Japp. Das geht durchaus auch. Hatte ich oben auch schon mal erwähnt. S3tc und daraus sollte DXT1 benutzt werden, da das keine Alphakanal beinhalten kann. Der ja auch nicht benötigt wird. Das Einlesen dürfte schneller gehen, da die Daten ja direkt übergeben werden können. Allerdings ist da mit qualitativen Verlusten zu rechnen ist. Abgesehen davon dürfte das die Daten im Vergleich zu JPG und PNG noch mal um ein weiteres Stück aufblasen, da die Komprimierung sehr simpel ist.
Um mal ein paar Hausnummern zu nennen. Die resultierenden Bildern haben dann eine 16Bit Farbtiefe (Rot 5 Grün 6 Blau 5). Das sieht aber keines wegs schlecht aus. In ungünstigen Fällen kann es zu Artefakten kommen. Weiche Verläufe sind dann auch nicht mehr ganz so weich.
Kompression ist immer fix und ein 512x512x24Bit Bild lässt sich von 768 Kb auf 128 Kb verkleinern. Man müsste aber eigentlich vom 16 Bit Original ausgenen und dann wäre das eh nur noch 512Kb groß. Falls das irgend jemanden interessiert.
Kannst du mal ausprobieren wie schnell du eine Textur hochladen kannst?
Jop, werd gucken wie schnell GL_BGR, gegenüber GL_BGRA ist.
Zitat:
Bzw. würde ich dir generell auch mal empfehlen. Um alles was irendwie etwas zeit benötigt mal mit dem PerformanceCounter mal zu testen.
Werd ich tun.
Zitat:
Du könntest doch deine Datei mit einem TFileStream öffnen, den Stream positionieren und dann an LoadFromStream übergeben?
Wenn ich das so mache, komm ich 1. an das Limit von Integer ran, deswegen benutz ich ja FileSeek welches Int64 unterstützt. Das ist insofern wichtig, weil das File 25 GB gross ist und das das Limit von Integer sprängt. Und 2. das laden dauert > 400 ms, weil er nen ende des Bildes selbst suchen muss funktioniert aber nur in nem file < 2 GB
Zitat:
Ich denke aber auch mal, dass die PNG Dekomprimierung auch ein wenig Zeit in Anspruch nehmen wird.
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Wenn dein PNG unkomprimiert ist, dann würde das bedeuten es wäre genausogroß wie ein entsprechendes Bitmap. PNG is nur deshalb kleiner als Bitmap weil es die Daten komprimiert. Wie Frase vermutet, denke ich auch, dass es unkomprimierte PNGs gar nicht gibt (VERMUTUNG!)
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Registriert: Sa Nov 13, 2004 11:00 Beiträge: 229 Wohnort: Steinhude
naja, wenn man wirklich will geht unkomprimiert schon. das sieht dann so aus, dass die einzelnen blöcke jeweils unkomprimiert sind (ist möglich um bei unkomprimierbaren daten die dateigröße nicht durch die kompression zu erhöhen). Dadurch hat man dann allerdings noch keine durchgehenden Bilddaten aufgrund der Blockheader und ich weiß nicht, ob es bildbearbeitungsprogramme gibt, bei denen man das machen kann
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Genau. Möglich ist alles. Nur ist das Problem, dass PNG wie gesagt in Blöcken aufgebaut ist, was das Laden nicht einfacher macht. Wenn man das durch ein TGA oder BMP austauchen würde, dann könnte man die Daten direkt laden. Und nicht erst über ein umständliches Format.
TFileStream oder generell Streams arbeiten immer mit Int64. Und 2ten versteh ich nicht.
Also hab bissel mal gesucht im netz und ne bessere/schnellere lib gefunden welches einige Grafikformate lesen kann.
FreeImage heisst die und bringt gut 10 ms mehr an speed, gegenüber dem normalen TPNGImage
Hab auch mal das mit der Zeitmessung gemacht und jetzt denk ich mal den übertäter gefunden zu haben.
Allerdings kann ich da nichts machen
Hab 4 Zeit Messungsteile gemacht:
- Sprungzeit (FileSeek)
- Lesezeit (FileRead)
- Dekodierzeit
- Konvertierungszeit (nach 24 Bit RGB und OpenGL Texture Upload)
- Gesamtzeit (Alle 4 zusammen + den anderen rest für ogl)
hab den film mal mit nem simplen 100 bilder increment laufen lassen, also so das die bildnummern immer um 100 erhöhen alle 40 ms.
Als er bei bild 29800 angekommen ist, lag die Zeit beim Lesevorgang schon allein über 40 ms, wie man am screenshot erkennen kann:
Selbst als er los fährt, bsp. 2500 ist die zeit scheisse:
Wenn er aber steht, beispiels an Bild 100000, das ist knapp am 25 GB File ende, dann ist die zeit ok.
Sobald er aber fährt dann brichts ein
Die Zeit wo einbricht, ist die Lesezeit, also das Simple FileRead Der rest ist in ordnung (Hier aufem AMD XP 2000+, mit GeForce 1 ist der Dekodier und Upload vorgang auch lahm, aber das macht nix, da dies auf unserem Video Rechner, P4 2,8 GHz, GeForce 6800 GT PCI-E beides zusammen knapp 14 ms hat)
Hat wer ne idee was man da machen kann ?
Liegt das an den Windows Hardware Interrupts ? Würde da nen abgeschotter Thread helfen ?
TFileStream geht nicht, da nur Longint hier in Delphi 5 und nix Int64 Habs auch ausprobiert, wenn er über die 2 GB grenze raus ist... dann kann er kein Seek mehr machen
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Hmmm. Das sieht so aus als ob Windows da die Zeit verbrät. Und es zum Ende hin gecached hat.
Ich denke du musst da ein Stück asynchronität in dein Program mit einbauen. Also indem du zum Beispiel einen Thread machst der permanent am Daten lädst. So ca. 10-50 Bilder oder so im vorraus. Du musst ja normal frühzeitig genug wissen wo du lang fahren willst also sollten so Fehlladungen praktisch ausgeschlossen sein. Wenn der Ladethread dann auf Windowswarten muss spielt das keine so große Rolle mehr, da er schon Bilder geladen hat. Diese werden dann immer abgefragt und so hast du einen Puffer um die Cacheschwäche von Windows ausgleichen zu können. So viel zur Theorie. Ob es funktioniert kann ich mit gewissheit nicht sagen.
Evtl. solltest du für den Anfang mal probieren ob du die Datei offen lassen kannst. Das dürfte den Cache von Windows nicht ganz so verwirren. Denke mal, dass du dadurch auch ein bisschen Probleme bekommen dürftest.
Dekodier und Konvertierzeiteinsparungen wirst du wohl nur durch ein alternatives Grafikformat erreichen. Wobei das ja formlich nach komprimierten Texturen schreit.
[edit] Das mit dem FileStream ist natürlich doof aber ist dann wohl nicht zu ändern. Wobei ich auch gemerkt habe, dass der Filestream keinen Cache eingebaut hat und bei vielen kleine Leseoperationen dann länger dauert als nene Cache anzulegen.
Mitglieder in diesem Forum: 0 Mitglieder und 7 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.