Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 16:55

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 31 Beiträge ]  Gehe zu Seite Vorherige  1, 2, 3  Nächste
Autor Nachricht
 Betreff des Beitrags:
BeitragVerfasst: Sa Mär 22, 2008 19:01 
Offline
DGL Member
Benutzeravatar

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.
Code:
  1. Texture.MipMap := mmNone;


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mär 22, 2008 23:40 
Offline
DGL Member

Registriert: So Jul 17, 2005 12:59
Beiträge: 89
Hi,

vielen Dank für Eure Antworten!

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.

Woran kann das nun liegen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Mär 22, 2008 23:57 
Offline
DGL Member
Benutzeravatar

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 networkmy 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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 23, 2008 01:22 
Offline
DGL Member

Registriert: So Jul 17, 2005 12:59
Beiträge: 89
Ok, hier mal Codeauszüge:

Code:
  1.  
  2. // Transporter-Objekt
  3. texTransObj = class
  4.   private
  5.  
  6.   public
  7.   tex: TglBitMap2D;
  8.     procedure upload();
  9.     constructor create(var pTex: TglBitmap2D);
  10.   end;
  11.  
  12. implementation
  13.  
  14. //Bilddaten laden
  15. procedure loadTexThread.loadTex();
  16. begin
  17.   texTrans.tex := TglBitmap2D.Create(texToLoad);
  18.   texTrans.tex.MipMap := mmNone;
  19. end;
  20.  
  21. procedure loadTexThread.execute();
  22. begin
  23.   Synchronize(loadTex);
  24.   Terminate();
  25. end;
  26.  
  27. // Transportobjekt an globale Liste anhängen, wird bei jedem Frame auf neue Objekte geprüft
  28. procedure loadTexThread.doSync();
  29. begin
  30.   cs.Enter;
  31.     texLoadingList.Add(texTransObjects[threadIndex]);
  32.   cs.Leave;
  33. end;
  34.  
  35. // Hier wird der Thread erstellt und ein instanziiertes Transportobjekt mitgegeben
  36. constructor loadTexThread.create(pThreadIndex: integer; pTexToLoad: String; pTexTransObj: texTransObj; pCS: TCriticalSection);
  37. begin
  38.  
  39.  threadIndex := pThreadIndex;
  40.  texTrans := pTexTransObj;
  41.  texToLoad := pTexToLoad;
  42.  inherited create(true);
  43.  
  44. end;
  45.  
  46. procedure texTransObj.upload();
  47. begin
  48.   tex.GenTexture(false);
  49. end;
  50.  
  51. constructor texTransObj.create(var pTex: TglBitmap2D);
  52. begin
  53.   tex := pTex;
  54. end;
  55.  
  56.  
  57. procedure TForm1.threadDone(Sender: TObject);
  58. begin
  59.  // Load Texture has finished
  60.   if sender is loadTexThread then
  61.   begin
  62.    dec(anzT);
  63.    (sender as loadTexThread).Synchronize((sender as loadTexThread).doSync); // Macht das hier Sinn?
  64.   end;
  65. end;  
  66.  
  67. // Hier wird das Laden der Texturen gestartet
  68. procedure TForm1.Button3Click(Sender: TObject);
  69. var
  70.  i: integer;
  71. begin
  72.  //Einfach-Schleife, Mehrfachschleife funktioniert nicht ohne Synchronize
  73.  for i := 0 to 0 do
  74.  begin
  75.   // Pictex ist eine globale TglBitmap2D Variable
  76.   texTransObjects[i] := texTransObj.create(pictex);
  77.   // cs ist eine instanziierte CriticalSection, in picsToShow stehen die Pfade zu den zu ladenden Dateien
  78.   texLoadThread[i] := loadTexThread.Create(i, picsToShow[i], texTransObjects[i], cs);
  79.   texLoadThread[i].OnTerminate := threadDone;
  80.   texLoadThread[i].resume;
  81.  end;
  82. end;
  83.  
  84.  


So, ich hoffe alles Wichtige ist dabei.
Würde mich sehr freuen, wenn Ihr mir Verbesserungsvorschläge machen könntet.

Viele Grüße


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 23, 2008 12:35 
Offline
DGL Member
Benutzeravatar

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.
Code:
  1. type
  2.   TTextureLoadThread = class(TThread)
  3.   protected
  4.     fTexture: TglBitmap2D;
  5.     fFilename: String;
  6.     procedure Execute; override;
  7.   public
  8.     property Texture: TglBitmap2D read fTexture;
  9.     constructor Create(Texture: TglBitmap2D; Filename: String);
  10.     procedure TextureLoaded(Sender: TObject);
  11.   end;
  12.  
  13.  
  14. { TTextureLoadThread }
  15.  
  16. constructor TTextureLoadThread.Create(Texture: TglBitmap2D; Filename: String);
  17. begin
  18.   inherited Create(True);
  19.  
  20.   fTexture := Texture;
  21.   fFilename := Filename;
  22. end;
  23.  
  24. procedure TTextureLoadThread.Execute;
  25. begin
  26.   try
  27.     fTexture.LoadFromFile(fFilename);
  28.   except
  29.     // irgendwas mit dem Fehler machen
  30.   end;
  31. end;
  32.  
  33.  
  34. procedure TForm1.TextureLoaded(Sender: TObject);
  35. begin
  36.   (Sender as TTextureLoadThread).Texture.GenTexture(False);
  37.   // Textur für Zeichnen gültig schalten.
  38. end;
  39.  
  40. procedure TForm1.Blah;
  41. var
  42.   Thread: TTextureLoadThread;
  43. begin
  44.   Texture := TglBitmap2D.Create;
  45.   Texture.MipMap := mmNone;
  46.  
  47.   Thread := TTextureLoadThread.Create(Texture, 'Blah.tga');
  48.   Thread.OnTerminate := TextureLoaded;
  49.   Thread.Resume;
  50. end;


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. ;)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 23, 2008 17:44 
Offline
DGL Member

Registriert: So Jul 17, 2005 12:59
Beiträge: 89
Hi,

vielen Dank!
So funktioniert es nun einwandfrei :)

Zwei Fragen hätte ich noch:

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?

Vielen Dank nochmal für Eure Hilfe!

Grüße
Pascal


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 23, 2008 18:07 
Offline
DGL Member
Benutzeravatar

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 networkmy 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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 23, 2008 19:22 
Offline
DGL Member
Benutzeravatar

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.

_________________
www.SaschaWillems.de | GitHub | Twitter | GPU Datenbanken (Vulkan, GL, GLES)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 23, 2008 19:38 
Offline
DGL Member
Benutzeravatar

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???


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 23, 2008 20:20 
Offline
DGL Member

Registriert: So Jul 17, 2005 12:59
Beiträge: 89
Hallo,

vielen Dank für Eure Antworten!

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.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 23, 2008 21:17 
Offline
DGL Member
Benutzeravatar

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.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 23, 2008 21:33 
Offline
DGL Member

Registriert: So Jul 17, 2005 12:59
Beiträge: 89
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.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 23, 2008 21:34 
Offline
DGL Member
Benutzeravatar

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 networkmy 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


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 23, 2008 21:38 
Offline
DGL Member

Registriert: So Jul 17, 2005 12:59
Beiträge: 89
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..


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 23, 2008 22:08 
Offline
DGL Member
Benutzeravatar

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.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 31 Beiträge ]  Gehe zu Seite Vorherige  1, 2, 3  Nächste
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 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.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.010s | 15 Queries | GZIP : On ]