Es ruckelt (SDL)
-
Hallo,
ich habe die letzte Zeit damit zugebracht mein Spiel von Framebremse 35 fps auf fps-Unabhängig zu trimmen.
Die gute Nachricht ist das ich jetzt ca 50fps auf meinem normalen Pc(2200 mit GeForce 4 TI 4200) und 200-300 auf meinem Laptop(1,5 ghz Centrino mit ati Mobility Radeon 9200) habe.
Sind beides denkich ganz akzeptable Ergebnisse und es läuft jetzt alles auch viel viel flüssiger.
Die Spiellogik ist grösstenteils jetzt auch so umgebaut das sie fps unabhängig läuft.Naja aber der Grund dieses Postes ist folgendes:
Während auf meinem Laptop alles superflüssig geht, ist auf meinem "normalen" PC, auf dem ich das Spiel auch grösstenteils entwickle, irgendwie ein ziemlich fieses Ruckeln.
Es ist kein flackern, sondern wirklich ein ruckeln, sprich der Charakter "springt" wenn ich auf der Karte scrolle ich sag mal etwa ein mal die Sekunde regelmäßig derartig unschön das es ein Grund wäre das Spiel nicht zu spielen
.Ich würde jetzt ja sagen das ich einfach irgendwo mist gebaut habe,
aber ich habe die letzten drei Tage damit zugebracht den Fehler im Quellcode zu suchen, die Koordinaten ausgegeben uswusw. das ich jetzt irgendwie langsam verzweifle ^^Resultate der letzten Tage waren:
- das meine Logikberechnungen wohl richtig sind, sprich ich berechne nicht irgendwann die Sekunde falsche Koordinaten und der Kram kommt dadurch Zustande
Sie sind auch insofern richtig, als das Bewegungen usw auf Laptop/Pc gleichschnell ablaufen.- etwa jeder 50te Frame (bei ca 50 fps :> ) ca 60 ms statt ca 20 ms dauert und der Effekt wohl dadurch entsteht
Dies ist auch der Fall wenn der Charakter stillsteht und nicht auf der Karte gescrollt wird.- ich mir nahezu sicher bin, das ich keine derartigen Berechnungen anstelle, die die benötigte Zeit einmal jede Sekunde verdreifachen.
Habe den den Quellcode auchnochmal gründlich nach sowas durchforstet und das einzige was ich jede Sekunde mache ist ein itoa... das wirds wohl eher nicht sein ;).- es tritt auch auf wenn ich nur die Charaktere zeichne und Hintergründe, Items usw NICHT darstelle/berechne... .
- Es läuft auf dem Laptop auch dann flüssig wenn ich eine Framebremse einbaue die die fps auf 50 runterregelt
- Auf dem PC lässt sich das ruckeln reduzieren(nicht wegbekommen, aber es wird spielbar wenn natürlich auch zähflüssiger) indem ich dort eine Framebremse auf 35 fps einbaue.
Frage ist nun, kommt dieses Problembild irgendjemandem bekannt vor und weiss er eine Lösung wie man das wegbekommen könnte?
Gruß
dreaddy
-
Ich schätzte mal, dass du eine Variable im Spiel hast, die die Zeit speichert, wie lange das letzte Bild für den Aufbau gebraucht hat.
Was hat die Variable für einen Typ? Vielleicht läuft die Variable über und erzeugt desshalb zu große Werte. Oder beim multiplizieren mit einem char oder einem short entstehen solche Fehler.
Lass dir mal alle Werte dieser Variable ausgeben und überprüfe, dass keiner dieser Werte aus der Reihe liegt.
-
Bei mir ist das der TFT-Monitor. Häng's mal an einen CRT und schau, ob es verschwindet.
-
Ich hab doch genau das selbe Problem. Ich hab aber mein Programm schon an den unterschiedlichsten Rechnern (mittlerweile 6) getestet und das Ruckeln scheint nicht wirklich vom Monitor abzuhängen. Zuerst hab ich gedacht, es liegt irgendwie an Allegro, aber wenn du mit der SDL das selbe Problem hast, ham wir selbst wohl irgendwo den gleichen unauffälligen Fehler gemacht.
-
Vielleicht läuft irgendein anderer Prozess im Hintergrund, der einmal pro Sekunde irgendwas macht und Deinem Spiel so die CPU entzieht. Probier mal testweise, die Priorität Deines Prozesses auf "Hoch" zu setzen (mit dem Task-Manager).
Es könnte auch tatsächlich am V-Sync liegen.
Was Du noch machen könntest: nimm nicht immer die vom letzten Frame benötigte Zeit beim Aktualisieren, sondern einen geglätteten Wert, z.B. den Mittelwert der letzten 10 Frames. Dann reagiert das Spiel auf heftige kurze Ruckler nicht so extrem.
-
Das es am Monitor liegt bezweifle ich, erstens habe ich einen crt und zweitens würde der dann doch nicht so offensichtlich schon im pc länger brauchen.
Genauso denke ich nicht das da irgendwo ein Überlauf in der Anzeige entsteht, ich mach dafür einfachUint32 now = SDL_GetTicks(); for(;;) { if(!make_gameframe())break; cout << "framedauer: "<< (SDL_GetTicks()-now)<<std::endl; now = SDL_GetTicks(); }Also ich habe das Spiel heute nochmal auf den PCs meiner Eltern probiert, auf dem dortigen p500 und p1500 lief es mit 40 bzw 50 fps vollkommen flüssig.
Setze ich die Priorität auf meinem PC hoch, läuft das Spiel auch etwas flüssiger, die framedaueranzeige sagt mir dazu dann
"
19
38
37
19
.....
"statt
"
19
20
19
19
59
19
..."Denke damit ist der Verursacher mehr oder weniger klar, irgendwo läuft bei mir ein Prozess der einmal die Sekunde irgendwelchen Müll macht.
Die 40ms die er braucht werden bei Prio hoch anscheinend nochmal unterteilt und man lässt das Spiel noch einmal während er rumrechnet ran.Hm... jetzt weiss ich aber immer noch nicht wie ich das verhindern kann ^^
Weder finde ich einen Prozess der sowas machen könnte(auch nachdem Virenscanner usw ausgeschaltet wurde tritt dieser Effekt auf), noch weiss ich wie ich das jetzt programmtechnisch umgehen könnte.Ich werd nochmal intensiv Spyware suchen undso... hmm ich frage mich nur warum tritt das dann nicht bei anderen Spielen auf?
Gibt es ein Tool um sich die Auslastung durch irgendwelche Programme pro ms genau anzeigen lassen zu können?
-
dreaddy schrieb:
19
20
19
19
59
19
..."Denke damit ist der Verursacher mehr oder weniger klar, irgendwo läuft bei mir ein Prozess der einmal die Sekunde irgendwelchen Müll macht.
ich hatte mal genau dasselbe problem, dort lags an einem falsch installierten treiber und es wurde mit der falschen GL-lib gelinkt.
-
Hm das mit dem Durchscnitt der letzten 10 framezeiten habe ich jetzt mal probiert, anstatt das es ruckelt macht der Char jetzt einmal die Sekunde eine kleine Pause.
Ist zwar auch nicht schön, sieht aber wesentlich besser aus, danke für den Tipp.
Spyware aller Sorten habe ich auch gefunden und gegrillt, das hat aber nichts gebracht.
Sdl-Libs habe ich auch nomma die neuesten gezogen, hat auch nix gebracht und opengl oder so nutze ich nicht sondern nur sdl mit den ganzen dazugehörigen libs wie mixer, gfx, image usw. und von denen habe ich grad überall die neuesten Versionen gesaugt.
Grafikkartentreiber habich eigentlich auch vor kurzem erst aktualisiert hmmm... das gefällt mir immer weniger alles =[Vielleicht sollte ich mir einfach einen neuen Pc kaufen

-
Versuch doch mal rauszufinden, wo genau er einmal die Sekunde die zusätzliche Zeit verbrät.
-
hm ich gehe inzwischen eigentlich davon aus das das irgendwo extern ausserhalb des Spieles und damit jedesmal an unterschiedlicher Stelle passiert, aber ich werde das nochmal nachprüfen.
-
hm das ist interessant, das Zeitproblem entsteht genau beim screens flippen hier:
save_time("vorm flip"); // zeit vorher in Datei speichern SDL_Flip (screen); <--------------------------------- !!!!!!!!!!!!! =[ save_time("ende make_gameframe"); // Zeit nachher in Datei speichern
-
Ich kenne mich mit SDL nicht so aus, aber wird da V-Sync benutzt?
-
-
Ich habe erst gelesen, dass SDL sehr implementierungs-abhängig ist. Bei dem Artikel ging es um Hardware Surfaces und so... könnte also auch an so etwas liegen.
Klingt jedenfalls sehr misteriös... Wenn nicht an deiner Zeitberechnung liegt...
Mich hat das ganze mit den verschiedenen implementierungen gleich so abgeschreckt, dass ich gleich zu sdl+opengl gegriffen hab. Weiß nicht ob dass viel besser ist, aber wurde auch in dem artikel angeraten.
Muss dazusagen, dass ich mit opengl auch schon früher eigentlich keine probleme der sorte hatte. (Weiß aber nicht ob dieser umstieg für dich in frage kommt)
gutes gelingen noch!
mfg Manuel
-
Naja eigentlich bin ich mit SDL bisher sehr zufrieden, nur das das sdl_flip sich irgendwie synchronisiert und dazu teilweise ewig für braucht is recht zum kotzen ^^
Ich mein da steht ja auch "The hardware will wait for vertical retrace, and then swap video buffers before the next video surface blit or lock will return" aber so lange?_?Das in nen extra SDL-Thread zu packen wirds wohl auch nicht bringen, das Bild muss ja fertig sein und auf allen anderen Rechnern läufts ja hmm.
-
Glaub mir du sparst dir extrem viel Ärger und Zeit, wenn du die Zeichenfunktionen immer in einem Thread lässt.
Hast du nen Virenscanner im Hintergrund laufen?
Dass du bei (kommerziellen) Spielen keine Probleme hast kann daran liegen, dass die ihre Prozesspriorität erhöhen (bringt bei dir anscheinend ja auch was).
-
Was soll ich da in einen extra Thread packen?
Ich kann immer nur dann auf dem Bildschirm darstellen wenn ein Frame fertiggezeichnet ist und das Problem ist ja die zeichnen <-> darstellen Synchronisation anscheinend.
Aber die sind halt voneinander abhängig.
-
Versuch doch mal in den Treibereinstellungen den vsync auszuschalten.
-
dreaddy schrieb:
hm das ist interessant, das Zeitproblem entsteht genau beim screens flippen hier:
save_time("vorm flip"); // zeit vorher in Datei speichern SDL_Flip (screen); <--------------------------------- !!!!!!!!!!!!! =[ save_time("ende make_gameframe"); // Zeit nachher in Datei speichernSry wenn ich Stuss erzähle, aber nur mal rein interessehalber: dauert das speichern in eine datei nicht extrem lange? Ich dachte immer solche sachen werden direkt in den Arbeitsspeicher geschrieben

-
Kommt drauf an!
Wenn Du z.B. flush aufrufst, dann wartet er wirklich, bis die Daten geschrieben wurden. Normalerweise werden sie in einen Puffer geschrieben, und wenn der voll ist, wird er auf die Platte geschrieben.
-
hm ok, aber beim nächsten frame werden die Daten denk ich mal ja dann wieder gelesen, bis dahin sind sich doch sicherlich noch nicht auf der hd. Das heist also man kann in den Puffer Daten schreiben und lesen noch bevor die geschriebenen Daten auf der hd gelandet sind. Dann wird so ein Puffer wohl unter anderem dazu verwendet das Programm vor dem völligen Stillstand zu bewahren wenn der ram voll ist. *n00bmäßige Vermutungen anstell* Vielleicht hat er den Puffer zu klein gemacht?