![]() |
AW: Beschleunigung von Laderoutine
Zitat:
Behalte doch einfach die OpenGL-Texture während der Laufzeit des Plug-Ins? Wenn ich das richtig verstehe, schmeißt du ja die Texturen weg, sobald die Grenze von (aCovers.count > QuadCount) überschritten ist. Der Flaschenhals ist ja das übertragen des JPEG-Bildes auf das Bitmap-Bild. Hier kannst du übrigens ein paar Zeilen einsparen: Anstatt:
Delphi-Quellcode:
Kannst du auch das schreiben:
// Create Bitmap
BMP := TBitmap.Create; BMP.pixelformat := pf32bit; BMP.Width := JPG.Width; BMP.Height := JPG.Height; BMP.canvas.draw(0, 0, JPG); // Copy the JPEG onto the Bitmap
Delphi-Quellcode:
BMP := TBitmap.Create;
BMP.Pixelformat := pf32bit; BMP.Assign(JPG); Zitat:
Das Vergleichen mit den neuen Titel/Albumpfad ist übrigens super schnell per TDictonary. Zitat:
Letztendlich ist das auch nur ein *.jpg oder anderer typ. Zitat:
|
AW: Beschleunigung von Laderoutine
Kannst mir das mal als Beispiele auf meine Routine übertragen?
So das ich das mal testen kann. Ich bin mir auch nicht sicher ob D2010 TDictionary unterstützt (Habe es vorher noch nicht verwendet.) Ok gibt es.. Zitat:
Zitat:
Das!
Delphi-Quellcode:
geht nicht.
BMP := TBitmap.Create;
BMP.Pixelformat := pf32bit; BMP.Assign(JPG); Danach wird mein Plugin einfach beendet. gruss |
AW: Beschleunigung von Laderoutine
Zitat:
Delphi-Quellcode:
...
uses System.Generics.Collections; ... var EWeissCoverDictionary: TDictionary<string, GLuint>; procedure Construct; begin EWeissCoverDictionary := TDictionary<string, GLuint>.Create; end; procedure LoadCovers(const CoverPath: string; out Texture: GLuint); begin if not EWeissCoverDictionary.TryGetValue(CoverPath, Texture) then begin LoadTexture(CoverPath, Texture, False); EWeissCoverDictionary.Add(CoverPath, Texture); end; end; procedure MachKaputtWasEuchKaputtMacht; var Texture: GLuint; begin for Texture in EWeissCoverDictionary.Values do begin glDeleteTextures(1, @Texture); end; EWeissCoverDictionary.Free; end; Zitat:
|
AW: Beschleunigung von Laderoutine
Zitat:
Werde es mir mal anschauen danke für das Beispiel. Obwohl ich eigentlich mit dem aktuellen Stand zufrieden bin. Hab das Teil im Hintergrund so ca. 5 Stunden laufen lassen. Keine Probleme und der speicherverbrauch liegt so bei 48 MB. EDIT: Habe mir da mal angeschaut. Letztendlich ist es so das es keinen sinn macht alle Covers incl. Texturen zu speichern. Im habe maximal 25 Cover im Karussell wird das 26 Geladen dann wird das erste gelöscht die anderen rücken dann nach und das 25 ist das aktuell spielende Album. Wenn ich das erste Cover lösche welchen sinn macht es dann dieses gespeichert zu lassen es kann aus dem Plugin dann nicht mehr abgespielt werden. Der sinn des Karussell ist das man ein beliebiges Album nochmals spielen kann. Ein gelöschtes Album kann man aber nicht mehr spielen von daher muss ich es auch nicht abspeichern weder im Array, Dictionary noch in einer Datei. Trotz allem ist schon interessant. gruss |
AW: Beschleunigung von Laderoutine
Bei der von mir vorgeschlagenen Lösung würdest du jeweils maximal 25 Texturen behalten, aber müsstest trotzdem immer nur Eine neu laden.
Init:
Delphi-Quellcode:
Neues Album laden:
InsertIndex := 0;
for I := Low(TextureArray) to High(TextureArray) do begin TextureArray[I] := NoCoverTexture; end;
Delphi-Quellcode:
Zeichnen vom Carousel:
if (TextureArray[InsertIndex] <> NoCoverTexture) then
begin DeleteTexture(TextureArray[InsertIndex]); end; LoadTexture(Pfad, TextureArray[InsertIndex]); Inc(InsertIndex); if (InsertIndex = Length(A)) then begin InsertIndex := Low(A); end;
Delphi-Quellcode:
for I := InsertIndex to High(TextureArray) do
begin RenderTexture(TextureArray[I]); end; for I := Low(TextureArray) to InsertIndex - 1 do begin RenderTexture(TextureArray[I]); end; |
AW: Beschleunigung von Laderoutine
Zitat:
|
AW: Beschleunigung von Laderoutine
Zitat:
Wie soll ich dann das nächste Album addieren wenn das Maximum erreicht ist? Was soll ich mit einem Cover das keine Verwendung mehr findet? Warum soll ich unnötiger weise den Speicher mehr belasten als nötig? gruss |
AW: Beschleunigung von Laderoutine
Zitat:
Beim Start werden all Texturen mit NoCoverTexturen befüllt.
Delphi-Quellcode:
Anschließend wird die INI eingeladen.
// fill all Quads with NoCoverTexture
if FileExists(FullDataPath + 'images\Default\NoCover.JPG') then begin LoadTexture(FullDataPath + 'images\Default\NoCover.JPG', NoCoverTexture, False); for q := 0 to QuadCount - 1 do quadTexture[q] := NoCoverTexture; end else NoCoverTexture := 0;
Delphi-Quellcode:
In aCovers stehen jetzt alle 25 Pfade zu den Album Covers.
procedure LoadINI;
var I: Integer; str: string; tmpList: TStringList; begin tmpList := TStringList.Create; try With AlbumIni do begin aCovers.Clear; CoverCount := StrToInt(ReadString('AlbumCover', 'Count', '0')); if CoverCount > 0 then begin for I := 0 to CoverCount - 1 do begin str := ReadString('AlbumCover', 'Folder' + IntToStr(I), ''); if (Length(str) > 0) then if FileExists(str) then aCovers.Add(str) else tmpList.Add(str); end; end; end; finally if tmpList.count > 0 then begin AlbumIni.EraseSection('AlbumCover'); for I := 0 to aCovers.count - 1 do AlbumIni.WriteString('AlbumCover', 'Folder' + IntToStr(I), aCovers.strings[I]); end; tmpList.Free; end; AlbumIni.Free; end; Jetzt werden all NoCoverTexturen mit den vorhandenen Covers gefüllt.
Delphi-Quellcode:
Und hier wird jetzt nur noch 1 Cover geladen..
if (aFileName = 'FOLDER') or (aFileName = Name) then
begin if quadTexture[I] = NoCoverTexture then LoadTexture(aCovers[I], quadTexture[I], False); // add to List LstCoverPath.Add(aCovers[I]); end;
Delphi-Quellcode:
Der erste Eintrag in der Liste für die Pfade zu den Cover Bildern wird geöscht.
if (aCovers.count > QuadCount) then
begin // delete first Cover aCovers.Delete(0); // move textures from destination to source for I := 0 to (aCovers.count - 1) do begin quadTexture[I] := quadTexture[I + 1]; // add to List LstCoverPath.Add(aCovers[I]); // Load last Testure if I = (QuadCount - 1) then begin // extract Filename aFileName := ExtractFileName(aCovers[I]); // extract extension aFileName := Copy(aFileName, 1, Length(aFileName) - Length(ExtractFileExt(aFileName))); // uppercase aFileName := AnsiUpperCase(aFileName); Name := ExtractFileName(GetAlbumArtistName); if Name <> '' then Name := Copy(Name, 1, Length(Name) - Length(ExtractFileExt(Name))); if (aFileName = 'FOLDER') or (aFileName = Name) then begin if quadTexture[I] <> NoCoverTexture then glDeleteTextures(1, @quadTexture[I]); LoadTexture(aCovers[I], quadTexture[I], False); end; end; end; end
Delphi-Quellcode:
aCovers.Delete(0);
Hier werden die Texturen verschoben
Delphi-Quellcode:
quadTexture[I] := quadTexture[I + 1];
Jetzt wird die Liste zu den Cover Bildern aktualisiert
Delphi-Quellcode:
LstCoverPath.Add(aCovers[I]);
Wenn I das gleiche wie Maximaler Cover Count -1 dann wird die letzte Texture gelöscht
Delphi-Quellcode:
glDeleteTextures(1, @quadTexture[I]);
und nur noch einmalig für dieses Album geladen
Delphi-Quellcode:
LoadTexture(aCovers[I], quadTexture[I], False);
Das geht schnell ohne merklichen Performance Verlust. Ich weiß das Rendern von dir ist nur ein Beispiel aber da steckt im Original einiges mehr an Funktionen drin
Delphi-Quellcode:
procedure RenderAlbum(aDeltaTime: single);
// Diese Funktion zeichnet die Quader. ColorScale skaliert dabei die Farbwerte der oberen beiden Ecken procedure DrawQuads(); var I: Integer; // index der for-schleife QuadAngle: single; // die Rotation des aktuellen Quads aPos: TGLVectord3; // die finale Position des aktuellen Quads [aPos = array[0..2] of single] begin glEnable(GL_TEXTURE_2D); glInitNames; glPushName(0); // alle Quads durchgehen for I := 0 to QuadCount - 1 do begin // Position initialisieren (aPos[0] = 0, aPos[1] = 0, aPos[2] = 10) aPos := Vector_Make3f(0, 0, 12); // Die Rotation des Quads (um den Mittelpunkt des Kreises, der durch die Quads gebildet wird) // + ListAnge, also die Rotation, die mit der Maus gemacht wird QuadAngle := DegToRad(360 / (QuadCount) * I) + ListAngle; // Den Positionvektor um den Mittelpunkt des Kreises um die Y-Achse rotieren aPos := Vector_Rotatef3(aPos, Vector_Make3f(0, 0, 0), QuadAngle, False, True, False); glBindTexture(GL_TEXTURE_2D, quadTexture[I]); if I = CurrentQuad then begin // Jetzt brauchen wir Blending glEnable(GL_BLEND); // nun die Blending-Funktion setzen glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(1, 1, 1, 0.7); // move to foreground StayOnTop(aPos, 1.5); // show only available cover if not(quadTexture[I] = NoCoverTexture) then begin win.IMGTexture := quadTexture[I]; win.bRenderGUI := True; end; end else begin // Original Farben setzen glColor4f(1, 1, 1, 1); // Blenden ausschalten glDisable(GL_BLEND); end; if not(LastAddCover = Round(NoCoverTexture)) then if LastAddCover = Trunc(quadTexture[I]) then begin glColor3f(1.0, 1.0, 1.0); glDisable(GL_TEXTURE_2D); // rahmen zeichnen glLineWidth(1); glBegin(GL_LINE_LOOP); glVertex3f(aPos[0] - QuadSizeS, aPos[1] + QuadSizeS * 2, aPos[2]); glVertex3f(aPos[0] - QuadSizeS, aPos[1], aPos[2]); glVertex3f(aPos[0] + QuadSizeS, aPos[1], aPos[2]); glVertex3f(aPos[0] + QuadSizeS, aPos[1] + QuadSizeS * 2, aPos[2]); glEnd; glEnable(GL_TEXTURE_2D); // Quad zeichnen glBegin(GL_QUADS); glTexCoord2f(0, 1); glVertex3f(aPos[0] - QuadSizeS, aPos[1] + QuadSizeS * 2, aPos[2]); glTexCoord2f(0, 0); glVertex3f(aPos[0] - QuadSizeS, aPos[1], aPos[2]); glTexCoord2f(1, 0); glVertex3f(aPos[0] + QuadSizeS, aPos[1], aPos[2]); glTexCoord2f(1, 1); glVertex3f(aPos[0] + QuadSizeS, aPos[1] + QuadSizeS * 2, aPos[2]); glEnd(); end; // Quad zeichnen glBegin(GL_QUADS); glTexCoord2f(0, 1); glVertex3f(aPos[0] - QuadSize, aPos[1] + QuadSize * 2, aPos[2]); glTexCoord2f(0, 0); glVertex3f(aPos[0] - QuadSize, aPos[1], aPos[2]); glTexCoord2f(1, 0); glVertex3f(aPos[0] + QuadSize, aPos[1], aPos[2]); glTexCoord2f(1, 1); glVertex3f(aPos[0] + QuadSize, aPos[1] + QuadSize * 2, aPos[2]); glEnd(); glLoadName(I + 1); end; glPopName; end; begin glDepthMask(ByteBool(GL_TRUE)); // Kamera ausrichten, damit man was sieht glTranslatef(0, -7, -30); // Maus verarbeiten if FMousePos.X > 0 then begin if FMousePos.X < 30 then ListAngle := ListAngle - pi / 4 * aDeltaTime else if FMousePos.X > _FNormal.Image1.Width - 30 then ListAngle := ListAngle + pi / 4 * aDeltaTime; end; // Wichtig für die Spiegelung glDisable(GL_CULL_FACE); glEnable(GL_BLEND); // Jetzt spiegel wir alles an der x-z-Ebene glScalef(1, -1, 1); // Jetzt zeichnen wir zuerst die Reflektionen der Quads DrawQuads(); glDisable(GL_BLEND); // Dann spiegel wir wieder zurück glScalef(1, -1, 1); // und zeichnen die eigentlichen Quads DrawQuads(); // Jetzt brauchen wir Blending glEnable(GL_BLEND); // nun die Blending-Funktion setzen glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBegin(GL_QUADS); glColor4f(0.0, 0.0, 0.0, 0.7); glVertex3f(-15, 0, 15); glVertex3f(-15, 0, -15); glVertex3f(15, 0, -15); glVertex3f(15, 0, 15); glEnd(); glDisable(GL_BLEND); glLoadIdentity; end; gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:06 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz