[OpenGL] tijdsindicaties/framerate

Pagina: 1
Acties:
  • 102 views sinds 30-01-2008
  • Reageer

  • Error323
  • Registratie: December 2001
  • Laatst online: 03-02 08:58
Beste Tweakers,

Sinds een paar dagen ben ik me aan het verdiepen in opengl (linux|c|c++). Gaat opzich heel voorspoedig, ik heb alleen een probleem met het behouden van een stabiele framerate in heel simpele scenes. Ik snap de theorie, weet hoe het moet worden gerealiseerd maar....
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void display( void ) {
  begin = clock();
  glClear( GL_COLOR_BUFFER_BIT );
  glColor3f( 1.0, 1.0, 1.0 );
  glPushMatrix();
  glRotatef( sun, 0.0, 1.0, 0.0 );
  glutWireSphere( 1.0, 20, 16 );
  glRotatef( year, 0.0, 1.0, 0.0 );
  glTranslatef( 2.0, 0.0, 0.0 );
  glRotatef( day, 0.0, 1.0, 0.0 );
  glutWireSphere( 0.2, 10, 8 );
  glPopMatrix();
  glutSwapBuffers();
  printf("framerendertime: %ld\n", clock() - begin );
}


Het probleem is in deze dat clock() niet precies genoeg is. Nu heb ik wat tweaker posts afgestruind, maar die hebben het allemaal over timeInMillis() operaties, wat voor het controleren van de framerate te onnauwkeurig is omdat dit micro- of nanoseconde precisie vereist. Dus mijn vraag: "Weet iemand hoe men een heel nauwkeurige tijdsindicatie verkrijgt in C/C++? Of technieken om 1-frame-render tijden te berekenen in OpenGL apps"

offtopic:
Waarom staat de CLOCKS_PER_SEC constante in linux op een miljoen bij een 3 gigahertz processor?

github.com/Error323


  • Daspeed
  • Registratie: Maart 2001
  • Laatst online: 09:49
Ik geloof dat ik ooit onder Windows/DirectX QueryPerformanceCounter gebruikte. Dat is denk ik windows only maar er is vast wel een alternatief. Heb je iig iets waar je op kan zoeken:
http://www.linuxtoday.com/developer/2001050201820PSMS

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 09:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

[google=high resolution timer linux] geeft bij mij toch aardig wat hits hoor :)

Let er touwens op dat frametimes berekenen achteraf-werk is. Stel je beweegt een object met 10 units per seconde naar rechts. Je vermengvuldigt die 10 dan met de frametime. Wat de frametime echter aangeeft is hoe lang de vorige frame geduurt heeft, niet hoe lang de huidige gaat duren, en dat is in principe wat je wilt weten. Als de vorige frame dus in een honderdste van een seconde klaar was, maar de huidige doet er een hele seconde over omdat er plots heel veel gerenderd moet worden, dan lijkt het dus alsof je object die frame een stuk langzamer beweegt (hij gaat namelijk 10 * 0.01 = 0.1 units naar rechts, terwijl hij eigenlijk 10 * 1 = 10 units naar rechts had moeten gaan). Als de frame daarna vervolgens weer een honderdste van een seconde duurt, zul je in die frame met een frametime van een seconde werken ipv 0.01, en dus beweeg je je object op dat moment 10 units terwijl hij er eigenlijk 0.1 had moeten bewegen.

Variabele framerates zijn op die manier heel erg opvallend, en helaas is er niet echt veel aan te doen zonder een ingewikkeld heuristisch algoritme op los te laten wat van tevoren kan bepalen hoe lang een frame ongeveer gaat duren, en dat is vrijwel niet te doen (ik heb iig nog nooit gehoord van een game die zoiets doet).

Framerate limiters helpen hier op zich wel, als je sporadische dalen hebt van 30 fps is het niet handig om de rest op 200 fps te laten lopen - als je het limit op 60 fps max, dan valt zo'n dal van 30 fps ineens een stuk minder op.

[ Voor 91% gewijzigd door .oisyn op 16-10-2006 13:16 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 13:10

Creepy

Tactical Espionage Splatterer

gettimeofday() heeft waarschijnlijk de resolutie die je wilt.

Overigens levert de manpage van clock() op een linux machine het volgende op
CONFORMING TO
ANSI C. POSIX requires that CLOCKS_PER_SEC equals 1000000 independent of the actual resolution.

[ Voor 4% gewijzigd door Creepy op 16-10-2006 13:56 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 09:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

De gereturnde units zeggen niets over de resolutie. Je kan een getTimeInMillis() ook wel converteren naar een getTimeInNanos() door het resultaat van die eerste functie met 1.000.000 te vermenigvuldigen. Daardoor is het niet ineens een nano-seconde resolutie functie :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Error323
  • Registratie: December 2001
  • Laatst online: 03-02 08:58
Dat is wel bizar, waarom moet CLOCKS_PER_SEC precies op 1 miljoen is dan de vraag. gettimeofday() gaat het probleem zo goed mogelijk benaderen dan maar :) Thnx voor jullie reply's.

github.com/Error323


  • Error323
  • Registratie: December 2001
  • Laatst online: 03-02 08:58
Nu heb ik dus code wat volgens mij moet werken, maar hangt in een paar seconden. Heeft iemand een idee waarom?
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void display( void ) {
  gettimeofday( &t1, 0 );
  glClear( GL_COLOR_BUFFER_BIT );
  glColor3f( 1.0, 1.0, 1.0 );
  glPushMatrix();
  glRotatef( sun, 0.0, 1.0, 0.0 );
  glutWireSphere( 1.0, 20, 16 );
  glRotatef( year, 0.0, 1.0, 0.0 );
  glTranslatef( 2.0, 0.0, 0.0 );
  glRotatef( day, 0.0, 1.0, 0.0 );
  glutWireSphere( 0.2, 10, 8 );
  glPopMatrix();
  glutSwapBuffers();
  gettimeofday( &t2, 0 );
  frameRenderTime = ( ( t2.tv_usec - t1.tv_usec ) * FPS_LIMIT );
  gettimeofday( &t1, 0 );
  t2.tv_usec = t1.tv_usec;
  while( ( t2.tv_usec - t1.tv_usec ) < frameRenderTime )
    gettimeofday( &t2, 0 );
}


Even niet lettend op de while... ik moet nog ff uitzoeken hoe je een nette wait uitvoert in microseconden.

[ Voor 6% gewijzigd door Error323 op 16-10-2006 15:30 ]

github.com/Error323


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 09:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

Omdat je alleen naar het microseconde-veld kijkt? Met een beetje debugger had je dat zelf trouwens ook wel kunnen achterhalen.

[ Voor 44% gewijzigd door .oisyn op 16-10-2006 17:36 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1