Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

xxendlessxx

Treue Seele

  • »xxendlessxx« ist der Autor dieses Themas

Beiträge: 230

Wohnort: Bad Schussenried

Beruf: Full Stack Developer

  • Private Nachricht senden

1

22.09.2009, 20:52

SFML Ressourcen freigeben.

Ich hab folgendes Problem.
Immer wenn ich zwischen dem Hauptmenü und dem Spielstate wechsle dann geht mein Ram um 2MB nach oben.

Kurz was zu meinem Quellcode:

Ich habe eine cGame Klasse die einen std::vector<cGameState*> States; Vektor besitzt.

In diesem Vektor werden die GameStates gespeichert.
Die GameState Klasse ist komplett virtual. Davon werden alle States abgeleitet, zb die Hauptmenüstate klasse. In der wird die Init() Funktion aufgerufen die zb das hintergrundbild läd.

Wenn ich nun den State wechsle dann wird folgende Funktion aufgerufen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
void cGame::ChangeState(cGameState* State)
{
    // cleanup the current state

    if ( !States.empty() ) 
    {
        States.back()->CleanUp();
        States.pop_back();
    }
    // store and init the new state

    States.push_back(State);
    States.back()->Initialize();
}

Es wird also jedesmal neu Initialisiert. Aber beim CleanUp kann ich ja die Bilder nicht löschen. Bzw. ich hab noch keine Funktion in SFML gesehen die in etwa so heißt: Image.Destroy();.

Ich hoffe mir kann jemand helfen. Ich werde mal den Kompletten quellcode ranhängen. ( Ist nicht viel )



gruß michi http://www.devnetik.de/source.zip

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

2

22.09.2009, 21:13

Speicher in deinem Gamestate irgendwo, ob der schonmal initialisiert wurde. Wenn dies der Fall ist, dann brauchst du die ganzen images nicht neu zu laden, sondern musst nur die Sprites neu erstellen.

xxendlessxx

Treue Seele

  • »xxendlessxx« ist der Autor dieses Themas

Beiträge: 230

Wohnort: Bad Schussenried

Beruf: Full Stack Developer

  • Private Nachricht senden

3

22.09.2009, 21:25

Hey danke für den Tip. Hab einfach eine if um den ganzen init block gemacht der abfragt ob in dem state schon initialisiert wurden.
wenn nein dann initialisiert der alles und setzt die variable auf true.

gruß michi

xxendlessxx

Treue Seele

  • »xxendlessxx« ist der Autor dieses Themas

Beiträge: 230

Wohnort: Bad Schussenried

Beruf: Full Stack Developer

  • Private Nachricht senden

4

22.09.2009, 21:58

@Topic: Gibt es aber wirklich keine Funktion um Fonts oder Images wieder zu löschen?
Also das Gegenstück zu sf::Image Bild; Bild.LoadFromFile("");

Es kann ja nicht sein das man alles läd und das bis zum Ende vom Spiel drin haben muss.

gruß michi

K-Bal

Alter Hase

Beiträge: 703

Wohnort: Aachen

Beruf: Student (Elektrotechnik, Technische Informatik)

  • Private Nachricht senden

5

22.09.2009, 23:45

bild.Create(0,0,sf::Color(0,0,0)) vielleicht?

Die SFML Doku ist immer ein guter Anhaltspunkt.

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

6

23.09.2009, 13:12

Zitat von »"xxendlessxx"«

@Topic: Gibt es aber wirklich keine Funktion um Fonts oder Images wieder zu löschen?
Also das Gegenstück zu sf::Image Bild; Bild.LoadFromFile("");

Es kann ja nicht sein das man alles läd und das bis zum Ende vom Spiel drin haben muss.



warum willst du es freigeben? wenn du es wieder brauchst musst du es neu laden, ist doch verschwendete zeit. und es erst am ende freizugeben ist eine durchaus clevere idee, weil jede vernünftige engine cached die daten und gibt dir dieselben ressourcen zurück, wenn du dieselbne neu erstellen willst.
es ist NUR dann sinnvoll sie explizit freizugeben, wenn das programm wirklich speichergierig ist. die paar mb sind da echt nicht die welt, solange sie am ende freigegeben werden!

K-Bal

Alter Hase

Beiträge: 703

Wohnort: Aachen

Beruf: Student (Elektrotechnik, Technische Informatik)

  • Private Nachricht senden

7

23.09.2009, 13:33

Da hat TrommlBomml recht. Du kannst das Bild auch mit new anlegen und dann mit delete wieder löschen.

xxendlessxx

Treue Seele

  • »xxendlessxx« ist der Autor dieses Themas

Beiträge: 230

Wohnort: Bad Schussenried

Beruf: Full Stack Developer

  • Private Nachricht senden

8

23.09.2009, 14:30

mal noch eine frage:
ich lege ja die states (die klassen) in einem vector ab.
wenn ich nun einen state wechsel zb von intro in das spiel,
dann wird folgendes gemacht

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
void cGame::ChangeState(cGameState* State)
{
    // Löscht alle noch enthaltenen States

    if ( !States.empty() ) 
    {
        States.back()->CleanUp(); //Führt die aufräum funktion aus

        States.pop_back(); //Entfernt den state vom Vector

    }
    //Speichert und initialisiert den neuen state

    States.push_back(State);
    States.back()->Initialize(this);
}


Wird dann nicht der alte State ganz aus dem Speicher entfernt? C++ macht das doch intern mit new und delete selbst wenn ich pop_back() aufrufe? oder versteh ich da was falsch.

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

9

23.09.2009, 15:03

Das einzige was gelöscht wird ist eine KOPIE des Zeigers auf deinen Gamestate. Weder der Zeiger, den du in der Funktion übergibst, noch die Daten, auf die er zeigt werden gelöscht.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

10

23.09.2009, 17:14

Zitat von »"xxendlessxx"«


Wird dann nicht der alte State ganz aus dem Speicher entfernt? C++ macht das doch intern mit new und delete selbst wenn ich pop_back() aufrufe? oder versteh ich da was falsch.


Die Container machen das lediglich für den Speicher, den sie selbst brauchen, um die Elemente zu speichern. Wenn du selbst Objekte anlegst, dann musst du die auch selbst freigeben. (der Container hat ja keine Möglichkeit festzustellen, ob du jetzt den Zeiger, den er da hält jetzt freigeben soll, oder nicht. Könnte ja gerade so gut ein Zeiger auf ein Objekt, ewlches im automatischen Speicher angefordert wurde sein.)

Wenn du aber ein solches Verhalten haben möchtest, dann kannst du dafür Sachen, wie z.B die in boost vorhandenen pointer Container benutzen.

Werbeanzeige