2017-01-07 1 views
3

Ich versuche, ein einfaches OpenGL-Spiel auf MacOS, mit einem NSTimer einzurichten, um eine Lauf-Schleife wie erläutert here. Die Idee ist, einen Wiederholungstimer mit einem sehr kleinen (~ 1ms) Zeitintervall zu erstellen und sich auf vsync zu verlassen, um die Bildrate zu regulieren.OpenGL VSync/NSTimer Probleme auf macOS

Ich setze mein NSOpenGLContext Auslagerungsintervall auf einen Wert von 1, der Vsync aktivieren sollte. Ich hatte den Eindruck, dass dies NSOpenGLContext.flushbuffer blockieren würde, aber das scheint nicht der Fall zu sein. Mein Rendercode feuert viel häufiger als 60 Mal pro Sekunde.

Das Dokument, das ich verlinkt habe wurde als im Ruhestand markiert, aber alle offiziellen Dokumentation, die ich gelesen habe, deutet darauf hin, dass es möglich ist, eine NSTimer Schleife auf die Bildwiederholfrequenz irgendwie zu drosseln. Ich konnte das nicht schaffen, und ich frage mich, ob dieser Ansatz nicht mehr praktikabel ist.

Fehle ich etwas? In einem modernen Projekt ist es besser, nur mit einem CVDisplayLink zu gehen?

Antwort

2

Mein Verständnis ist, dass es unwahrscheinlich ist, dass eine NSTimer häufiger als etwa 10-20 Mal pro Sekunde feuern wird, und mit Timer Koaleszenz Sie wahrscheinlich nicht garantiert Feuerzeiten für diese Art von Anwendung geeignet sind. Zum Beispiel weist one answer to this question hin, dass die docs sagen:

Aufgrund der verschiedenen Eingangsquellen eine typische Laufschleife, die effektive Auflösung des Zeitintervalls für einen Timer beschränkt sich auf in der Größenordnung von 50-100 Millisekunden verwaltet . Wenn die Auslösezeit eines Timers während eines langen Callouts auftritt oder wenn sich die Laufschleife in einem Modus befindet, der den Timer nicht überwacht, wird der Timer erst ausgelöst, wenn die Laufschleife das nächste Mal den Timer überprüft. Daher kann die tatsächliche Zeit, zu der der Zeitgeber möglicherweise ausgelöst wird, eine erhebliche Zeitspanne nach der geplanten Auslösezeit sein.

CVDisplayLink ist definitiv die bevorzugte Lösung. Es ist auch ziemlich einfach zu benutzen.

Und um Ihre andere Frage zu beantworten, hat sich ja etwas geändert. Das Betriebssystem hat die Handhabung von Timern geändert, um die Energieleistung zu verbessern. Ich habe an einer App gearbeitet, die bis OS 10.9 oder 10.10 die von Ihnen vorgeschlagene Methode verwendet. Sobald das herauskam, mussten wir unsere Strategie überdenken, weil Timer anders funktionierten.