[ sucur @ 21.08.2005. 15:28 ] @
E ovako narode, radim sa openGL (C++) i pravim neku igru, kod mene sve je uredu, al' kada sam odnjeo kod druga, brzina igre je abnormalna (prebrza). E naravno prvo sto mi je palo na pamet je razlika u brzini procesora, moj je 1.7, a njegov 3 GHz, dok nam je RAM obojici 512MB.
Tako da je 99% u tome problem, da kod njega brze "vrti" kod i samim tim brzina igre je mnogo veca.
E sada meni terba rjesenje ovog problema, tj. kako da mi igra radi istim tempom na svim racunarima?
Jer ipak ovo je veoma gadan problem, i na ostalim racunarima igra je beskorisna.
[ yooyo @ 21.08.2005. 15:39 ] @
U glavnoj petlji programa racunaj vreme od starta igre i delta vreme izmedju 2 uzastopna frejma. Koristeci jednu od ove vrednosti, sinhronizuj animaciju svih objekata u igrici.

yooyo
[ NastyBoy @ 21.08.2005. 15:50 ] @
Nije problem u tome shto je njegom CPU brzhi, odnosno to nikad ne sme da bude problem vec prednost.

Pogledaj tutorijale na temu "game loop"-a (imash ih podosta na netu), i pojam "frame time"-a.
Odnosno, treba ti neshto neshto slichno ovome :
Code:

void MyGame::Update()
{
  // u tajmeru mozhesh izmeriti vreme koje je proshli frejm zauzeo
  // ili jednostavno "zakljuchati" frejm-rejt an neku vrednost (recimo 30fps)
  // tj. na FrameTime = 0.03;
  float FrameTime = MyTimer.GetFrameDuration();
  
  // ovde apdejtujesh elemente igre sa datim delta vremenom
  GameWorld.Update(FrameTime);
}


Recimo da imash kretanje nekog objekta chija da je brzina v, i trenutna pozicija pos. U sledecem apdejtu ce polozhaj tog objekta biti pos = pos + v*FrameTime. Dakle, apsolutna brzina je ista, i za npr. 5 sekundi ce taj objekat preci istu putanju na obe mashine, ali ce sa vecim frejm-rejtom taj pomeraj izgedati postepen i gladak, dok cesh na sporijoj mashini imati manje osvezhavanja pozicije u tih pet sekundi pa ce i kretanje "seckati" (shto mozhesh da vidish u svakoj igri kada frejm rejt opadne ispod recimo 30 frejmova)
[ sucur @ 21.08.2005. 18:17 ] @
Pa da pretpostavio sam da mi terba neki timer koji ce to sve vremenski odradjivati, jer trenutno kod mene se sve odradjuje preko framesa, tako koliko framesa u sekundi koji racunar moze postici tolika je brzina, dok vrijeme je svima isto.

Pa ako neko zna neku stranicu gdje bih mogao pronaci nesto o ovome bilo je dobro.

@NastyBoy: Ma znam da je to prednost, sto je brzi, ali u ovom slucaju je "problem", zbog velikog frameratea.
[ NastyBoy @ 21.08.2005. 18:36 ] @
Za diskusiju o implementaciji tajmera, pogledaj ovaj thread na GameDev-u :
http://www.gamedev.net/community/forums/topic.asp?topic_id=316498
[ sucur @ 21.08.2005. 23:23 ] @
ok, hvala svima!
[ mloh2 @ 22.08.2005. 09:10 ] @
Evo ovaj tajmer smo koristili za ball7.

ovo ti je zaglavlje....

/**********************************/
#ifndef _CTIMER_H_
#define _CTIMER_H_

#include <windows.h>
#include <winbase.h>
#include <math.h>




class cTimer
{
public:
cTimer(void);
void Reset(void);
float Update(void);
private:
LARGE_INTEGER clock_frequency;
LARGE_INTEGER num_clocks;
double fTime;
double fOld_Time;
double fStart_Time;
};


#endif

/**********************************/


ovo ti je implementacija....

#include "cTimer.h"


/*
// Konstruktor klase. Cita frekvenciju CPU kloka.( mada to kad se pretvori u double nije pravi klok )
*/
cTimer::cTimer(void)
{
QueryPerformanceFrequency(&clock_frequency);
}

/*
// Metoda Reset(), resetuje tajmer
*/
void cTimer::Reset(void)
{
fTime=0;
fOld_Time=0;
QueryPerformanceCounter(&num_clocks);
fStart_Time=(double)num_clocks.QuadPart/(double)clock_frequency.QuadPart;
}

/*
// Metoda Update(), vraca proteklo vreme od poslednjeg poziva ove funkcije ili
// funkcije Reset().
*/
float cTimer::Update(void)
{
fOld_Time=fTime;
QueryPerformanceCounter(&num_clocks);
fTime=(double)num_clocks.QuadPart/(double)clock_frequency.QuadPart-fStart_Time;
return (float)(fTime-fOld_Time);
}



znaci napravis ovako nesto

///// resetujes vreme i tajmer
cTimer delta_timer;
float fTime;

fTime=0.0f;
delta_timer.Reset();
///




posle negde to updejtujes
///////////

float dt;

fTime+=dt=delta_timer.Update();

i dt ti je proteklo vreme od prethodong frejma....

fTime ti je ukupno vreme...

pozdrav
mloh


[Ovu poruku je menjao mloh2 dana 22.08.2005. u 10:11 GMT+1]
[ tosa @ 22.08.2005. 10:27 ] @
Nece boleti da dodas i pauzu u taj kod, korisnici ce zeleti da pauziraju igru..
[ netoff @ 22.08.2005. 10:36 ] @
Mislim da je ovo gore loš primer za clock. Nisam se udubljivao ali vidim da se koristi QueryPerformanceFrequency i QueryPerformanceCounter. Na nekim prenosnim računarima takt procesora nije konstantan već varira tokom vremena, tako da nisam siguran da je ovo baš pouzdana metoda za merenje vremena.
[ mloh2 @ 22.08.2005. 10:58 ] @
@netoff -> Ne radi ni na mikrotalasnim rernama ;)

Salim se, ali mislim da je coveku koji ocigledno na pocetku to odlican tajmer sa kojim moze da napravi igru. Verujem da je i opaska na mestu, stoga predlazem da izlozis resenje, i meni bi pomoglo.


Sto se pauze tice, veoma je jednostavno... Kad izadjes iz pauze, samo resetujes sve tajmere, igra ce da se odmrzne i krene dalje, posto ce ti delta tajm pri sledecem pozivanju update biti veoma mali. Svim klasama koje sadrze timer napises metodu npr:

void klasa::UnFreeze(void)
{
timer.Reset();
}

i prozoves metodu kad izlazis iz stanja pauze...




[Ovu poruku je menjao mloh2 dana 22.08.2005. u 12:08 GMT+1]
[ YanObu @ 22.08.2005. 12:11 ] @
@netoff:
Citat:
netoff: Mislim da je ovo gore loš primer za clock. Nisam se udubljivao ali vidim da se koristi QueryPerformanceFrequency i QueryPerformanceCounter. Na nekim prenosnim računarima takt procesora nije konstantan već varira tokom vremena, tako da nisam siguran da je ovo baš pouzdana metoda za merenje vremena.


nisi se udubljivao ali si rekao da je shit u sushtini...Bash si neki fin decak.
Radish za NASU? nece da radi kod na SUN SPARCK-u? heheheh, veselo nema sta
Cim neko da nekome neshto da pomogne , odmah ga ljudi pljuju...

Ajde daj ti tvoj kod za tajmer!
[ tosa @ 23.08.2005. 09:58 ] @
Ajmo bez flejmova! Niko nikoga nije pljuvao ovde, covek je rekao stvar
koja je savrseno tacna. Ako smatras da ti to nije bitno, ti ignorisi...
[ mloh2 @ 24.08.2005. 09:38 ] @
Da stvarno neprijatno...
[ netoff @ 26.08.2005. 01:25 ] @
Da ne bude da lažem evo šta piše na jednom od onih slajdova sa Meltdown 2005
Citat:

Use QueryPerformanceFrequency every few frames to handle power management clock rate changes

Možda iz Microsofta lažu:)

To u stvari može da znači da je stvar još gora, ne samo da igra možda neće da radi na nekom notebook računaru nego je moguće da ovo ne funkcioniše ni na stonim mašinama, niti postoji garancija da će na budućim procesorima da radi.

Između ostalog u dokumentaciji piše:
Citat:

The QueryPerformanceFrequency function retrieves the frequency of the high-resolution performance counter, if one exists.

Ako postoji, što verovatno znači da postoji mogućnost da uopšte ne postoji.

U dokumentacji još i piše
Citat:

timeGetTime
The timeGetTime function retrieves the system time, in milliseconds. The system time is the time elapsed since Windows was started.

DWORD timeGetTime(VOID);

......
Return Values
Returns the system time, in milliseconds.
......
Windows NT/2000: The default precision of the timeGetTime function can be five milliseconds or more, depending on the machine.
Windows 95: The default precision of the timeGetTime function is 1 millisecond.

Pošto pretportavljam da nikome ne treba 1000 frejmova u s. logično je da nije preporučljivo da se koriste nesigurna rešenja kao gore navedeno.
[ bkaradzic @ 26.08.2005. 01:46 ] @
Evo par interesantnih linkova:

Performance counter value may unexpectedly leap forward
http://support.microsoft.com/default.aspx?scid=kb;en-us;Q274323

Implementing a Better Timer
http://www.rpi.edu/~pudeyo/articles/better_timer.html

Timing in Win32
http://www.geisswerks.com/ryan/FAQS/timing.html

Inače komercijalne igre koriste i QueryPerformanceCounter (npr. PC i Xbox verzija FSW1 i FSW2) i timeGetTime (npr. Quake 3) podjednako.
[ yooyo @ 26.08.2005. 08:11 ] @
Koristite QueryPerformanceCounter za benchmark nekog dela programa, (upload textura ili brzina nekog algoritma), a timeGetTime kao timer koji kontrolise brzinu animacije objekata.

yooyo
[ mloh2 @ 26.08.2005. 09:19 ] @
Cenim da rasprava postaje konstruktivna.
[ sucur @ 26.08.2005. 14:15 ] @
Ma zavrsio sam to preko timeGetTime() funkcije.
Pozdrav !