|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Zyrian Super JLI'ler
Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 29.02.2004, 21:57 Titel: Performance verbessern |
|
|
Hi zusammen
ich habe in meinem Game eine Framerate von ca 29 fps ohne Framebremse. Lediglich auf einem Aldi-Rechner können Framerates von ~70fps erreicht werden.
Folglich kann man sagen, ich hab bei der Performance ziemlich ins Klo gegriffen ^^
Ich vermute einfach mal, dass es an den Vektoren liegt, die bei jeder Bewegung durchlaufen werden, und so ca. 800 einzelne Tiles + zusätzliche Sprites um die jeweilige Koordinatenänderung in andere Richtungen bewegen.
Mit Tiles hab ich mich diesmal das erste Mal auseinandergesetzt. Aus einer Datei lade ich das Aussehen der Landschaft und setze es in Sprites um.
Das sieht momentan so aus:
Code: |
if(surfaceTyp == "1")
{
RManager.AddTexture("gfx\\graphics\\gras.png"); // Grastextur hinzufügen
SurfaceToDraw.Create(Direct3D.GetDevice(),&RManager,128,128,1,1,1);
SurfaceToDraw.SetPosition(x,y);
SurfaceToDraw.AddTexture(RManager.GetTexture("gfx\\graphics\\gras.png"));
SurfaceToDraw.SetTexture(RManager.GetTexture("gfx\\graphics\\gras.png"));
// der Vektor, der bei der Renderroutine durchlaufen wird
vecSurfacesToDraw.push_back(SurfaceToDraw);
x += 128; // um Texturbreite weiterbewegen
}
|
Hier werden alle Tiles in einen Vektor gepackt. Dieser Vektor und noch ein weiterer Vektor, der die anderen Sprites, gegen die man "gegen laufen" kann, enthält, werden bei jeder Bewegung und jedem Renderschritt durchlaufen. Ich glaub, da hab ich meinem Rechner doch ein wenig zu viel zu getraut
Ich bin schon dies und das im Kopf durchgegangen, aber bin dann doch zu keinem Schluss gekommen, wie ich die Performance bessern könnte (ausser durch eine Vergrößerung der einzelnen Tiles). Für solche Gedanken bin ich vielleicht noch nicht weit genug, darum hoffe ich, dass ihr mir ein wenig unter die Arme greifen könntet bei diesem Problem (:
MFG
Chris _________________ Schau mir in die Augen, Kleines. |
|
Nach oben |
|
|
Beni5 Super JLI'ler
Alter: 36 Anmeldedatum: 12.11.2003 Beiträge: 310 Wohnort: Switzerland Medaillen: Keine
|
Verfasst am: 29.02.2004, 22:07 Titel: |
|
|
Also bei mir geht das toll. Ich habe auch Tiles, und momentan 2 Layer aus sprites und surfaces. Bist du sicher das du die files nur 1 mal lädst? Das war bei mir auch mal der Fehler. |
|
Nach oben |
|
|
Christian Rousselle Site Admin
Alter: 48 Anmeldedatum: 19.07.2002 Beiträge: 1630
Medaillen: Keine
|
Verfasst am: 29.02.2004, 22:52 Titel: |
|
|
Das ist alles etwas schwer zu sagen, ohne den kompletten Code zu kennen. Beschreib doch erstmal, was dein Programm machen soll, dann kann man auch besser sagen, ob das mit mehr als 29 FPS geht. Ansonsten, wie Beni5 schon sagt:
1. Sicherstellen, dass alles nur 1x geladen wird, nicht in jedem Frame.
2. vecSurfacesToDraw.push_back(SurfaceToDraw); sieht so aus, als wenn du das Object und nicht nur einen Zeiger/Adresse in den Vektor kopierst, kann man aber ohne die Definition von vecSurfacesToDraw zu sehen auch nicht sagen.
3. Was ist der Unterschied zwischen AddTexture und SetTexture, versteht man nicht.
Christian |
|
Nach oben |
|
|
Zyrian Super JLI'ler
Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 01.03.2004, 20:14 Titel: |
|
|
Also, geladen wird alles nur 1mal, so wie ich das hier sehen kann. Dafür hab ich ja 2 Funktionen, wobei die eine die "Bodensprites" ausliest und die andre die anderen, zu interagierenden Sprites. Diese Funktionen werden in der WinMain Methode aufgerufen, und zwar vor der Nachrichtenschleife.
Dies hier ist meine Renderroutine:
Code: |
void RenderGame()
{
// Szene beginnen
Direct3D.BeginScene();
//////////////////////
int i = 0;
// Surfaces zeichnen
for(i = 0; i < vecSurfacesToDraw.size(); ++i)
{
vecSurfacesToDraw[i].Draw();
}
// Sprites zeichnen, aus dem Kollisionsvektor gelesen
for(i = 0; i < vecKollision.size(); ++i)
{
vecKollision[i].Draw();
}
Schatten.Draw();
// Spieler zeichnen
Held.DrawAnim(Held.GetX(),Held.GetY(),8);
// Animation ausschalten
Held.SetAnim(FALSE);
// Framerate ausgeben
sprintf(fps,"FPS: %d\n MapX: %d\n MapY: %d",
RManager.GetFramerate(),
xPos,yPos);
Direct3D.DrawText(fps,1,1,D3DCOLOR_XRGB(0,255,0));
///////////////////
Direct3D.EndScene();
// Szene beenden
}
|
Zu dem Vektor vecSurfacesToDraw:
Die Deklaration war vector <CSprite> vecSurfacesToDraw
Der andere Vektor: vector <CSprite> vecKollision
Versuche von mir, Zeiger zu übergeben, äußerten sich nach erfolgreicher Kompilierung in einer Fehlermeldung und einem Absturz, wobei der Debugger mir nur einen Hinweis auf irgendwelche Hexadezimalcodes gibt.
Ich weiss aber, dass es generell unklug ist, bei solchen Ausmaßen die Objekte by value zu übergeben, aber wie gesagt ist der Versuch, es anders zu machen, bisher immer misslungen =/
Sorry für die fehlende Erklärung zu SetTexture()
Die Methode erlaubt es, einem Sprite eine andere Textur zuzuweisen. Wenn ich diese Funktion nicht aufrufe nach der Auslesung aus der Datei, so haben alle Sprites die Grafik des zuerst aufgerufenen Sprites. Wenn also zuerst Grasflächen ausgelesen werden, so haben später auch die Gehwege die Grastextur. Dies konnte ich bisher nur mit einem expliziten Setzen der zu verwendenen Grafik beheben.
Diese Methode verwende ich auch, wenn ich dem Spielersprite eine neue Grafik gebe, bspw. wenn sich die Figur in die entgegengesetzte Richtung dreht usw. _________________ Schau mir in die Augen, Kleines. |
|
Nach oben |
|
|
xardias JLI Master
Alter: 38 Anmeldedatum: 28.12.2003 Beiträge: 804 Wohnort: Palo Alto, CA Medaillen: Keine
|
Verfasst am: 01.03.2004, 20:45 Titel: |
|
|
Also generell kann man so noch optimieren:
Nach Texturen sortieren. d.h. alle Stein texturen zeichnen, dann alle holz usw. also so, dass man nur selten die textur wechseln muss, das verbraucht nämlich gut performance.
Ansonsten, speicher Sparen (4 statt 16 statt 32).
Wenns imemr noch langsam ist, würde ich mich mal nach nem profiler umschaun um den flaschenhals in deinem Spiel zu finden.
Happy Codin'
Xardias |
|
Nach oben |
|
|
Zyrian Super JLI'ler
Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 02.03.2004, 16:37 Titel: |
|
|
Hm, wie kann ich denn nach Texturen sortieren? Gibts dafür einen Algorithmus?
Zitat: | Ansonsten, speicher Sparen (4 statt 16 statt 32).
|
Was meinst du damit konkret?
btw:
Kann mir einer unter die Arme greifen bei der Verwendung von Adressen im Vektor statt der kompletten Objekte. Hört sich vielleicht blöd an, aber ich habs selber net hingekriegt... _________________ Schau mir in die Augen, Kleines. |
|
Nach oben |
|
|
Christian Rousselle Site Admin
Alter: 48 Anmeldedatum: 19.07.2002 Beiträge: 1630
Medaillen: Keine
|
Verfasst am: 02.03.2004, 16:47 Titel: |
|
|
Code: |
class CSprite
{
// viele nützliche Methoden/Daten
Render();
};
std::vector<CSprite*> m_vecSprites;
CSprite* sp;
sp = new CSprite("Sprite1");
m_vecSprite.push_back(sp);
sp = new CSprite("Sprite2");
m_vecSprite.push_back(sp);
// dann Rendern
std::vector<CSprite*>::iterator it;
for(it=m_vecSprite.begin();it!=m_vecSprite.end();++it)
{
(*it)->Render();
}
am Ende Löschen nicht vergessen:
for(it=m_vecSprite.begin();it!=m_vecSprite.end();++it)
{
delete (*it);
}
|
C. |
|
Nach oben |
|
|
Zyrian Super JLI'ler
Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 02.03.2004, 18:54 Titel: |
|
|
Jo klasse! Danke dafür! (:
Hab jetzt ~60 FPS, is zwar net viel, aber auch n guter Wert für ne Framebremse.
Thx 4 help!
MFG
#C _________________ Schau mir in die Augen, Kleines. |
|
Nach oben |
|
|
xardias JLI Master
Alter: 38 Anmeldedatum: 28.12.2003 Beiträge: 804 Wohnort: Palo Alto, CA Medaillen: Keine
|
Verfasst am: 03.03.2004, 17:33 Titel: |
|
|
Zum texturen sortieren gibt es leider keinen festen algoritmus.
Es komtm halt drauf an, wie du deine objekte verwaltest.
du verwendest ja für deine objekte den std::vector soweit ich mit bekommen habe. Dann könntest du zum Beispiel nen Functor benutzen um deine objekte zu sortieren. oder du machst das gleich per hand, es gibt ja eine menge sortier algoritmen. du musst nur deinen vector durchgehen und den so anordnen, dass die sprites mit den gleichen texturen direkt hintereinander liegen.
Das mti den Texturen mein ich ganz einfach nur so, dass du zum Beipsiel für s/w Bilder keine 32 Bit textur nehmen soltest. da reichen auch 4 bit (weiß nur nicht, welche parameter DX dafür braucht). Und für Bilder, die kein Alpha channel brauchen reicht meist auch 16 bit. |
|
Nach oben |
|
|
Hazel JLI MVP
Alter: 39 Anmeldedatum: 19.07.2002 Beiträge: 1761
Medaillen: Keine
|
Verfasst am: 03.03.2004, 17:56 Titel: |
|
|
Wenn du einen Vector benutzt, würd ich das mit dem sortieren sein lassen, weil es dort sehr zeitaufwendig ist. Da Spielobjekte sowieso andauernd kommen und gehen würde ich dir empfehlen auf std::list umzusteigen. _________________ *click* Dabuu!?
Twitter: http://twitter.com/Ollie_R
|
|
Nach oben |
|
|
Christian Rousselle Site Admin
Alter: 48 Anmeldedatum: 19.07.2002 Beiträge: 1630
Medaillen: Keine
|
Verfasst am: 03.03.2004, 18:05 Titel: |
|
|
Wobei ich nicht sehe, was dass für ein Nachteil haben soll, da ja nur Zeiger in dem vector sind.
Bei der Sortierung der Texturen bin ich mir auch nicht sicher....ich habe da noch nie einen Performance Vergleich geshen, noch habe ich das selbst gesehen, aber schon 1000x gehört. Was Sinn machen wird, ist die Texturen zu sortieren, damit sie nicht aus dem Videospeicher rausfliegen, wenn sie einmal drin sind und immer wieder geladen/rausgeschmissen werden usw. aber wenn man sowieso weniger braucht, als die Grafikkarte RAM hat, sehe ich den immer erwähnten Performancevorteil nicht. Die paar SetTexture-Calls können es jawohl nicht ausmachen und sind am Ende normalerweise schneller als das Sortieren. Kann mich jemand aufklären?
C. |
|
Nach oben |
|
|
Hazel JLI MVP
Alter: 39 Anmeldedatum: 19.07.2002 Beiträge: 1761
Medaillen: Keine
|
Verfasst am: 03.03.2004, 18:26 Titel: |
|
|
Stimmt mein Fehler... hab nicht dran gedacht dass es nur Zeiger sind. :) _________________ *click* Dabuu!?
Twitter: http://twitter.com/Ollie_R
|
|
Nach oben |
|
|
Zyrian Super JLI'ler
Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 03.03.2004, 18:52 Titel: |
|
|
na gut, dann würde das mit dem sortieren schon mal rausfallen.
hab grad bemerkt, dass ich leider nur auf gute fps komme, wenn meine einzelnen tiles nicht kleiner als 128x128 sind. eigentlich schade, aber was kann man schon von einem duron 1200 erwarten ... ?
noch mal zum sortieren. die sprites müssten ja eigentlich sowieso sortiert werden, und zwar danach, wo sie gezeichnet werden sollen. soll heissen, die sprites ganz oben müssten als erstes gezeichnet werden, dann die nächsten usw.
welchen suchalgorithmus sollte ich dazu am besten verwenden? im c++ primer sind eine ganze reihe aufgelistet, aber nur der sort algorithmus ist erklärt. die restlichen erläuterungen finde ich nicht, oder sie sind nicht vorhanden.
MFG
#C _________________ Schau mir in die Augen, Kleines. |
|
Nach oben |
|
|
Zyrian Super JLI'ler
Anmeldedatum: 30.08.2003 Beiträge: 321 Wohnort: Essen Medaillen: Keine
|
Verfasst am: 24.04.2004, 21:46 Titel: |
|
|
Mal so eine generelle Frage:
Ist es performancemäßig besser, wenn man mit wenigen großen, oder mit vielen kleinen Texturen arbeitet?
MFG
Chris _________________ Schau mir in die Augen, Kleines. |
|
Nach oben |
|
|
Sören JLI Master Trainee
Anmeldedatum: 26.07.2002 Beiträge: 647 Wohnort: Bonn Medaillen: Keine
|
Verfasst am: 24.04.2004, 22:56 Titel: |
|
|
Stellst du denn sicher dass du auch nur die Tiles renderst die auch auf dem Bildschirm zu sehen sind? Wenn von 800 Tiles nur 40 pro Frame zusehen sind, aber 800 gerendert werden isses klar dass da was abgebremst wird.
(Hab jetzt nicht den ganzen Thread komplett gelesen, also sry wenn ich was übersehen hab...) |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|