Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Black-Panther

Alter Hase

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

11

29.06.2007, 23:34

Also ich habs mit Sleep(anzahl der Millisekunden die noch fehlen); sowie mit der while(...) Sleep(0); variante probiert. Die erste kann man vergessen. Zumindest bei mir funktioniert diese gar nicht! Es gibt immer wieder unschöne Grafikfehler (Das Bild ist dann in Streifen geschnitten --> normalerweise nicht ein V-Sync problem?? KA, jedenfalls mit timebasedrendering passiert das nicht!). Mit der 2. variante gehts zwar besser aber oftmals treten dann doch diese streifen auf...

Hab mal versucht die Auflösung der Sleepfunktion drastisch durch die ::select(...) [WinSock] Funktion zu erhöhen, doch leider funktioniert das unter windows nicht... (nur linux, weil unter windows diese abbricht, wenn die sets alle NULL-Sets sind).

Wenn du mir mal deinen Code schicken könntest, mit dem das funktioniert, wäre ich dir dankbar...
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

rewb0rn

Supermoderator

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

12

30.06.2007, 00:44

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void AppManager::FramebasedRendering(void)
{
    static Ogre::Timer Timer;

    //Framebased rendering:

    if (TimePerFrame > 0.0)
    {
        while (Timer.getMilliseconds() < TimePerFrame) Sleep(1);
        TimePassed = TimePerFrame / 1000.0;
    }
    else
        TimePassed = double(Timer.getMilliseconds()) / 1000.0;

    Timer.reset();
}


das funktioniert so auf 1-2 frames pro sekunde genau.

Zitat von »"LagRange"«

Es geht hauptsächlich darum dass aufwändigere Physikinteraktionen die Framerate ganz schön drücken können. Man spart einiges an Rechenzeit wenn man die nicht so oft aufruft.

eben deswegen habe ich konstante framezeiten. für welche anderen elemente lohnen sich zusätzliche berechnungen?

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

13

30.06.2007, 07:53

Ich habe nicht alles gelesen, aber hier mal ein paar Kommentare ;)

1. Sleep(10) bedeutet: Lege den Thread mindestens 10 ms schlafen. Erst nach den 10 ms kann der Scheduler den Thread wieder auswählen, so dass er die CPU bekommt.

2. Ich mache es mittlerweile immer so: Die Spiellogik läuft mit einer festen Framerate, z.B. 50 fps. Nur so kann man wirklich garantieren, dass bei gleicher Eingabe auch immer dasselbe Ergebnis rauskommt. Das funktioniert nicht, wenn man es so macht wie ich in meinem Buch und alle Bewegungen mit der vergangenen Zeit multipliziert. Außerdem funktionieren Physik-Engines auch am besten, wenn man sie mit festen Zeitschritten arbeiten lässt.
Ich habe ein "Zeitkonto", das die Anzahl der noch zu verarbeitenden Millisekunden speichert.

C-/C++-Quelltext

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
30
31
32
33
34
35
const int STEP_SIZE = 20; // 50 fps

int timeToProcess = 0;
bool render = true;

while(!quit)
{
    int t0 = ZEIT_MESSEN();
    bool rendered = false;

    if(render)
    {
        RENDERN();
        render = false;
        rendered = true;
    }

    while(timeToProcess >= STEP_SIZE)
    {
        UPDATE();
        timeToProcess -= STEP_SIZE;
        render = true; // rendern, da Update erfolgte

    }

    int dt = ZEIT_MESSEN() - t0;
    timeToProcess += dt;

    // Zeitkonto nach oben hin begrenzen

    if(timeToProcess > MAX_TIME) timeToProcess = MAX_TIME;

    if(rendered) SZENE_ANZEIGEN();

    // Hier kann ein Sleep(0) nicht schaden, damit die Anwendung

    // nicht 100% CPU-Last erzeugt.

    Sleep(0);
}

LagRange

Frischling

Beiträge: 26

Wohnort: dzt. Aalborg, DK

Beruf: Student

  • Private Nachricht senden

14

30.06.2007, 11:50

Zitat von »"rewb0rn"«

Zitat von »"LagRange"«

Es geht hauptsächlich darum dass aufwändigere Physikinteraktionen die Framerate ganz schön drücken können. Man spart einiges an Rechenzeit wenn man die nicht so oft aufruft.

eben deswegen habe ich konstante framezeiten. für welche anderen elemente lohnen sich zusätzliche berechnungen?

Meine Überlegung war dass wenn sich z.B. Physikberechnungen nicht mit der gewünschten Framerate von 50fps durchführen lassen diese eben nur mit 20fps laufen, Grafikausgabe und Eingaben werden aber mit voller Framerate behandelt so dass für den Spieler zumindest die Illusion eines flüssigeren Spielablaufs entsteht.

Inzwischen kommen mir aber schon Zweifel ob sich das lohnt ;)
Science is common sense applied to evidence.

Black-Panther

Alter Hase

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

15

30.06.2007, 12:16

@David
Mulitplizierst du jetzt GAR nichts mehr mit der Zeit??

