PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Qt/OpenGL] Frame-Bremse, aber wie richtig?



Miles
28-08-2003, 21:38
Ich bin - wie das einige vielleicht mitverfolgen - schon eine ganze Weile auf der Suche nach einer guten Ergänzung zu OpenGL bzw. wie ich es in Linux implementieren soll. Jetzt bin ich doch zu dem Schluss gekommen, dass Qt fürs Erste die Beste Wahl ist.

Mit einem normalen Fenster bekomme ich bei einer mehr oder weniger geringen Berechnung 400-5000 (!) fps zusammen, je nach dem, wie groß das Fenster ist.

Das liegt vorallem daran, dass ich noch keine Frame-Bremse eingebaut habe. Und genau da liegt das Problem:
In meinem QGLWidget wird die updateGL-Funktion mit einem QTimer aufgerufen.

Das läuft alles super - solange der QTimer mit dem Millisekunden-Wert 0 initialisiert wird. Also dass er so oft wie möglich das Bild updatet. Da meine Berechnungen (z.B. die Rotation) direkt mit der Zeichenfunktion zusammenhängt und da 500 fps überflüssig sind muss ich eine Frame-Bremse einbauen.

Also:
Wenn ich 50 fps (was noch viel zu hoch ist, aber das Problem verdeutlichen soll) erreichen will, muss ich den QTimer mit 20 ms initialisieren. Klar, oder?

PROBLEM:
Das Programm läuft jetzt (bei SEHR wenigen Objekten) scheinbar nicht mehr flüssig, da anscheinend die "Sprünge" bei der Rotation zu groß sind. (da das Bild nur noch 50 statt 500 mal/s aufgebaut wird)
Das ist für mich die einzige Erklärung.

Wie kann ich in mein Programm aber eine Frame-Bremse einbauen, die aber nicht das Bild von der Logik her verlangsamt? (Die 50 fps würde mehr als ausreichen, für die "Sprünge" der Rotation aber nicht.)

Vielleicht liegt das Problem aber auch an etwas anderem. Jedenfalls scheint das Bild in Bewegung trotz 50 fps nicht flüssig zu sein. Erst ab 200 fps oder mehr. HEEEEEEEEEEEEEE????????????????


Hoffe mich versteht jemand.
Bitte um Antwort.
Euer Miles, ein bisschen verzweifelt =P

wraith
28-08-2003, 21:55
Deine Lösung ist nicht eine Frameratebremse.
Du mußt für jeden Frame berechnen wie lange dieser gedauert hat,und alle deine Berechnungen von diesem Wert abhängig machen.
Also am Frameanfang einen Wert holen (zb. mit clock),und am Frameende nochmal einen Wert holen,und mit der Differenz im nächsten Frame deine Berechnungen machen.

Zum Timer:
Gibt es für Qt keine bessere Lösung?Timer sind schlecht,eigentlich mit das Dümmste.

Miles
28-08-2003, 22:33
Hm. Wenn ich das richtig verstanden habe soll das dann so aussehen?



void PPCGLWidget::paintGL(void)
{ static int fps=1,RemSecond=0;
static char AuxString[20];
int Time0,Time1;

// Start-Zeit berechnen
m_pTime->restart();
Time0=((m_pTime->hour()*60+m_pTime->minute())*60+m_pTime->second())*1000+m_pTime->msec();

// Berechnungen durchführen

// Rotationen neu berechnen
rotX+=m_fAddX;
rotY+=m_fAddY;
rotZ+=m_fAddZ;

// solange in der Schleife bleiben, bis 20 ms vorbei sind (50 fps).
do
{ m_pTime->restart();
Time1=((m_pTime->hour()*60+m_pTime->minute())*60+m_pTime->second())*1000+m_pTime->msec();
}while(Time1-Time0<20);
}


Ich hoffe nicht. Denn das hat absolut nichts daran geändert. ^^''
(BITTE SAGT MIR, WIE ICH SOETWAS OHNE QTIMER IN QT REALISIERE!! =P)

Könnte es daran liegen, dass die Bilder, die ich erzeuge nicht synchron zum Bildschirm aufgebaut werden? Wenn ja - wie finde ich die Bildfrequenz heraus und was muss ich dabei beachten (vertikal, horizontal,...) ???

axeljaeger
29-08-2003, 09:14
Es ist generell üblich, bei 3D Animationen den Bildschirm so oft wie möglich neu zu zeichnen. Das erledigt ein QTimer mit Interval 0. Das heist, das der Timer bei jedem Durchgang der Qt-mainloop ein timeout() feuert. Du kannst ein QTime-Objekt benutzen, wenn deine Animation startet, QTime::start() aufrufen und dann immer beim neuzeichnen mit QTime::elapsed() feststellen, wie viel Zeit seit Programmstart vergangen ist und deine Animation entsprechend weiter berechnen.

Miles
29-08-2003, 11:03
Hm. Meinst du jetzt, dass ich das Bild einfach immer neu aufbauen lassen soll und nur die Berechnungen (Rotationen zum Beispiel) mit einer Bremse versehe?

So erscheint es mir am logischsten.

Miles
29-08-2003, 11:39
Ich glaube ich hab jetzt die beste Lösung gefunden. Ich lass die Frames so schnell wie möglich brechnen, auch wenn das 400 fps sind und die Rotation wird insofern "gebremst", indem ich sie indirekt proportional zu den fps verlangsamere. Sprich: Mehr fps, weniger Rotation pro Frame -> gleichviel Rotation pro Sekunde. :)

axeljaeger
29-08-2003, 13:04
Nein, so nicht. Angenommen, du hast ein Auto, so berechnest du die Position vom Auto so:

pos = startpos * a * timesincestart.

Wenn ich dich richtig verstanden habe, hast du was änliches vor, aber komplizierter. Aber ich nen Link für dich:

http://www.gametutorials.com/Tutorials/OpenGL/OpenGL_Pg1.htm (das letze auf der Seite, es gibt sogar einen SDL-Port