| Autor |
Beitrag |
Logiqu
      
Beiträge: 43
Win XP
Delphi 2006 Pro
|
Verfasst: Do 20.01.05 23:11
Hallo!
Ich habe mir eine klitzekleine OpenGL-Engine gebastelt (ist noch lange nicht fertig) und kann auch Texturen laden.
Nun habe ich jedoch einen Anwendungsfall, bei dem es zu Speicherintensiv wäre, alle Texturen mit einem Mal in den Speicher zu drücken. Also dachte ich mir, ermittle man die Polygone, die nicht gesehen werden und gebe dessen Texturen frei (in diesem Fall belegt eine Textur genau ein Polygon).
Das Freigeben bereitet mir keine Probleme. Viel mehr aber das Laden.  Denn ich will Ladezeiten vermeiden. Aus diesem Grund dachte ich mir, die Texturen einfach in einem neuen Thread zu laden. Doch leider kommt von dem Thread keine Textur zurück. Ich denke, es liegt an der Funktion glGenTextures(1, Texture);. Wenn ich nämlich nach dem Aufruf die Variable Texture ansehe, steht ein Wert drinnen, der nicht nach einer neu zugewiesenen TextureID aussieht.
Womit kann das zusammenhängen? Oder gibt es andere Lösungsansätze, Texturen in Realtime zu laden 
_________________ Logiqu. Just feel it...
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Fr 21.01.05 08:41
Das geht auch nicht! OpenGL ist Threadabhängig. Du kannst die Texturen nur in dem Thread Laden in dem du auch OpenGL initialisiert hast.
Das glGenTextures dürfte kaum Zeit in Anspruch nehmen. Das intensivste beim Laden ist das Senden der Daten bzw. das Laden des Bildes von der Festplatte. Du könntest schon einmal Zeit sparen in dem du die Bilddaten in einem anderen Thread lädst. Diese müsstest du dann an den OpenGL Thread übergeben und er sendet diese dann zur Graka. (Pointer)
Zum Senden der Texturdaten solltest du alternative Möglichkeiten überprüfen. gluBuild2DMipmaps ist dort zwar die gebräuchlichste Möglichkeit aber nicht unbedingt die beste Wahl. Sollte die Extension GL_SGIS_generate_mipmap von der Karte unterstützt werden könntest du diese benutzen. Dann werden die MipMaps von der Grafikkarte in Echtzeit berechnet.
Desweiteren solltest du dir mal überlegen ob du nicht die Texturen einfach komprimieren kannst. GL_ARB_texture_compression GL_EXT_texture_compression_s3tc
Besonders bei Texturen die keine weichen Übergänge haben ist die Kompression kaum zu sehen.
Alternativ kannst du die Texturen auf auf 16 Bit stellen. Oder die Auflösung ein wenig verringern. Sollte eine Textur irgendwann mal nicht mehr in den Grafikkartespeicher passen so wird sie in den Hauptspeicher ausgelagert und es wird über AGP auf diese zugeriffen. Das ist zwar langsamer als wenn sie auf der Karte liegt ist aber trotzdem noch erstaunlich schnell. Deutliche Performanceeinbüche sind aber dennoch vorhanden.
Zum Laden von Texturen habe ich einen Header geschrieben. Dieser bietet diverse Möglichkeiten die andere zum Teil nicht haben. In der Version die ich zu Hause weiterentwickel benutze ich dann auch GL_SGIS_generate_mipmap und werde den noch um ein paar Dinge erweitern. Evtl kannst du dir ja ein paar Anregungen etc holen. Vielleicht gefällt er dir ja und dir benutzt den. 
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
Logiqu 
      
