Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Sa Dez 21, 2024 15:55

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Ruckeln bei Verschiebung
BeitragVerfasst: So Nov 25, 2018 19:46 
Offline
DGL Member

Registriert: Di Feb 13, 2018 19:02
Beiträge: 24
Programmiersprache: Java
Hallo,

ich arbeite gerade an einem Android-Game (mit Java / OpenGL ES 2.0). Wenn ich im Spiel, bzw. in OpenGL Objekte verschiebe, dann ruckeln diese Objekte immer wieder, in regelmässigen Abständen.

Das ganze sieht dann etwa so aus, wie hier in diesem Video:
- https://www.youtube.com/watch?v=5DXuYuaabvM&list=LLCWsOHjUzuJNUKdDzinU_KA&index=8&t=0s

Die Qualle in den Video ruckelt auch sehr stark. Und so ähnlich, ist es auch bei mir.



Am Programmanfang setze ich den Rendermode auf "RENDERMODE_CONTINUOUSLY":
Code:
  1. glSurfaceView.setRenderMode( GLSurfaceView.RENDERMODE_CONTINUOUSLY );


In onDrawFrame() findet dann die Berechnung (Verschiebung) der Objekte statt, direkt danach werden sie auch gezeichnet. Vereinfachte Darstellung:
Code:
  1.     public void onDrawFrame(GL10 glUnused)
  2.     {
  3.         objektverschiebung_berechnen();
  4.  
  5.         GLES20.glDrawArrays(...);
  6.     }


Wenn ich zu Beginn von onDrawFrame() die weitere Ausführung um ca. 10ms stoppe, dann wird das Ruckeln besser.


Habt ihr eine Idee wie ich das in den Griff kriegen kann?


Vielen Dank,
arenas


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ruckeln bei Verschiebung
BeitragVerfasst: So Nov 25, 2018 20:19 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
Benutzt du Timebased Movement?

Und unabhängig davon: Im Video fällt auf, dass die Qualle sich nicht synchron mit der Kamera bewegt, obwohl scheinbar beabsichtigt ist, dass die Qualle immer in der Mitte des Bildes sein soll. Daher lohnt es sich wahrscheinlich, anzuschauen, wo sich der Code zur Bewegung der Kamera vom Code zur Bewegung der Qualle unterscheiden.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ruckeln bei Verschiebung
BeitragVerfasst: So Nov 25, 2018 20:41 
Offline
DGL Member

Registriert: Di Feb 13, 2018 19:02
Beiträge: 24
Programmiersprache: Java
Zitat:
# Benutzt du Timebased Movement?


Ja, die Verschiebung ist bei mir abhängig von der Zeit. Pro Aufruf von onDrawFrame() werden so zwischen 15-22ms benötigt.

Die Zeitspanne (in ms) seit dem letzten Aufruf wird an die Verschiebefunktion übergeben:
Code:
  1. objektverschiebung_berechnen( zeit_differenz );


Der Wert der genauen Verschiebung ist dann abhängig von der Framezeit. Hier soll die Verschiebung 5 Einheiten pro Sekunde betragen:
Code:
  1. void objektverschiebung_berechnen()
  2. {
  3.    float verschiebung_x = zeit_differenz * ( 5.0f / 1000 );
  4.    kamera_verschiebung_x = kamera_verschiebung_x  + verschiebung_x;
  5. }


Das Video mit der Qualle ist nicht von mir, bzw. nicht mein Projekt. Es zeigt nur auch das Ruckeln so ähnlich wie bei mir auf.

Woran könnte es sonst noch liegen?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ruckeln bei Verschiebung
BeitragVerfasst: So Nov 25, 2018 20:55 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
15-22 ms sind grundsätzlich kurz genug, um die Illusion einer flüssigen Bewegung aufrechtzuerhalten. Möglicherweise hast du es aber mit Mikrorucklern zu tun. Diese treten auf, wenn die Zeit zweier aufeinander folgender Frames sehr unterschiedlich ist. Dies kann z.B. dadurch passieren, dass die Java-Runtime plötzlich auf die Idee kommt, Speicher aufzuräumen (dazu muss sie das Programm kurz anhalten) oder dadurch, dass das Programm auf das Display wartet, dass sich mit fester Frequenz aktualisiert (nur wenn V-Sync an ist).

