Registriert: Mo Okt 22, 2007 09:00 Beiträge: 22 Wohnort: Ilmenau
Hi alle zusammen,
ich stehe (mal wieder ^^) vor einem Problem, wo ich nicht weiß, wie ich es am besten löse.
Folgende Situationen: In meinem Programm kommen bestimmte Bilder im .jpg-Format zum Einsatz. Um den Überblick über diese Bilder zu behalten, bin ich grad dabei, eine Art Übersicht zu erstellen, wo dann bis zu 60 dieser Bilder verkleinert dargestellt werden.
Das Problem: Beim Aufbau der Übersicht müssen ja erstmal alle Bilder generiert werden, damit ich sie anschließend als Texturen auf Quads kleben kann. Und gerade dieses Laden kostet ziemlich viel Zeit (~ 5 sek. oder so).
Meine Frage: Gibt es eine (möglichst nicht zu komplexe ^^) Möglichkeit, die großen Bilder, deren volle Auflösung ich in der Übersicht ja nicht benötige, vor dem Generieren zu verkleinern, sodass ich eben nur die Thumbnails als Texturen vorliegen habe?
Ein Beispiel: Sagen wir, die jpg-Bilder wären 512*1024px groß. In der Übersicht sollen diese Bilder aber nur mit einer maximalen Auflösung von 128*256 dargestellt werden, sodass es eben eine Verschwendung wäre, die gesamte Auflösung der Bilder als Textur zu haben.
Wäre nett wenn ihr mir hier etwas unterstützen könntet, denn mehrere Sekunden Ladezeit finde ich an dieser Stelle doch bissl viel, weil das meiste ja wahrscheinlich für das GenTexture() drauf geht. Achja: Als Texturenloader verwende ich glBitmap.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Erstmal korrektur: Das meiste geht nicht für glGenTextures sondern glTexImage2D drauf. Wobei, da fällt mir gerade ein, den aufruf bekommst du ja wegen glBitmap garnciht mit. Ich weiss nicht, inwiefern glBitmap die möglichkeit bietet, die bilder noch zu verkleinern. Wenn du dir statt dessen SDL_image anschaust, da kannst du definitiv skalieren (mittels der sdlutils-Routine SDL_ScaleSurfaceRect, scheint aber zu problemen zu führen bei Bildern mit Alphakanal, was aber bei JPGs kein Problem darstellt).
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 die glBitmap bietet so keine Möglichkeit die Bilddaten zu skalieren. Je nach Platform gibt es unterschiedliche Möglichkeiten. Die von Lord Horazont ist eine. Aber ich spare mir das jetzt mal. Verwendest du Delphi oder FreePascal und ist es für Windows Only angedacht oder auch für SDL?
Aber ich denke als erstes solltest du etwas anderes machen. Denn ich persönlich denke, dass der Riesenanteil nicht bei OpenGL liegt sondern beim JPEG. Aber die haben einen richtig guten Vorteil. Du kannst JPEGs bereits verkleinert laden und dabei sparst du obendrein fast linear Rechenzeit. Das geht aber nur, wenn du die JPEGs direkt mit Delphi oder passenden Alternativen lädst.
Bei Delphi müsstest du die JPEGs dann per Hand laden. TJPEGImage erstellen. LoadFromFile/Stream. Dann anhand der Größe einen Faktor auswählen (1/2, 1/4, 1/8 ) und diesem dann bei Scale (oder so) setzen und das JPEG auf ein Bitmap zuweisen. Erst beim Zuweisen auf ein TBitmap wird das JPEG dekodiert. Dieses Bitmap kannst du dann auf die glBitmap zuweisen und eine Textur erstellen. Evtl kannst dieses Bitmap dann noch umrechnen. Aber wenn es nicht zu weit von der gesuchen Größe ist, dann liefert die Filterung von OpenGL auch pasable Ergebnisse. Und spart massiv Zeit.
Wenn es Platformunabhängig sein soll, dann kann ich dir zur libJPEG raten. Die ist obendrein auch noch schneller als die Implemenation von Delphi. Aber benötigt eine externe DLL. ABER bei dem Header von mir sind zwar Beispiele dabei aber der Code ist trotzdem ziemlich krank. Deswegen nur dann benutzen, wenn man stark, mutig und tapfer ist.
Registriert: Mo Okt 22, 2007 09:00 Beiträge: 22 Wohnort: Ilmenau
Erstmal vielen Dank für die beiden Antworten
Lossy eX hat geschrieben:
Also die glBitmap bietet so keine Möglichkeit die Bilddaten zu skalieren. Je nach Platform gibt es unterschiedliche Möglichkeiten. Die von Lord Horazont ist eine. Aber ich spare mir das jetzt mal. Verwendest du Delphi oder FreePascal und ist es für Windows Only angedacht oder auch für SDL?
Ich verwende Delphi (genauer gesagt Turbo Delphi), und es soll nur für Windows sein
Zitat:
Aber ich denke als erstes solltest du etwas anderes machen. Denn ich persönlich denke, dass der Riesenanteil nicht bei OpenGL liegt sondern beim JPEG. Aber die haben einen richtig guten Vorteil. Du kannst JPEGs bereits verkleinert laden und dabei sparst du obendrein fast linear Rechenzeit. Das geht aber nur, wenn du die JPEGs direkt mit Delphi oder passenden Alternativen lädst.
Bei Delphi müsstest du die JPEGs dann per Hand laden. TJPEGImage erstellen. LoadFromFile/Stream. Dann anhand der Größe einen Faktor auswählen (1/2, 1/4, 1/8 ) und diesem dann bei Scale (oder so) setzen und das JPEG auf ein Bitmap zuweisen. Erst beim Zuweisen auf ein TBitmap wird das JPEG dekodiert. Dieses Bitmap kannst du dann auf die glBitmap zuweisen und eine Textur erstellen. Evtl kannst dieses Bitmap dann noch umrechnen. Aber wenn es nicht zu weit von der gesuchen Größe ist, dann liefert die Filterung von OpenGL auch pasable Ergebnisse. Und spart massiv Zeit.
Werde mal in den nächsten Tagen diesen Weg ausprobieren. Habe mir bereits ein paar Gedanken darüber gemacht, das ganze irgendwie über die TJPEGImage etc. zu gehen, wusste allerdings nicht, dass man das direkt verkleinert dort reinladen kann. Somit scheint diese Variante wohl recht gut zu sein
Registriert: Mo Sep 02, 2002 15:41 Beiträge: 867 Wohnort: nahe Stuttgart
FYI: Also möglich ist es tatsächlich ziemlich einfach, vor dem GenTexture mit glBitmap zu resizen. Zumindest mit Delphi/Win32. Aber nur weil Lossy so toll gecodet hat. Beim Runterskalieren einer JPEG von 2048x2048 auf 512x512 hab ich 30ms eingespart!
Code:
type
TglBitmap2DDownScalable =class(TglBitmap2D)
public
function ScaleDown(Factor:Integer):Boolean;
end;
{ TglBitmap2DDownScalable }
function TglBitmap2DDownScalable.ScaleDown(Factor:Integer):Boolean;
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Ich kann dir DDS empfehlen.
DDS hat ein MipMap support und kennt auch DXT5.
Du kannst also Dir einfach eine MipMap laden(z.B. lade MipMap 256x256) und wenn dieses nicht vorhanden ist, dann nimmt er das nächst größere.
Das Format ist sehr einfach, übersichtlich und ein header schwirrt auch für Objekt Pascal rum.
Da das suchen im Forum mir zulagen dauert, verweise ich einfach auf den Header im meinen svn.
Die Loaderroutine anzupassen ist ziemlich leicht, du hast immernoch kompremierte Bilder und musst keine Thumbs verwenden, sondern kannst das Orginal nutzen.
Desweiteren ist DDS mit DXT1 oder 5 im vergleich zu jpeg, in sachen ladezeit, in etwa so zu vergleichen.
DDS(DXT1/5) ist die Rakete und Jpeg der Elefant.
Ich brauche für eine 512x512 Textur mit MipMaps ~11ms bis vom Load call bis zum binden.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Tak ich sage das ja nur ungern. Aber da zwoetzen jpeg explizit erwähnt könnte es vielleicht sein, dass die BBilder extern sind. Bei Digitalkameras zum Beispiel ist DDS nicht so wirklich weit verbreitet. Da gibt es nur jpeg und dann muss man die eben schnell laden. So denke ich mir das zu mindest.
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Er redet von Texturen die z.B. 512x1024 groß sind und hat garkein Format genannt.
Jpeg hast du vorgeschlagen und npot texturen haben Cameras eigentlich nicht.
Ergo, denke ich passt mein Vorschlag sehr wohl hier rein.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
zwoetzen hat geschrieben:
Folgende Situationen: In meinem Programm kommen bestimmte Bilder im .jpg-Format zum Einsatz. Um den Überblick über diese Bilder zu behalten, bin ich grad dabei, eine Art Übersicht zu erstellen, wo dann bis zu 60 dieser Bilder verkleinert dargestellt werden.
zwoetzen hat geschrieben:
Ein Beispiel: Sagen wir, die jpg-Bilder wären 512*1024px groß. In der Übersicht sollen diese Bilder aber nur mit einer maximalen Auflösung von 128*256 dargestellt werden, sodass es eben eine Verschwendung wäre, die gesamte Auflösung der Bilder als Textur zu haben.
Spielt aber auch keine Rolle. Denn zwoetzen wird sicher wissen was er damit vor hat...
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Hehe, okey.
Da hab ich doch zu schnell den Text überflogen ^^.
Das Problem bei Jpeg ist die Dekompression, diese ist nicht so schnell und das dauert dann antürlich einige ms.
Vieleicht sollte man auch mal libpng zur rate ziehen, png nutzt meines wissens ne zlib kompression und die ist massiv auf entpackgeschwindigkeit getrimmt und ist daher auch ein bischen schwächer in der Kompression aber auch verlustlos.
edit: Sehr viel zeit kann man rausholen, wenn man nicht 60 files stück für stück anfässt sondern alle in eine tar packt und dann die tar mit einen ruck lädt. Das ständige anfordern von Datein und das stückweise auslesen sind sehr Zeitintensive.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Mitglieder in diesem Forum: 0 Mitglieder und 4 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.