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

hanhau

Treue Seele

  • »hanhau« ist der Autor dieses Themas

Beiträge: 80

Wohnort: St. Pölten, Österreich

Beruf: schueler

  • Private Nachricht senden

1

22.03.2015, 09:07

[C++][SFML 2.1] TileMap effizienter rendern

Guten Morgen :)

Zu meiner Frage:
Ich habe es geschafft, einen TexturenManager zu schreiben, der für
meine kleine TileMap Texturen einliest. Nun habe ich eine TileMap,
die ein short int Array[][][] mit TexturenIDs besitzt und die Tiles von einer
Tilelist lädt.

Beim Rendern der TileMap gehe ich wie folgt vor:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void TileMap::draw(sf::RenderWindow *RW,sf::Vector2f Pos,float Radius)
{
    for(int z=0;z<MapSizZ-1;z++)                                           // Ebene abgehen (-1, da oberste Ebene Triggerebene)
    {
        for(int y=0;y<MapSizY;y++)                                          //Zeile abgehen
        {
            for(int x=0;x<MapSizX;x++)                                      //Spalte abgehen
            {
                if(TL->List[Map[x][y][z]].getID() != 0)                    //Wenn nicht Luft
                {
                    if(Radius >= sqrtf(pow((Pos.x-TileSizX*x),2) +    //Wenn Tile im Radius
                                       pow((Pos.y-TileSizY*y),2)))
                    {
                        // Hier wird das Shape eines Tiles, das in einem Vector in der TL = TileList sitz positioniert
                        TL->List[Map[x][y][z]].Shape.setPosition(sf::Vector2f(TileSizX*x,TileSizY*y));
                        // Hier wird es gezeichnet - Textur bekam es beim erstellen
                        RW->draw(TL->List[Map[x][y][z]].Shape);
                    }
                }
            }
        }
    }
}


Damit schaffe ich auf einen Laptop mit Quad Core ala 2.5Ghz und dedizierter GPU 8ms Frametime.
Inzwischen habe ich eine Funktion, die den Renderbereich auf eine sf::View beschränkt, allerdings habe
ich hier schlechtere Performane mit 10-12ms;

Ich habe gehört, dass es mit Vertex schneller sein soll, stimmt das, oder könnte ich meine
Schleife/Abfragen verbessern ?
Wie stelle ich das mit den Vertex eigentlich an ?

Danke im Voraus !
Oft denke ich an sie, niemals habe ich sie gefragt, niemals etwas gesagt,
nur verzweifelt am PC gesessen und dabei die Zeit vergessen, sie ist weg.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

22.03.2015, 09:17

Wie groß ist deine Map?

Ich möchte dir mal einen kleinen Hinweis geben, so dass es dir vielleicht selbst auffällt. Mal angenommen, du sollst alle Menschen befragen, die sich in einem Radius von 100 Metern um den Kölner Dom herum aufhalten. Würdest du dann sämtliche Länder der Erde abklappern und von jedem Menschen, den du triffst, die Distanz zum Kölner Dom messen, nur um dann "verwundert" festzustellen, dass sie in den allermeisten Fällen größer als 100 Meter ist? Wäre es nicht sinnvoll, deine Suche einzuschränken?

Und noch ein Tipp: Deine Wurzel ist überflüssig. Wenn sqrt(a² + b²) < c, dann ist a² + b² < c² (für positives c). Und hast du wirklich einen kreisförmigen sichtbaren Bereich? Nicht eher einen rechteckigen?

Es bietet sich auch an, die z-Schleife ganz nach innen zu verlegen, und zwar innerhalb der if-Abfrage. Die fragt nämlich nur nach x und y.

Letzter Tipp: Benutze einen Profiler (im Release-Modus, siehe unten!). Der sagt dir, wo wirklich die ganze Zeit verbraten wird. Da liegt man intuitiv nämlich oft meilenweit daneben und optimiert das falsche Stück Code.

Ach ja: Es heißt "size", nicht "siz".

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

22.03.2015, 09:25

Ich würde auch stark davon abraten für jede Schicht einen 2D-Array zu verwenden, da diese vermutlich größtenteils leer sind und somit unnütz über leere Einträge iteriert wird.
Ich würde daher die Tiles, die es wirklich gibt, alle in einen Vector hauen. Zum effizienten Rendern bietet sich ein sf::VertexArray an. Dafür gibt es auf der SFML-Webseite sogar ein Tutorial.