Die von dir verwendete Klasse GLSurfaceView ist mir nicht bekannt. Hat der Rendermode etwas mit V-Sync zu tun oder was macht der?

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ruckeln bei Verschiebung
BeitragVerfasst: So Nov 25, 2018 21:08 
Offline
DGL Member

Registriert: Di Feb 13, 2018 19:02
Beiträge: 24
Programmiersprache: Java
Für setRenderMode gibt es zwei Konstanten "RENDERMODE_CONTINUOUSLY" und "RENDERMODE_WHEN_DIRTY".

- Bei RENDERMODE_CONTINUOUSLY wird onDrawFrame() immer wieder aufgerufen, so zusagen in Endlosschleife.
- Bei RENDERMODE_WHEN_DIRTY wird onDrawFrame() nur dann ausgeführt, wenn die Anweisung durch glSurfaceView.requestRender(); gegeben wird.

Die Zeit zwischen den Frames ist immer relativ konstant, sie liegt in der Regel zwischen 16-19ms. Grössere Ausschläge, wie z.B. 200ms gibt es nicht. Das kan ich ausschliessen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ruckeln bei Verschiebung
BeitragVerfasst: So Nov 25, 2018 21:23 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
Naja, die Millisekunden misst du doch in deinem Programm, oder? Falls der Grafiktreiber im Hintergrund Triple-Buffering betreibt, unterscheidet sich die Ausgabe des Displays zeitlich von der Frame-Fertigstellung deines Programms. Das sollte dann aber zu keinen allzu krassen Mikrorucklern führen.

Interessant zu wissen wäre noch, ob bei dir nur bestimmte Objekte ruckeln oder ob es das ganze Bild in gleicher Weise betrifft.

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ruckeln bei Verschiebung
BeitragVerfasst: Di Nov 27, 2018 09:40 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2622
Wohnort: Berlin
Programmiersprache: Go, C/C++
Es wäre praktisch die Spikes zu tracken. Meine erste Vermutung ist sehr einfach. Der Garbage Collector tut I'm Hintergrund aufräumen und dafür hält er alle threads an. Je nach dem, wieviel Dreck anfällt hast du Dan alle paar Sekunden ein frame mit z.b. 30ms und dann spielt die Art der time based Funktion eine große Rolle, weil die eventuell über kompensiert. Es kann auch passieren, dass du 1000fps hast und alle 2s Dan ein frame auf 120ms rutscht. Da hab ich mir in C# mit dem GC schon öfter ein Kampf geliefert. Die erste Lösung wäre den GC jeden Frame, als letztes auf zu rufen. Damit verteilt sich die last des GC auf jeden frame, statt auf einen, alle paar Sekunden. Ist es der GC und der brauch immer noch zu lange, dann muss man mit nem diagnostik Tool die Gründe für den garbage suchen und den Teil umschreiben. Ein Kumpel von hatte da diverse Basis Klassen angepasst, damit sein game gar kein garbage mehr wirft und somit frei vom GC war. Das ist der Hauptgrund für C++ in der game Industrie, gegenüber c# und Java. Unity hat sämtlichen engine code in c++ geschrieben und benutzen im high level c# code ausschließlich eigene Klassen mit Caches,um die Grundlast gering zu halten und stabile frame Zeiten zu bekommen. Ein mieses UI plugin, welches die text Werte jeden Frame neu zusammen Schuster und es ist vorbei.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ruckeln bei Verschiebung
BeitragVerfasst: Di Nov 27, 2018 23:53 
Offline
DGL Member

Registriert: Di Feb 13, 2018 19:02
Beiträge: 24
Programmiersprache: Java
Es scheint wirklich der Garbage Collector zu sein, der die Probleme verursacht. Werde das jetzt mal genau testen. Melde mich dann nochmal...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ruckeln bei Verschiebung
BeitragVerfasst: Fr Nov 30, 2018 20:55 
Offline
DGL Member