Beiträge: 43
Win XP
Delphi 2006 Pro
|
Verfasst: Fr 21.01.05 11:50
Danke!
Ich habe mir eben mal deine glBitmap angesehen. Sieht sehr nützlich aus! Wenn ich ein bisschen Zeit habe, werde ich sie mal ein Bisschen mehr unter die Augen nehmen.
Aber sag mal, wie machen das "ausgereifte" Spiele mit den Texturen? Laden die tatsächlich alle Texturen beim Start eines Levels?
Ich hatte schon versucht, die Maps in einem eigenen Thread zu laden und wenn der Thread fertig ist, diese Map im Haupt-Thread an OpenGL zu übergeben. Aber sehr viel schneller ging das auch nicht. (ich werde nochmal in die Soirces rein sehen... vielleicht habe ich auch was übersehen)
Also mal zur Vorstellung, was ich vor habe:
Ich wohne in einer mitteldeutschen Stadt und habe Satellitenbilder gefunden. Diese Bilder sind quadratisch mit einer Seitenlänge von 500 Pixel. Die ganze Stadt setzt sich aus 36 x 42 = 1512 solcher Quadrate zusammen. Ich denke, da ist es leicht nachzuvollziehen, dass ich nicht alles auf einmal rein laden will  Die Auflösung sollte aber schon erhalten bleiben. Ich will die Maps also nicht verkleinern.
Hast du eine Idee 
_________________ Logiqu. Just feel it...
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Fr 21.01.05 12:11
1512 * 500 * 500 * 32 bit / (8 Bit/Byte) -> 1448 MB Gesamtdaten
gut, kann ich nachvollziehen ...
Würd das in etwa so lösen:
Teilung deines darstellung in 4 Levels:
Level 1: Grad angezeigt
Level 2: An Anzeige angrenzend, Ablage in GraKa-RAM
Level 3: mittelweit von Anzeige entfernt, Ablage in Main-RAM
Level 4: sehr weit von anzeige entfernt, Lesen von HDD.
Am besten an einer Map zu veranschaulichen ... Koordinate 33 wird grade vollständig angezeigt ...
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| |123456789 -+--------- 1|222223344 2|222223344 3|221223344 4|222223344 5|222223344 6|333333344 7|333333344 8|444444444 9|444444444 |
Bewegt sich nun Die Anzeige in Richtung 5,4, dann sähe das dann so hier aus:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| |123456789 -+--------- 1|333333333 2|332222233 3|332222233 4|332212233 5|332222233 6|332222233 7|333333333 8|333333333 9|444444444 |
Umladen musst Du dann nur die Texturen, die sich in ihrem "Anzeige-Level" geändert haben ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Lossy eX
      
Beiträge: 1048
Erhaltene Danke: 4
|
Verfasst: Fr 21.01.05 12:26
Ein Spiel kommt normalerweise ohne solche riesigen Datenmengen aus. Wenn es 100 Texturen sind dann ist das schon gar nicht mal wenig. Und die sind dann aber auch noch nicht einmal so groß.
500 ist natürlich auch keine richtige Texturgröße. Normal haben die immer eine Potenz von 2 als größe. Also dann 512. Wenn du das mit weiß auffüllen würdest dann würdest du natürlich auch ein bisschen Speicher wegschmeißen. Was aber glaube ich nicht so extrem ins gewicht fallen dürfte. Die Bilder könntest du aber so auch nicht richtig laden. Da würde sich OpenGL weigern.
Und sonst würde ich mal schauen ob du das nicht doch anders lösen kannst. Ich kann mir aber auch gerade nicht sinnvoll vorstellen was du genau mit den Bildern anfangen willst. Wenn das die einzigste Möglichkeit wäre, dann musst du wohl oder übel immer Stückchen nachladen.
Ich würde dann aber auch nicht die kompletten Bilder laden sondern kleinere Stückchen. So 128x128. Dort könnte man dann entsprechend auch das Ende bei 500 Pixel durch andere Bilder auffüllen. Dann geht das laden schneller und blockiert nicht so lange. Vor allem geht nichts an Speicher verlohren. Das Laden würde ich aus einem anderen Thread machen. Der liefert dann nur einen Pointer mit den Bilddaten an den OpenGL Thread und der erstellt dann die Texturen. Aber nicht zu viele auf einmal.
Aber mal so intressehalber. Wie größ wäre eigentlich die Fläche die du gleichzeitig darstellen würdest? Falls die nämlich schon den Rahmen sprengen würde kämst du mit dem Laden gar nicht mehr hinterher.
_________________ Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
|
|
Logiqu 
      