Zum Messen von Frametimes solltest Du übrigens niemals die Debug-Variante nutzen, was Du mit Garantie machst. Diese ist um etwa den Faktor 80 (ja, 80, nicht etwa 8) langsamer als die Release-Version. Sowohl von der SFML, als auch von Deinem eigenen Code.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

hanhau

Treue Seele

  • »hanhau« ist der Autor dieses Themas

Beiträge: 80

Wohnort: St. Pölten, Österreich

Beruf: schueler

  • Private Nachricht senden

4

22.03.2015, 10:34

Danke ür die Tipps/Hinweise :)

David:
Da hast du Recht, ich werde mal meine Abfragen ändern und schauen, ob es nun schneller ist :)
Ja, ich habe tatsächlich einen kreisförmigen Berech, der mir nicht im Spiel weiterhilft .....
Ich sollte das mit einer sf::View beschränken ^^
Es hieß immer bei mir Siz, Pos, Col .... das sollte ich aber auch mal ändern :)

Blue:
Im Release ist mein Programm minimal schneller,
an was kann es liegen ?
Habe im Release-Mode, bei den Linker Settings immer:

sfml-graphics
sfml-......
sfml-......

Muss ich die Endung -s verwenden ?

Danke !
Oft denke ich an sie, niemals habe ich sie gefragt, niemals etwas gesagt,
nur verzweifelt am PC gesessen und dabei die Zeit vergessen, sie ist weg.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

5

22.03.2015, 10:53

Blue:
Im Release ist mein Programm minimal schneller,
an was kann es liegen ?

Wie gesagt: Profiler benutzen.

Muss ich die Endung -s verwenden ?

Nein, das sind die statisch gelinkten Bibliotheken.

Mal ne Frage: Was genau misst du eigentlich? Und hast du V-Sync ein oder aus? Wie hoch ist die CPU-Auslastung?

hanhau

Treue Seele

  • »hanhau« ist der Autor dieses Themas

Beiträge: 80

Wohnort: St. Pölten, Österreich

Beruf: schueler

  • Private Nachricht senden

6

22.03.2015, 11:05

Ich messe die Frametime intern mit sf::Clock so wie

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sf::View view;
view ....              //auf Fenster anpassen

sf::Clock clock;

while(sf::Keyboard::isKeyPressed(sf::Keyboard::Space) /// zum Testem
{
        clock.restart();
        fenster.clear();
        
        //zeichnen von Tilemap
        LevelTileMap.draw(&fenster,Pos,Radius);

        fenster.display();    
        cout << clock.asMilliseconds() << endl;    
}
Oft denke ich an sie, niemals habe ich sie gefragt, niemals etwas gesagt,
nur verzweifelt am PC gesessen und dabei die Zeit vergessen, sie ist weg.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

7

22.03.2015, 11:06

Und hast du V-Sync ein oder aus?

Wie hoch ist die CPU-Auslastung?

hanhau

Treue Seele

  • »hanhau« ist der Autor dieses Themas

Beiträge: 80

Wohnort: St. Pölten, Österreich

Beruf: schueler

  • Private Nachricht senden

8

22.03.2015, 11:08

Entschuldigung, hab mir schon gedacht "Irgendwas hab ich jetzt vergessen".

V-Sync ist AUS.
CPU Auslastung bei 50% - 60%.
Oft denke ich an sie, niemals habe ich sie gefragt, niemals etwas gesagt,
nur verzweifelt am PC gesessen und dabei die Zeit vergessen, sie ist weg.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

9

22.03.2015, 11:34

Du hast aber einen aktuellen Grafiktreiber? Ansonsten läuft OpenGL und somit SFML komplett in Software-Rendering auf der CPU. Es klingt so als ob Du generell die SFML-Release-DLLs benutzt und dafür ist die Frametime doch sehr hoch.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

hanhau

Treue Seele

  • »hanhau« ist der Autor dieses Themas

Beiträge: 80

Wohnort: St. Pölten, Österreich

Beruf: schueler

  • Private Nachricht senden

10

22.03.2015, 13:20

Alle Grafiktreiber aktuell, kann man bei SFML abfragen, womit gerade gerendert wird ?
Oft denke ich an sie, niemals habe ich sie gefragt, niemals etwas gesagt,
nur verzweifelt am PC gesessen und dabei die Zeit vergessen, sie ist weg.

Werbeanzeige