PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : OpenGL-Problem: RAM wird zugemüllt


Matti
2004-03-30, 15:07:48
ich bin gerade dabei, einen Landkarten-Viewer mit OpenGL zu machen. Das Grundprinzip: die Karte besteht aus Kacheln, alle sichtbaren Kacheln werden als Textur geladen, wird eine Kachel nicht mehr benötigt und der Speicher knapp, wird sie wieder freigegeben.

1.Fehlschlag:
ich habe alle Texturen mit glGenTextures & glTexImage2D erzeugt und mit glDeleteTextures wieder freigegeben. Das funktioniert auch bis zu einem gewissen Punkt, aber irgendwann wird nichts mehr freigegeben und immer neuer Speicher belegt.

2.Fehlschlag:
beim Freigeben wird die Textur-ID in einen Puffer geschrieben. Beim Laden wird zuerst in den Puffer geguckt, ob da schon eine Textur-ID zur Verfügung steht, wenn ja wird sofort glTexImage2D ausgeführt, wenn nicht wird vorher noch glGenTextures gemacht. ...damit ist das Problem aber auch nicht behoben.

:help:

PS:
Graka ist ne ti4600 mit aktuellsten Treibern

BofD
2004-03-30, 17:32:53
Hi,

wie gibst du denn den Speicher wieder frei (delete Operator)?

Bei meiner "Engine" (, wenn man das so nennen darf) werden die Texturen genauso geladen, aber werden über einen Zeiger-Array angesprochen. Wenn man da dann einfach nur einen bestimmten Eintrag des Arrays löscht bleibt ja das Bild selber im Arbeitsspeicher. Vielleicht ist ja bei dir daselbe.

Ach und nochwas wenn es das Programm ja ne Zeit lang tut, dann frag mal die ERROR_CODEs von glDeleteTexture ab:

Error Codes
The following are the error codes generated and their conditions.

Error Code Condition
GL_INVALID_VALUE n was a negative value.
GL_INVALID_OPERATION glDeleteTextures was called between a call to glBegin and the corresponding call to glEnd.

zeckensack
2004-03-30, 18:32:45
Eigentlich muss der Treiber das abkönnen, aber es ist eben nicht alles perfekt, auch nicht bei NVIDIA.
Du solltest aber nochmal checken, ob deine Texturnamen (nach GL-Lingo, eben die von glGenTextures gelieferten Zahlen) alle richtig sind.
Checkliste:
glDeleteTextures(x,p) - x sollte niemals 0 sein. p sollte immer auf ein Array zeigen das von glGenTextures gefüllt wurde. x sollte die gleiche Anzahl angeben, die auch beim zugehörigen Aufruf an glGenTextures benutzt wurde.

glBindTexture(*,x) - x sollte immer und überall ein von glGenTextures gelieferter Wert sein. Du solltest niemals eine Textur binden, nachdem du sie gelöscht hast. Um das sicherzustellen, kannst du die Texturnamen mit Nullen überschreiben, nachdem du glDeleteTextures aufgerufen hast.

Wenn deine Texturnamen in dynamischem Speicher liegen (etwa in Objekten, die auf dem Heap erzeugt werden), dann solltest du auf jeden Fall glDeleteTextures aufrufen, bevor du diesen Speicher wieder freigibst.

Texturnamen als lokale Variablen innerhalb einer Funktion sind so gut wie immer falsch. Sowas bitte unbedingt vermeiden.

BofD,
glTexImage2D innerhalb eines Begin/End-Paares würde - eben aufgrund des Fehlers - rein garnichts bewirken. Darstellungsfehler (aufgrund falscher Texturen) wären die Folge, aber keine Speichervermüllung.

Original geschrieben von Matti
2.Fehlschlag:
beim Freigeben wird die Textur-ID in einen Puffer geschrieben. Beim Laden wird zuerst in den Puffer geguckt, ob da schon eine Textur-ID zur Verfügung steht, wenn ja wird sofort glTexImage2D ausgeführt, wenn nicht wird vorher noch glGenTextures gemacht. ...damit ist das Problem aber auch nicht behoben.Versuch in dem Fall (also wenn du ein Texturobjekt recyclest) mal glTexSubImage2D.

Das geht natürlich nur dann gut, wenn alle deine Kachel-Texturen die gleiche Grösse haben, und das gleiche interne Format gewünscht ist. Diese Kriterien zu erfüllen, sollte bei einem Landkarten-Renderer aber kein Problem sein.

Matti
2004-03-31, 11:01:18
mir ist ein ganz dummer Fehler passiert :banghead:


void CMapViewer::FreeLoaderBuffer()
{
int i;

lbitems=0;

//Textur-Bitmaps freigeben
for(i=0;i<lbitems;i++)
{
if(loaderbuffer[i].texture.data!=NULL)
{
delete [] loaderbuffer[i].texture.data;
loaderbuffer[i].texture.data=NULL;
}
}

}

;D

zeckensack
2004-03-31, 11:16:30
Original geschrieben von Matti

<...>
lbitems=0;
<...>
for(i=0;i<lbitems;i++)
<...>

*mitroll* ;D