glDeleteTextures gibt Speicher nicht frei
trotz alledem das ich die texturen lösche wird der Speicher nicht freigegeben
Delphi-Quellcode:
woran kann es liegen ?
if assigned(quadTexture) then
begin for I := 0 to QuadCount - 1 do begin glDeleteTextures(i, @quadTexture); quadTexture[i] := 0; end; end; glDeleteTextures(1, @BackTexture); // Texture für Hintergrund glDeleteTextures(1, @GradientTex); // Texture für DiskSpectrum glDeleteTextures(1, @MeterTexture); // Texture für VUMeter glDeleteTextures(1, @PeaksTexture); // Texture für Peaks glDeleteTextures(1, @SpectrumTexture); // Texture für Spectrum glDeleteTextures(1, @BarTexture); // Texture für Slider glDeleteTextures(1, @PrivateTexture); // Texture für CDLabel Wüßte jetzt nicht was da falsch ist. gruss Emil |
Re: glDeleteTextures gibt Speicher nicht frei
Moin Emil,
unabhängig von irgendwelchen Speicherfreigaben - müsste das nicht eher so aussehen?
Delphi-Quellcode:
Ich habe jetzt mal dynamische Texture-Arrays angenommen.
begin
if Assigned(QuadTexture) then begin glDeleteTextures(Length(QuadTexture), @QuadTexture[Low(QuadTexture)]); SetLength(QuadTextures, 0); end; if Assigned(BackTexture) then // ... end; Freundliche Grüße |
Re: glDeleteTextures gibt Speicher nicht frei
@EWeiss
dir ist aber schon klar das deine Texture Variablen Pointer sind, oder ? Das heist. Wenn du eine Varaible
Delphi-Quellcode:
hast. dann kannst du B.free machen , und gibst den speicher frei.
var b:TBitmap;
Die Abfrage
Delphi-Quellcode:
würde aber immer noch True ergeben, da b.free sich selbst nicht auf NIL setzt.
if assigned(b) then begin
end; Genau das selbe ist es mit den OpenGL Texturen als Test. Gib deine Textur an einem Punkt frei nachdem du noch rendern kannst. ( also meinetwegen direkt wieder nach dem Laden ) dann stellst du fest das OpenGL dir stattdessen 1. Blödsinn oder 2. eine weise Textur anzeigt => der speicher wurde freigegeben. |
Re: glDeleteTextures gibt Speicher nicht frei
@marabu
Dynamisches Array ist ok hab dann wohl einen Denkfehler ;) Hab nicht daran gedacht das ganze Array auf einmal zu löschen. werd mal schaun ob es dann freigegeben wird.
Delphi-Quellcode:
@Corpsman
begin
if Assigned(QuadTexture) then begin glDeleteTextures(Length(QuadTexture), @QuadTexture[Low(QuadTexture)]); SetLength(QuadTextures, 0); end; if Assigned(BackTexture) then // ... end; Zitat:
warum sollte es das nicht sein die Trexture ist ein Pointer auf GLUnit 'PGlUint'
Delphi-Quellcode:
ist ein dynamisches array auf gluint da ist nix mit 'free'
quadTexture : array of GLuint;
EDIT: Auch wenn ich das Array(Texturen) in einem zug frei gebe steigt die Speicherbelastung stetig.. gruss Emil |
Re: glDeleteTextures gibt Speicher nicht frei
Woran erkennst du denn, dass die Texturen nicht freigegeben werden? Dem Arbeitsspeicher kannst du das eigentlich nicht ansehen, da die Texturen im Grafikkarten-RAM gespeichert werden. Wenn der Grafikkarten-Speicher voll ist, werden die Texturen dann in den Arbeitsspeicher geschoben, aber sonst nicht.
Noch was zu deinem Code
Delphi-Quellcode:
Dieser Code funktioniert nicht. glDeleteTextures erwartet zwei Parameter. Der erste Parameter sagt OGL, wieviele Texturen gelöscht werden sollen. Der zweite Parameter ist ein Pointer auf das erste Element eines glUint-arrays (wenn nur eine Textur gelöscht werden soll, dann muss es kein array sein).
if assigned(quadTexture) then
begin for I := 0 to QuadCount - 1 do begin glDeleteTextures(i, @quadTexture); quadTexture[i] := 0; end; end; Dein Code von oben müsste man also folgendermaßen umschreiben (nur wenn du ihn mit der for-schleife benutzen willst)
Delphi-Quellcode:
//Edit:
if assigned(quadTexture) then
begin for I := 0 to QuadCount - 1 do begin glDeleteTextures(1, @quadTexture[i]); quadTexture[i] := 0; end; end; Ach noch was: sind die anderen Variablen zufällig auch arrays? Wenn du den Pointer auf das erste Element eines arrays zurückgeben willst, würd ich das immer so machen:
Delphi-Quellcode:
@NameDesArrays[0]
|
Re: glDeleteTextures gibt Speicher nicht frei
Zitat:
Ich erkenne es daran das nach etwa 20 Titeln die Anwendung 150MB speicher belegt :) Beim start sind es 30MB und es steigt stetig wenn das Album sich ändert und die Texturen neu eingeladen werden. Zitat:
Habe ja oben die einzelnen Texturen auch mit
Delphi-Quellcode:
1 gelöscht.
glDeleteTextures(1, @BackTexture); // Texture für Hintergrund
Die schleife ansich macht das gleiche wie marabus vorschlag. Nur seiner ist eleganter kann mir die schleife dann sparen. EDIT: Zitat:
gruss Emil |
Re: glDeleteTextures gibt Speicher nicht frei
Ich glaube, dass das Problem nicht bei glDeleteTextures liegt. Ich glaube, es liegt er daran, dass du die Texturdaten nach dem Laden nicht freigibst.
Normalerweise schaut das Laden einer Textur ungefähr so aus
Delphi-Quellcode:
(die einzelnen Parameter sind jetzt mal beliebig gewählt)
glEnable(GL_TEXTURE_2D);
glGenTextures(1, @Texture); glBindTexture(GL_TEXTURE_2D, Texture); // Textur mit Daten füllen glTexImage2D(GL_TEXTURE_2D, 0, 3, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, pTexData); In pTexData befinden sich jetzt die einzelnen RGB-Werte der Textur (in diesem Beispiel 768 KB). Diese Daten solltest du nach dem Laden wieder freigeben. Am besten mit FreeMem(pTexData);. Sonst spuken diese Daten im RAM herum, obwohl du sie nicht mehr brauchst. Jetzt ist auch noch die Frage, wie du die Texturdaten aus der Datei in den Speicher bekommst (also pTexData mit RGB-Daten füllst). Wenn du z.B. TBitmap verwendest kann es noch sein, dass du die Instanz TBitmap nicht mehr freigibst. Das ist jetzt alles nur eine Vermutung. Was du auch noch machen kannst: schau dir mal die Werte an, die die einzelnen Textur-Indizes haben (in meinem Beispiel den Wert von Texture). Soweit ich beobachtet habe sucht OpenGL den niedrigsten freien Wert und setzt ihn dann in die Variable. Wenn die Werte jetzt immer größer werden, werden die Texturen vielleicht nicht freigegeben. Ich bin mir da aber überhaupt nicht sicher, ob das überhaupt funktionierten kann. |
Re: glDeleteTextures gibt Speicher nicht frei
Ich lade sie so..
Delphi-Quellcode:
aCovers ist ne TStringList
if Assigned(QuadTexture) then
begin glDeleteTextures(Length(QuadTexture), @QuadTexture[Low(QuadTexture)]); SetLength(QuadTexture, 0); end; glDeleteTextures(1, @BackTexture); // Texture für Hintergrund glDeleteTextures(1, @GradientTex); // Texture für DiskSpectrum glDeleteTextures(1, @MeterTexture); // Texture für VUMeter glDeleteTextures(1, @PeaksTexture); // Texture für Peaks glDeleteTextures(1, @SpectrumTexture); // Texture für Spectrum glDeleteTextures(1, @BarTexture); // Texture für Slider glDeleteTextures(1, @PrivateTexture); // Texture für CDLabel if assigned(aCovers) then aCovers.Free; // Lade Cover für Quader aCovers := TStringList.Create; if CoverPath <> '' then begin if CoverPath <> Path then ScanDirectory(CoverPath, 'bmp, tga, jpg', True); tmpC := 0; if (aCovers.count <= QuadCount) then begin for i := 0 to aCovers.count-1 do begin if (ExtractFileName(AnsiLeftStr(aCovers.Strings[i], Length(aCovers.Strings[i]) - 4)) = 'COVER') or (ExtractFileName(AnsiLeftStr(aCovers.Strings[i], Length(aCovers.Strings[i]) - 4)) = 'CDLABEL') then begin if FileExists(Path + UpperCase('Data\images\CompDisk\Default\NoCover.jpg')) then LoadTexture(Path + 'Data\images\CompDisk\Default\NoCover.jpg', quadTexture[i], False); dec(tmpC); end else begin LoadTexture(aCovers.Strings[i], quadTexture[tmpC], False); end; inc(tmpC); end; if (QuadCount >= (aCovers.count - 1)) then begin for q := (aCovers.count - 1) to QuadCount do if FileExists(Path + UpperCase('Data\images\CompDisk\Default\NoCover.jpg')) then LoadTexture(Path + 'Data\images\CompDisk\Default\NoCover.jpg', quadTexture[q-1], False); end; exit; end; tmpA := 0; if (aCovers.count >= QuadCount) then begin for i := 0 to aCovers.count-1 do begin if (ExtractFileName(AnsiLeftStr(aCovers.Strings[i], Length(aCovers.Strings[i]) - 4)) = 'COVER') or (ExtractFileName(AnsiLeftStr(aCovers.Strings[i], Length(aCovers.Strings[i]) - 4)) = 'CDLABEL') then begin if FileExists(Path + UpperCase('Data\images\CompDisk\Default\NoCover.jpg')) then LoadTexture(Path + 'Data\images\CompDisk\Default\NoCover.jpg', quadTexture[i], False); dec(tmpA); end else begin if (tmpA) <= QuadCount-1 then LoadTexture(aCovers.Strings[i], quadTexture[tmpA], False); end; inc(tmpA); end; if (QuadCount >= (aCovers.count - 1)) then begin for q := (aCovers.count - 1) to QuadCount do if FileExists(Path + UpperCase('Data\images\CompDisk\Default\NoCover.jpg')) then LoadTexture(Path + 'Data\images\CompDisk\Default\NoCover.jpg', quadTexture[q-1], False); end; end; end; Ok kann man besser machen ;) Das laden funktioniert ja lediglich das freigeben nicht Zum laden benutze ich den Textureloader von Sulaco gruss Emil |
Re: glDeleteTextures gibt Speicher nicht frei
Ok, der Texturloader vom Jan Horn sollte nicht das Problem sein, den hab ich früher auch verwendet.
Ich glaube, du lädst die Texturen doppelt. Die if-Abfragen
Delphi-Quellcode:
überlagern sich, falls aCovers.Count = QuadCount ist. Außerdem: kann es ein, dass du aCovers nicht mehr freigibst (oder hast du das aCovers.Free einfach nur nicht mit in den Post kopiert)?
if (aCovers.count <= QuadCount) then
// ... if (aCovers.count >= QuadCount) then Ich würd die Lade-Routine mal umschreiben, im Moment ist die noch relativ umständlich:
Delphi-Quellcode:
Keine Garantie auf Korrektheit, hab den Quelltext ohne offene IDE geschrieben
if FileExists(Path + UpperCase('Data\images\CompDisk\Default\NoCover.jpg')) then
LoadTexture(Path + 'Data\images\CompDisk\Default\NoCover.jpg', NoCoverTexture, False) else NoCoverTexture := 0; aCovers := TStringList.Create; try if CoverPath <> Path then ScanDirectory(CoverPath, 'bmp, tga, jpg', True); aFilledQuads := 0; for i:=0 to aCovers.Count-1 do begin // den Dateinamen extrahieren aFileName := ExtractFileName(aCovers[i]); // die Dateiendung abscheiden aFileName := Copy(aFileName, 1, length(aFileName) - length(ExtractFileExt(aFileName))); // Upper-Case machen aFileName := AnsiUpperCase(aFileName); if (aFileName = 'COVER') or (aFileName = 'CDLABEL') then begin LoadTexture(aCovers[i], quadTexture[i], False); end else QuadTexture[i] := NoCoverTexture; inc(aFilledQuads); // Schleife beenden, falls alle Elemente von quadTexture gefüllt sind if i >= High(quadTexture) then break; end; // Falls noch ein paar ungefüllte Quads übrig sind, werden die auch noch mit der // NoCoverTexture gefüllt for i:=aFilledQuads to High(quadTexture) do QuadTexture[i] := NoCoverTexture; finally aCovers.Free; end; |
Re: glDeleteTextures gibt Speicher nicht frei
Zitat:
Zitat:
Danke! aCovers.free darf in Finaly nicht freigegeben werden da später im Code noch verwendet Erst bei erneuten aufruf wenn neue Cover eingeladen werden. gruss Emil |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:21 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz