Autor Wątek: fps w czasie rzeczywistym  (Przeczytany 14052 razy)

Offline shyha

  • Użytkownik
    • Shyha@Flickr

# Sierpień 31, 2006, 09:05:57
Wybor klatki do animacji też musisz uzależnić od czasu (z tego co piszesz, zrozumiałem, że nie masz tego).

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

st3tc

  • Gość
# Sierpień 31, 2006, 17:22:59
u mnie petla glowna aplikacji wyglada tak:

{
FPS++;

lastFrameTime = GetTickCount() - helperTime;
helperTime = GetTickCount();

UpdateCamera(keys, 0.1f *lastFrameTime/15.0f);
Render();
SwapBuffers(hDC);
}

tylko ze amiast GetTickCount znacznie lepiej jest uzyc QueryPerformanceCounter. przy przy GTC moga sie pojawic drobne "rwania", ktorych przy QPC nie bedzie. ale jak juz bedziesz uzywac QPC to tez musisz pobrac czestotliwosc za pomoca QueryPerformanceFrequency i lastFrameTime podzielic przez otrzymana czestotliwosc

Offline Krzysiek K.

  • Moderator
    • DevKK.net

# Sierpień 31, 2006, 18:11:31
maxest: GetTickCount() (czy cokolwiek innego) wywołuj tylko raz na klatkę (użyj zmiennej pomocniczej). W Twoim kodzie może się zdażyć tak, że GTC tyknie pomiędzy dwoma wywołaniami w tym samym obiegu i przegapisz nieco czasu. Oczywiście to jest mało prawdopodobne, ale zawsze możliwe, pozatym z takim błędem Twój kod wygląda niezbyt profesjonalnie. :)

st3tc

  • Gość
# Sierpień 31, 2006, 18:43:59
Wybor klatki do animacji też musisz uzależnić od czasu (z tego co piszesz, zrozumiałem, że nie masz tego).
Oczywiscie, uzalezniam klatke animacji od czasu. Ale to jest gra typu TPP z mozliwoscia obrotu kamery w okol gracza. Wiec najbardziej to widac jak ustawie kamere z boku, a graczem i de do przodu. Gracz caly czas jest na srodku ekranu prawda? I tak chyba powinno byc. A, ze przemieszcza w kazdej klatce sie o rozny odcinek drogi to wszystko skacze. Do mierzenia czasu uzywam aktualnie QueryPerformanceCounter i QueryPerformanceFrequency. Ale ktorej metody bym nie uzywal to dzieje sie dokladnie to samo z oczywistych wyzej wymienionych przyczyn :).

Moze jest to wina mojego sposobu animowania. Ja robie to tak, ze kiedy postac przemieszcza sie z punktu A do B, to caly czas, z kazda klatka rownomiernie ja przesuwam z dana predkoscia (przesuniecie zalezy od czasu ostatniej ramki), i jednoczesnie ja animuje, tzn. wyswietlam animacje chodzenia(ktorej szybkosc rowniez zalezy od czasu ostatniej ramki. Animacja jest zrobiona w ten sposob, ze jest caly czas w danym punkcie wzgledem lokalnego ukladu wspolrzednych). Momentami wyglada to niezbyt profesjonalnie bo nawet w momencie kiedy postac ma postawiona stope na ziemi ta stopa przesuwa sie wzgledem podloza. Chyba powinno byc tak, ze animujac postac ona przesuwa sie tylko wzgledem swojego lokalnego ukladu wspolrzednych, a kiedy zrobi PELNY krok (tzn. pierwsza klatka bedzie taka sama jak ostatnia tylko przesunieta o pewna odleglosc) wtedy caly obiekt przemiesczam o ta odleglosc. Tylko jak wtedy sterowac kamera, zeby byla plynnie przesuwana, a jednoczesnie zeby nie bylo "rwan". Pomozcie.
« Ostatnia zmiana: Sierpień 31, 2006, 18:47:35 wysłana przez kosmonauta »

st3tc

  • Gość
# Styczeń 10, 2007, 01:52:52
Witam. Czytam wlasnie z zafascynowaniem te dyskusje na temat FPS QPC i innych GetTickow i w przyplywie natchnienia wrzucilem do swojego programiku taki kodzik

{
DWORD Timer = timeGetTime();
DWORD TickDiff;

/*TU RENDEROWANIE*/

TickDiff = timeGetTime() - Timer;

sprintf(napis, "%f", (1/(FLOAT)TickDiff *1000.0f));
SetWindowText(hWnd, napis);


}

W rezultacie dostaje kolosalne lioczby z przedzialu [500.0000, 1000.0000] nie mam pewnosci czy to jest moj FPS. Mozliwe ze tak jest bo w sumie duzo sie tutaj nie dzieje. Czy jest tutaj cos podejrzanego???

Offline Xion

  • Redaktor
    • xion.log

# Styczeń 10, 2007, 08:22:52
Jak najbardziej. To:

TickDiff = timeGetTime() - Timer;
Ta różnica nie mierzy czasu klatki, tylko długość poprzedniego wywołania timeGetTime().  Prawidłowo zmienna Timer powinna być inicjalizowana tylko raz:

DWORD Timer = GetTickCount(), NewTimer;

while (...)
{
     NewTimer = GetTickCount();
     TickDiff = Timer - NewTimer;
     Timer = NewTimer;
   
     /* reszta klatki */
}

Zapewne można to zrobić ładniej i bez dodatkowej zmiennej, ale tak z rana nie chce mi się myśleć ;)

st3tc

  • Gość
# Styczeń 10, 2007, 09:34:00
Nie używajcie timeGetTime, GetTickCount itp. One mają rozdzielczość 1 msec. Jedyną prawidłową na windzie jest QueryPerformanceCounter( na linie clock_gettime). Rozdzielczości bez problemu jest na poziomie dziesiątek (lub lepiej) ns. I tylko taki pomiar da prawidłowe wyniki. Przy większej ilości fps, counterki 1ms będą gigantycznie fałszować wyniki.

Offline Charibo

  • Redaktor

# Styczeń 10, 2007, 12:26:55
Ale QueryPerformanceCounter ma taki narzut, ze juz bedzie te kilka klatek mniej i cale profilowanie i mierzenie traci sens. afaik trzeba zrobic sobie wlasna klase do mierzenia czasu. W perelkach 2 bylo o tym

st3tc

  • Gość
# Styczeń 10, 2007, 12:36:15
Ale QueryPerformanceCounter ma taki narzut, ze juz bedzie te kilka klatek mniej i cale profilowanie i mierzenie traci sens. afaik trzeba zrobic sobie wlasna klase do mierzenia czasu. W perelkach 2 bylo o tym
... A świstak zawija czasoprzestrzeń ( (c)copycat ;) ) ...

Offline shyha

  • Użytkownik
    • Shyha@Flickr

# Styczeń 10, 2007, 13:09:10
Ale QueryPerformanceCounter ma taki narzut, ze juz bedzie te kilka klatek mniej i cale profilowanie i mierzenie traci sens. afaik trzeba zrobic sobie wlasna klase do mierzenia czasu. W perelkach 2 bylo o tym
No, a w klasie dajesz QPC :P
Co proponujesz w zamian? rdtsc?

st3tc

  • Gość
# Styczeń 10, 2007, 13:33:29
No, a w klasie dajesz QPC :P
Co proponujesz w zamian? rdtsc?

I tak użyje rdtsc :) Nie wierzę, żeby pisał na coś innego i niższego niż pentium 3/duron. Polecam do przeczytania:

http://209.85.129.104/search?q=cache:t3LQZsEHuBwJ:www.libsdl.org/pipermail/sdl/2004-August/063821.html+sdl+fixed+frame+rate+demo+pig&hl=pl&gl=pl&ct=clnk&cd=1&client=firefox-a

* Fixed logic frame rate with frameskipping and/or
  interpolation. (Game logic runs in the rendering thread,
  but is throttled so that it runs at the correct average
  frame rate.)
+ Fixed frame rate ==> simple and robust game logic.
+ Easy to design exact (repeatable) game logic.
+ No multithreading complexity
+ Interpolation is easy to implement, since there
  are no asyncronous buffering issues.
+ A very high logic frame rate (say 1 kHz) is an
  easy hack if you want to avoid interpolation.
- Needs interpolation or very high logic frame rates
  for smooth animation at all rendering frame rates.
« Ostatnia zmiana: Styczeń 10, 2007, 13:35:26 wysłana przez agent_J »

st3tc

  • Gość
# Styczeń 10, 2007, 13:39:51
A bylo juz tyle razy ze nie uzywa sie rdtsc ...

Offline Charibo

  • Redaktor

# Styczeń 10, 2007, 16:06:01
Shyha: tak mowilem o rdtsc :)
st3tc : dlaczego nie?
« Ostatnia zmiana: Styczeń 10, 2007, 19:08:55 wysłana przez Charibo »

Offline Steel_Eagle

  • Użytkownik

# Styczeń 10, 2007, 16:59:39
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/Game_Timing_and_Multicore_Processors.asp

Ja osobiscie nie chcialbym zeby moja gra nie chodzila na nowych wielordzeniowych procesorach  ;) + pare detali...

Pozatym czy Query jest az tak czasozerne? Watpie... I tutaj wychodzi znane: "Premature optimization is root of all evil", wiec zamiast optymalizowac na sile cos czego nie trzeba, lepiej zastanowic sie nad tym co faktycznie moze zjadac procesor ;)

st3tc

  • Gość
# Styczeń 10, 2007, 18:52:49
Caribo - zrobic dwa bledy w tak prostym nicku jak st3tc ? ;p

A dlatego nie - ze na prockach z kontrola taktowania (common w laptopach) rdtsc da pupy. Sam mialem niemila niespodzienke, kiedy moje demko zwariowało na laptopie ;). Dodajac do wypowiedzi Steel-Eagle-a - dokladnie. Profilowanie - narzedziami do tego przeznaczonymi - i bedzie "siara ... i wszystko jasne" :D