FPS-Kontrolle

Symla

Grünschnabel
Hallo,

Da ich gerade an einem "Spiel" arbeite und ich noch nicht allzu viel Erfahrung im Bereich Grafik mit Java besitze wollte ich fragen, ob meine selbst "ausgedachte" Methode zur FPS-Kontrolle sinnvoll ist. Der grund für "Feedback" ist, da ich sogar bei eingestellten 1000fps ein gleiches Ergebnis wie bei 60fps bekomme (keine Unterschiede bei CPU und GPU) :confused: .... :

Java:
	public void repaintAll(int startat, int periode) {
		Timer fpsc = new Timer("fpscounter");
		TimerTask fpstask = new TimerTask(){
			public void run() {
				repaint();
				frames++;
			}
		};
		fpsc.schedule(fpstask, startat, 1000/periode);
	}

Hoffe jemand kann mir eine Erklärung geben oder gegebenenfalls eine Verbesserung bringen ...


Peter
 

Muepe32

Erfahrenes Mitglied
Hallo Peter

Ich weiss jetzt nicht was für eine Library du verwendest, aber in der Regel synchronisieren alle Bibliotheken die (3D-) Graphikpipeline mit der Bildwiederhofrequenz des Monitors, welcher in der Regel auf 60 Hz eingestellt ist. Wenn es darunter fällt springt er auf die halbe Frequenz, also 30 Frames pro Sekunde. Wenn das Rendern zu früh dran ist blockiert er einfach so lange bis auch der Bildschirm bereit ist. Grund dafür ist dass es überhaupt nichts bringt mehr als 60 (eigentlich schon mehr als 30) mal pro Sekunde das Bild zu refreshen, das Auge merkt ab ca 28 Frames keinen Unterschied mehr.

Die meisten Bibliotheken ermöglichen es in der Regel auch VSync auszuschalten.

Grüsse
Muepe
 

slowfly

Erfahrenes Mitglied
Ich bin da nicht ganz mit der Aussage von Muepe bezüglich Wiederholfrequenz/FPS/menschliches Auge einverstanden.

Das kann man am Besten veranschaulichen, wenn man's mal probiert zu programmieren: Bewegt mal ein Quadrat von 20*20 Pixel auf dem Bildschirm von Pos 0,0 nach 1920,0. Und das innert einer Sekunde. Einmal mit 30fps, einmal mit 60.
Bei 30fps muss ich das Quadrat pro Frame um 64 Pixel verschieben, bei 60fps 32. Und auch das sieht nicht sonderlich aus.
Was man jetzt machen kann, weitere Zwischenbilder berechnen. Zwischenbilder würde man dann jeweils dazurenderen. Also zwischen Position 0,0 und 60,0 - bei einem "Zwischenbild" wär's 30,0 - gibt's noch ein halb-transparentes Quadrat, welches bewirkt, dass das Auge das ganze eher als Bewegung wahrnimmt. Natürlich kann man nicht nur _ein_ Zwischenbild reinrendern, das können auch viel mehr sein - schlussendlich ist es dann das, was ein Fernseher macht, denn der bekommt sein Bildmaterial auch nur mit 24 oder 25 fps.

Gruss
slowy
 

Symla

Grünschnabel
Danke erstmal für die Antworten!

Ich habe mir jedoch jetzt was einfallen lassen. Ich hab einen neuen Thread gemacht, welcher immer wieder den ganzen Frame mit allen dazugehörigen Elementen neuzeichnet. Dann habe ich eine Pause eingebaut ( Thread.sleep(****); ). Diese ist genau so lang, dass der Thread die Methode repaint(); genau 60mal in der Sekunde ausführt ... funktioniert auch besser als der Timer!


Peter