Und warum machst du es nicht einfach so:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
const float fUpdatePeriod = 1.f / 30.f;
while(!bQuit)
{
    m_fTime += fDeltaTime;
    if(fLastUpdate + fUpdatePeriod <= m_fTime)
    {
        //move, render und present

        fLastUpdate = m_fTime;
    }
}


Irgendwie kommt mir deine Version reichlich umständlich vor, oder hab ich da einen Vorteil übersehen?? :?:
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

16

30.06.2007, 12:40

Zitat von »"Black-Panther"«

@David
Mulitplizierst du jetzt GAR nichts mehr mit der Zeit??

Da die Zeitschritte immer gleich groß sind, ist das nicht notwendig, zumindest nicht dynamisch. In einer Update-Methode könnte natürlich schon noch die konstante Schrittgröße vorkommen.

Zitat von »"Black-Panther"«


Und warum machst du es nicht einfach so:
(...)

Meinst du jetzt mit konstanter Schrittgröße? Falls ja: Damit kannst du nicht sicherstellen, dass das Spiel immer mit derselben Geschwindigkeit läuft. Wenn ein Frame einmal länger gedauert hat als üblich, würde deine Methode danach nur ein Update machen, obwohl mehrere nötig wären.

Konstante Schrittgröße hat auf jeden Fall viele Vorteile. Das Spiel liefert, wie gesagt, bei der gleichen Eingabe immer das gleiche Resultat. Das kriegt man mit dynamischen Schrittgrößen nicht hin. Man kann dann Dinge wie "Aufnehmen & Abspielen" viel leichter realisieren. Die Update-Methoden sind dann außerdem einfacher zu schreiben.

17

30.06.2007, 14:25

nochmal danke für die ganzen antworten.

ich geh jetzt mal auf einiges ein:

Zitat


2. Ich mache es mittlerweile immer so: Die Spiellogik läuft mit einer festen Framerate, z.B. 50 fps. Nur so kann man wirklich garantieren, dass bei gleicher Eingabe auch immer dasselbe Ergebnis rauskommt. Das funktioniert nicht, wenn man es so macht wie ich in meinem Buch und alle Bewegungen mit der vergangenen Zeit multipliziert. Außerdem funktionieren Physik-Engines auch am besten, wenn man sie mit festen Zeitschritten arbeiten lässt.
Ich habe ein "Zeitkonto", das die Anzahl der noch zu verarbeitenden Millisekunden speichert.


also, wenn ich das richtig verstehe, wird dort rendern von aktualisiern von physik, positionen etc getrennt. ich hab allerdings noch ein paar fragen zu dem code:

C-/C++-Quelltext

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
30
31
32
33
34
35
const int STEP_SIZE = 20; // 50 fps

int timeToProcess = 0;
bool render = true;

while(!quit)
{
    int t0 = ZEIT_MESSEN();
    bool rendered = false;

    if(render)
    {
        RENDERN(); //Hier werden die Polygone gerendert aber noch nciht angezeigt oder?

        render = false;
        rendered = true;
    }

    while(timeToProcess >= STEP_SIZE) //muss das nicht <= heißen? weil hier wird ja solange geupdated bis die stepsize erreicht ist. wenn ich das richtig verstehe^^

    {
        UPDATE();
        timeToProcess -= STEP_SIZE; //warum zieht man hier die step size ab?

        render = true; // rendern, da Update erfolgte

    }

    int dt = ZEIT_MESSEN() - t0;
    timeToProcess += dt;

    // Zeitkonto nach oben hin begrenzen

    if(timeToProcess > MAX_TIME) timeToProcess = MAX_TIME;

    if(rendered) SZENE_ANZEIGEN(); //Warum trennst du rendern und anzeigen?


    // Hier kann ein Sleep(0) nicht schaden, damit die Anwendung

    // nicht 100% CPU-Last erzeugt.

    Sleep(0);
}



Noch etwas, sollten nicht 30 Updates pro Sekunde reichen?

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

18

30.06.2007, 14:44

timeToProcess speichert, wie viele Millisekunden noch verarbeitet werden müssen. Immer, wenn dieser Wert STEP_SIZE erreicht, wird ein Update gemacht und STEP_SIZE abgezogen (solange, bis der Wert wieder unter STEP_SIZE liegt). timeToProcess ist das "Zeitkonto".

Rendern und Anzeigen werden getrennt, weil man beim Anzeigen u.U. warten muss, bis die Grafikkarte mit dem Rendern fertig ist. Darum zuerst rendern (Grafikkarte mit Aufträgen versorgen), dann updaten (während die Karte rendert) und anschließend anzeigen.

30 Updates pro Sekunde sind normalerweise zu wenig. Man merkt dann immer noch ein gewisses Ruckeln. 50 ist gut.

19

30.06.2007, 14:54

ok, ich habs verstanden. also ist das trennen von rendern und anzeigen praktisch eine performance verbesserung, weil während die graka rendert macht die cpu schon das update für den nächsten frame?

edit: hat man dann nicht das problem das sich evlt schon koordinaten verschieben während des renderns? weil das müsste dann ja in 2 threads ablaufen.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

20

30.06.2007, 17:20

Nein, das ist völlig ausgeschlossen.
Wie sollte das denn deiner Meinung nach möglich sein?

Werbeanzeige