Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Wie ich oben auch schon mal erwähnt hatte. Auf meiner Radeon 9600 hatte mit RGB (24Bit) Texturen auch schon feststellt, dass das hochladen länger dauert. RGBA (32Bit) Texturen wurden innerhalb von 1 ms Hochgeladen aber 24 Bit Texturen wurden anscheinend noch mal vom Treiber umkonvertiert und das dauert dann ca 60 ms. Evtl solltest du mal messen ob bei dir auch so etwas passieren könnte.
Zusätzlich dazu solltest du dir überlegen ob du MipMaps benötigst. Wenn du keine MipMaps benötigst aber sie aktiviert sind (das ist default so) dann werden sie beim hochladen erstellt. Im schlimmsten Falle macht die Grafikkarte das nicht sondern es muss auf die GLU zurückgegriffen werden. Wenn du keine benötigst dann einfach deaktivieren.
Ok, das Stocken der Anwendung hatte tatsächlich das Builden der MipMaps als Grund. Nach dem Ausschalten geht es sehr viel schneller.
Leider funktioniert das aber nur, wenn ich den Code zum Erstellen der Textur und dem Laden der Bilddaten NICHT synchronisiere. Wenn ich Synchronisiere, dann hängt die Anwendung wieder beim Laden
Wie Lord Horazont aber schon richtig bemerkt hat, muss ich das Syncen, sonst bekomme ich spätestens beim Laden mehrerer Texturen gleichzeitig unschöne Zugriffsverletzungen.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Zeig mal deinen Synchronisationscode. Vielleicht kann man da was optimieren.
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Also das Synchronize in deinem Thread ist falsch. Denn dadurch lädst du die Textur synchron im Hauptthread. Also genau das was du nicht bezweckt hast. Und das OnTerminate wird bereits syncronisiert aufgerufen. Also dort musst du nichts weiter synchronisieren.
Ich würde eher so etwas vorschlagen. Habe es aber nicht getestet sondern eben so frei Schnauze runter geschrieben. Aber sollte funktionieren.
Im Execute wird direkt geladen. Und im OnTerminate wird die Textur dann erzeugt. Du solltest aber darauf achten, dass die Textur erst dann verwendet wird, wenn sie im OnTerminate erzeugt wurde. Also, dass sie anschließend irgendwie / irgendwo gültig gestellt wird.
Das Speichern von Indizes halte ich persönlich für potentiell gefährlich.
PS: Im übrigen sind deine Klassennamen (loadTexThread) etwas verwirrend.
1. Ich möchte hauptsächlich JPEGs laden. Kann das JPEG Format überhaupt 32Bit Farbtiefe abspeichern? Das Hochladen der Textur verursacht leider noch einen ganz kleinen Ruckler.
2. Wie werden die Texturdaten eigentlich im Grafikkartenspeicher abgelegt? Wenn ich beispielsweise ein JPEG Bild lade, mit einer Auflösung von 512x512 Pixeln und einer Dateigröße auf der Festplatte von 200kB. Werden dann 200kB belegt, oder wird das Bild erst in ein unkomprimiertes Format gewandelt und belegt dann mehr Speicher?
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Die Daten werden natürlich entkomprimiert, da die Grafikkarte zum beispiel kein JPEG lesen kann. Wenn du also die Texturen nicht mittels OpenGL Texturkompression hochlädst (kann dir Lossy sicher mehr zu sagen) wird die mehr brauchen.
Und JPEG kann keine 32-Bit-Formate, was wegen der Kompression auch reichlich komisch aussehen würde. Wenn du den Alpha-Kanal also brauchst, musst du auf Formate wie PNG oder TGA umsteigen.
Wenn es jetzt nur um das eventuell schnellere Hochladen geht, musst du mal schauen, ob und wie man mittels der glBitmap die Texturen in ein anderes Format bringen kann (Lossy?)
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Mo Sep 23, 2002 19:27 Beiträge: 5812
Programmiersprache: C++
Das beste, und damit auch schnellste Format ist DDS. Praktisch jede Grafikkarte kann direkt mit den komprimierten DXT-Formaten umgehen. Dadurch geht das hochladen in den VRAM viel schneller, es muss nichts mehr umgewandelt oder entkomprimiert werden. Ansonsten hat das DDS-Format viele weitere Vorteile, und letztendlich ist es quasi dass einzig sinnvolle Format für Texturen.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Ja die Aussage von Lord Horazont stimmt. Die Texturen werden fast immer unkomprimiert abgelegt. Die glBitmap lädt die Bilder in ein unkomprimiertes Format (außer DXT) und dieses wird dann an OpenGL übergeben.
Es gibt auch die Möglichkeit die Texturen zu komprimieren. Die Gebräuchlichsten sind da DXT1, DXT3 oder DXT5 (DXT3 ist aber irgendwie nutzlos). Allerdings die Kompression ist ziemlich simpel und man sieht mitunter deutliche die Komprimierung. Es gibt aber auch die Möglichkeit die Texturen beim Hochladen komprimieren zu lassen. Aber das kostet Zeit weswegen das eher nicht benutzt wird. Für die Kompression solltest du eher zu DDS greifen, da das von hause aus komprimiert abgelegt werden kann.
JPEG kann aussließlich nur Graustufen oder RGB Bilder ablegen. Solltest du einen Alphakanal benötigen solltest du eher zu TGA, PNG oder DDS greifen. JPEG ist außerdem Verlustbehaftet wodurch die Kompression in der Lage ist deine Farben geringfügig zu verändern.
Die Ruckler. Wenn du ein Singlecore System hast, dann wird sich auch das Laden wärend dem Rendern bemerkbar machen, da beides auf einer CPU stattfinden muss. Das Hochladen wird in jedem Falle zusätzlich noch etwas Zeit benötigen. Um das zu messen kannst du ja mit dem HighPerformanceCounter mal messen wie lange das Hochladen dauert. Außerdem kann es immer passieren, dass mehr als eine Textur zur selben Zeit fertig sind. Die dann direkt nacheinander hochgeladen werden wollen. Das kann auch zu so etwas führen.
Die glBitmap ist auch in der Lage aus einem RGB ein RGBA Bild zu machen. Dafür gibt es die Methode ConvertTo(Format). Du kannst auch einen Alphakanal von einer beliebiegen Quelle hinzufügen. AddAlphaFrom???
Ich habe nun mal gemessen, wie lange das Hochladen der Textur benötigt und verschiedene Formate ausprobiert:
RGB JPEG ohne Konvertierung:
22ms
Selbes JPEG mit vorheriger Konvertierung nach RGBA:
18ms
D.h. es wir schon schneller, aber leider nicht so wahnsinnig viel. (Es handelt sich hierbei allerdings auch um eine relativ große Datei. Die einzige Möglichkeit, auch dieses letzten kleinen Ruckler zu beseitigen wäre wohl, das Bild in viele kleinere Teile zu unterteilen, oder?)
Achso: Die Anwendung läuft auf einem DualCore Prozessor. Während dem Laden der Bilddaten läuft die Anwendung perfekt flüssig weiter. Außerdem habe ich das nun so gebaut, dass maximal eine Textur pro Frame hochgeladen wird.
Weiterhin hab ich mir mal den "Video Memory Watcher" heruntergeladen, um zu sehen wie viel Speicher ich so verbrauche auf der Grafikkarte. Komischerweise hab es keinen Unterschied zwischen dem unkomprimierten Modus und dem DXT5/1 Modus. Beides mal wurden ca. 120Mb verbraten..?
Zu SSD: Gibt es eine Möglichkeit, die Texturen direkt mit Delphi umzuwandeln? Unter den glBitmap Funktionen habe ich bisher nichts gefunden.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
SSD? Du meinst DDS? Aber ja das wäre mit der glBitmap/OpenGL auch möglich, wenn ich komprimierte DDS speichern können wollte. Allerdings wäre das eher nur für ein externes Tool etwas. Aber es gibt sowohl für GIMP als auch für Photoshop entsprechende Plugins. Das ist in jedem Falle sinnvoller.
Ruckler: 18-22 ms ist schon nicht wenig. Das dürfte sich sich in jedem Falle bemerkbar machen. Allerdings 1 Textur pro Frame könnte schon recht viel werden. Du hast ja auch in dem Thread konvertiert, oder?
Dual/Single Core. Du solltest evtl. auch mal testen wie es aussieht, wenn du es auf einen Kern beschränkst.
"Video Memory Watcher" das lässt sich nicht immer so richtig sagen, denn die Speicherverwaltung obliegt dem Treiber. Normal sollte es sich schon bemerkbar machen aber ist kein zwang.
Klar, meinte DDS, sorry.
Nunja, das Ganze wird so eine Art Fotoalbum, und eigentlich sollte das nach Pfadangabe funktionieren, ohne das ich vorher erst alle Bilder in DDS umwandeln muss.. daher würde DDS eigentlich nur in Frage kommen, wenn die Anwendung das selber konvertiert. Kann Deine glBitmap DDS schon laden? Dann werde ich mal ein Bild umwandeln und nochmal messen, ob sich das überhaupt lohnen würde.
Konvertiert habe ich im Thread, jepp.
Wenn ich das Prog auf einen Core beschränke, dann ruckelt es sich ziemlich einen ab..
Also zur Zeit fahre ich mit einer Textur pro Frame auf jeden fall gut, denn das Laden der Bilddaten dauert pro Bild so ca. eine halbe Sekunde, und bei knapp 2000 Frames die ich habe, dürften genug Frames dazwischen sein um ein flüssiges Bild zu erzeugen
Ich lade die Bilder nun übrigens hintereinander, nicht gleichzeitig. Bei gleichzeitigem Laden wird auch der Hauptthread-Kern belastet, und dann fängt es wieder an zu ruckeln. Viel schneller geht es dadurch im Übrigen auch nicht.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Du könntest mal mit SetThreadAffinityMask festlegen, auf welchem kern der Thread laufen soll, also einmal im Ladenthread auf den zweiten Kern schieben und im Hauptthread (VCL) auf den ersten. Vielleicht packt windows deinen Thread aus irgeneinem grund auf den gleichen Kern.
Gruß Lord Horazont
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Danke für den Tipp, das hat Windows allerdings schon richtig gemacht. Im Taskmanager erreicht meine Anwendung beim Laden 100% Last, und fällt danach wieder auf 50% ab. Sollte also passen..
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Passi hat geschrieben:
Wenn ich das Prog auf einen Core beschränke, dann ruckelt es sich ziemlich einen ab..
Hab ich erwartet.
Und Windows verteilt der Sheduler die Threads so wie gerade Platz ist. Also immer hin und her. Und bei einem dauerhaften Renderthread (Hauptthread) wird der Ladethread eigentlich immer auf dem anderen Kern ausgelagert. Die Threads aber immer zwischen den Kernen gewechselt.
Ja die glBitmap kann DDS laden. Allerdings nur normale Texturen. Keine volumetrischen, keine Mipmaps und keine CubeMaps. DXT geht ohne Umwege. Sofern die Karte das unterstützt ansonsten wirds beim Generieren umgewandelt.
Mitglieder in diesem Forum: 0 Mitglieder und 2 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.