Beiträge: 43
Win XP
Delphi 2006 Pro
|
Verfasst: Fr 21.01.05 12:32
Nettes Konzept
Ähnlich habe ich es auch schon. Da das Zoomen möglich ist, habe ich mehrere Maps, die angezeigt werden (entsprichte deinem Level 1). Ich verwende den Radius zum Blick-Mittelpunkt, um festzustellen, welche Maps in diesem Bereich liegen. Dann folgt ein Bereich, in dem die Maps zwar noch in der GraKa liegen, aber nicht angezeigt werden. Damit soll die Darstellung beschleunigt werden. Und ab einem bestimmten Radius werden die Maps wieder komplett freigegeben. Ich habe also dein Level 3 nicht implementiert. Eine Map wird in meinem Fall erst geladen, wenn sie angezeigt werden soll. Das ermöglicht einen Bewegungsspielraum ohne Nachladen.
Das Problem ist dann aber auch noch das "unbemerkte" Nachladen.
_________________ Logiqu. Just feel it...
|
|
Logiqu 
      
Beiträge: 43
Win XP
Delphi 2006 Pro
|
Verfasst: Fr 21.01.05 12:39
Zur Zeit lasse ich zwischen 9 und 16 dieser Maps anzeigen. Beim Laden werden die Maps auf 512 gestrecht. Das wäre allerdings nen Ansatzpunkt, das noch schneller zu machen, indem man die Maps schon mit der Seitenlänge von 512 Pixel lädt.
_________________ Logiqu. Just feel it...
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Fr 21.01.05 12:48
Das Level 3 in meinem Konzept ist das, was Lossy mit dem Ablegen im RAM meint ... Das bringt in sofern vorteile, weil Du,
1. Beim Übergang von 3 --> 2 keinen großen Ladeaufwand hast
2. Der Zugriff auf die Daten recht schnell is
3. meist genug RAM vorhanden ist, um eben mal 64 Level-3-Bilder anzuzeigen
4. Du damit bei der Fast-Anzeige nochmal einen Zusatz-Puffer hast
5. Alles Multithreaded ablaufen kann.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
NeoInDerMATRIX
      
Beiträge: 245
Win95, Win98(+se), WinNT, Win2000, WinME, WinXP(+pro), VISTA, Linux(SuSe), DOS [MultiMon(3)], Vista
D6 PeE + (FP 2.0l) + D3 Pe + D2005+ D2006 Arch
|
Verfasst: Fr 21.01.05 15:13
Hi,
also ich denke die idee von BenBE ist nicht schlecht! Nur noch nicht wirklich ausgereitst. Und das deine Texturen solche masse haben ist für 3D nicht wirklich vorteilhaft.
Vorschlag:
- benutze eine Texture die als platzhalter dient
- benutze ein loader thread
- benutze eine einteilung was sichtbar ist BSP-Tree
- bentzue ein Texture Manager
Texture Manager:
- Verwaltet alle Texture die zur verfügung stehen
- Läd aber nur diese die auch wircklich geladen werden müssen
- Fals eine Texture noch nicht geladen ist, wird sie in der anzeige per Platzhalter angezeigt, und Per Thread in den Speicher geladen.
- Texture wird nur an GaKa übergeben wenn sie direckt sichtbar ist, das wird per BSP-Tree getestet.
So müste es gehen! Der Thread für das laden sollte so nur kurtzfristig FPS einbussen erzeugen! Dies kannst du aber auch noch minimieren in dem du das lesen der Texture stückelst allso nicht mit einmal lädst. Und da du ja so lange die texture nich komplett geladen ist einen Platzhalter benutz, siegt es zwar nicht sonderlich gut aus, aber sollte gehen.
Ich hoffe ich konnte so einiger massen erklären was ich meine.
Cu
Neo
|
|
|