28

SEP09

Mainloop, FPS, Framebremse und VSync …

Trackback URIVon Peppie in C++, Programmierung, Spiele-Entwicklung

Die Framebremse

Lasst mich euch ein paar Codeschnippsel zeigen die ich im Internet gefunden habe, wie man es machen kann aber besser nicht sollte.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
RECT Rectangle = { 10, 100, 100, 120 };

int startzeit;

while( !bQuit )
{
    if( PeekMessage( &WindowMessages, NULL, 0, 0, PM_REMOVE) )
    {
        ...
    }
    else
    {
        startzeit = GetTickCount();

        // Frame neu malen
        DrawText( hdc, calcFPS(), 32, &Rectangle, DT_LEFT );

        while( (GetTickCount() - startzeit ) < 10 );
        {
            // Hier passiert nichts ;)
        }
    }
}
...

Wenn ich diese Art von Framebremse benutze bekomme ich statt meinen ~4k Frames nur noch rund 64 FPS. Hier eine weitere Variante die mich nicht mehr auf dem Stuhl gehalten hatte

1
2
3
4
5
6
7
8
9
10
11
12
13
...
}
else
{
    // Frame neu malen
    DrawText( hdc, calcFPS(), 32, &Rectangle, DT_LEFT );

    for( int i=0; i<1000000; i++ )
    {
        // Hier passiert nichts ;)
    }
}
...

Also ersteres findet ihr sogar in meinem Pong und sogar in meinem Frozenbubble Clone wieder, ich hab damals auch nur die erst beste Variante genommen, aber die zweite Variante ist mal echt übel. Also bitte liebe Leser, die erste Variante lass ich ja noch durchgehen aber von der zweiten Variante solltet ihr lieber die Finger lassen. Die Variante die ich euch empfehlen kann ist, die Bewegung der Objekte mit der vergangenen Zeit des letztens Frames zu Multiplizieren. ;)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
...
UINT uiLastRound        = 0;
UINT uiDeltaTime        = 0;
float PositionX            = 0.0f;

while( !bQuit )
{
    if( PeekMessage( &WindowMessages, NULL, 0, 0, PM_REMOVE) )
    {
        ...
    }
    else
    {
        uiLastRound = GetTickCount();

        // Frame neu malen
        DrawText( hdc, calcFPS(), 32, &Rectangle, DT_LEFT );

        Rectangle.left = static_cast<LONG>( PositionX );
        Rectangle.right = Rectangle.left + 90;

        // deltaTime berechnen
        uiDeltaTime = ( GetTickCount() - uiLastRound );

        // deltaTime mit Bewegung multiplizieren
        PositionX += ( 0.05f * uiDeltaTime );
    }
}
...

In diesem Beispiel wollen wir das unsere Objekt xPixel pro Sekunde nach links wandert. Da wir nur Ganzzahlen, für jeden Pixel, darstellen können, wir aber viele kleine Schritte machen werden, müssen wir eine Position als Float definieren. Mit unserem static_cast wird dann von diesem aktuellen Wert immer die Nachkommestellen abgeschnitten. Wenn jetzt jemand mit einem langsamen Rechner dies ausführt, wird nach eine Zeit von X die Position die gleiche sein wie auf einem schnelleren Rechner. Der schnelle Rechner macht zwar viele kleine Schritte aber auch wenige größere Schritte bringen uns auf die gleiche Position ;)

Das ganze Thema mit Framebremse hin oder her zählt je nur bei Rechnern auf denen kein VSync vorhanden oder abgeschaltet ist. Was ist das eigentlich und was macht es genau?

VSync – Vertikale Synchronisation

Ich möchte hier jetzt nicht ausschweifend werden, kurze erklärung zu VSync. VSync verhindert das die Grafikkarte ein weiteres Bild rüber schickt bevor dies überhaupt beim Monitor angekommen ist, somit hat mein quasi eine Framebremse die sich nach der eingestellten Frequenz des Monitors richtet. Genauere Informationen über VSync bekommt ihr schön erklärt in Wikipedia unter http://de.wikipedia.org/wiki/Vsync

Auf folgender Seite findet ihr ein Code-Snippet mit dem ihr VSync Anwendungsgesteuert aus und anschalten könnt. http://dotnet-snippets.de/dns/deaktivieren-von-vsync-unter-opengl-SID860.aspx

Das wars eigentlich auch schon mit diesen Themen der Spieleentwicklung. Ich wünsch euch viel Spaß beim programmieren.
P.S. Wenn ihr die FPS Berechnung und die für DeltaTime in eine Klasse packt dann habt ihr das alles schön kompakt zusammen ;)

Seite:
1 2

Peppie
Über den Autor:
Vor mehr als 6 Jahren habe ich mein Hobby zum Beruf gemacht. Seit her bekommt mich kein Problem so schnell in die Knie, ich bin sehr verbissen und arbeite solange an einem Problem bis es gelöst ist.

Ähnliche Artikel:

Kommentar schreiben

;) :( :) :D :P :o :| ^^ :> :< :cry: :S xD


Blogverzeichnis - Blog Verzeichnis bloggerei.de frisch gebloggt Blog Top Liste - by TopBlogs.de Bloggeramt.de Add to Technorati Favorites Dennis bei Xing Wikio - Top Blog