Registriert: Di Feb 13, 2018 19:02
Beiträge: 24
Programmiersprache: Java
Das Problem scheint der Garbage Collector zu sein. onDrawFrame() braucht für einen Durchlauf durchschnittlich 17ms, was absolut in Ordnung ist. Dazwischen gibt es jedoch immer wieder Sprünge auf bis zu fast 50ms. Und daher kommt auch das regelmässige ruckeln beim Verschieben. Es tritt so ca. 1x pro Sekunde auf.

Ich rufe jetzt am Ende von onDrawFrame() den Garbage Collector manuell auf. Dadurch wurde das ganze ein wenig besser. Die Sprünge sind aber immer noch bei ca. 40ms.

Was kann ich da noch machen? Bin total verzweifelt. Muss ich mich jetzt auch noch in C++ einarbeiten???? :cry:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ruckeln bei Verschiebung
BeitragVerfasst: Sa Dez 01, 2018 08:40 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Aug 14, 2013 21:17
Beiträge: 588
Programmiersprache: C++
Wie TAK schon geschrieben hat, kannst du auch schauen, an welchen Stellen dein Programm "Garbage" verursacht und versuchen, das zu vermeiden. Immer, wenn du irgendwo einer Referenz eine neue Speicheradresse zuweist, verwaist die alte*. Immer wenn eine Referenz zerstört wird, weil das Programm ihren Scope verlässt, verwaist der Speicherbereich, auf den sie zeigt*. Das kann man versuchen zu vermeiden und dem Garbage Colloector dadurch etwas Aufräumarbeit ersparen. Bestimmt gibt es Tools, die dein Programm analysieren und dir die entscheidenden Stellen im Code aufzeigen können. Da kenne ich mich aber nicht aus.

*vorausgesetzt, es gibt keine zweite Referenz die auch dorthin zeigt

_________________
So aktivierst du Syntaxhighlighting im Forum: [code=pascal ][/code], [code=cpp ][/code], [code=java ][/code] oder [code=glsl ][/code] (ohne die Leerzeichen)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Ruckeln bei Verschiebung
BeitragVerfasst: Sa Dez 01, 2018 15:11 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2622
Wohnort: Berlin
Programmiersprache: Go, C/C++
Das schöne ist, du hast mit Java da die besser unterstützte Sprache, im vergleich zu C#. Es gibt diverse Tools und Boardmittel um sich dinge genauer an zu gucken.
Ich hab mal kurz gegoogelt und folgendes gefunden.
Java GC monitoring

Was du suchst ist ein GC Profiler, Tracer oder Monitoring, welches dir sagt was der GC denn eigentlich macht.
Da du 16-17ms Intervalle hast, vermutlich durch VSync, bedeutet es, du hast 60 Durchläufe deines Codes pro Sekunde.
Solltest du z.B. ein Statistik Screen rendern, welcher jeden Frame die Strings neu baut, statt diese einmal in einer Klasse zu behalten und diese nur an zu passen, dann erzeugst du halt für jede String operation das 60zig fache an Objekten pro Sekunde.
Also line[i]="Player "+i.ToString()+" ("+players[i].Name+")"+" "+players[i].Points.ToString(); für 10 Spieler würde pro GC Aufruf zu 10*60*4=2400 String Objekte führen, die er weg räumen muss, auch nur, wenn er so klever war die statischen Strings global an zu legen und für das zusammen fügen keine temporären instanzen an zu legen, sonnst wird es noch schlimmer.
Der GC von Java ist extrem gut optimiert aber selbst bei vielen Tausend Objekten trifft dann Random Access und cold cache zu, was den GC nicht auf CPU sondern Speicher Geschwindigkeit limitiert.

Also keine Panik, du brauchst kein C++ um das Problem zu lösen, vor dir haben auch schon diverse andere Entwickler erfolgreich mit Java komplexe 3D Spiele geschrieben. Es braucht nur mehr Zeit bei der Speicherverwaltung, im Vergleich zu C++ aber man spart ja unmengen an Zeit bei diversen anderen Bereichen.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: Bing [Bot] und 4 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.011s | 16 Queries | GZIP : On ]