Archived

This topic is now archived and is closed to further replies.

Xiachunyi

Keeping the frame rate same on different computers

Recommended Posts

Hello again, I was wondering how do you keep the frame rate of your OpenGL program the same on different computers. I''ve been doing the image translations via each call of "DrawGLScene()" under the "WinAPI WinMain(...)" function, but since not all computers are like mine... some cycle through faster or slower than mine. I was thinking of asking the user for a delay count and inserting the given number into the "Sleep()" function, but that does not seem like a very good idea. Should I take the refresh speed of the graphics card or something like that? Thankyou in advance. My code for cycling is like this:
  
//UNDER WINAPI WINMAIN

...
	while(!done)							
	{
		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))	
		{
			if (msg.message==WM_QUIT)			
			{
				done=TRUE;						
			}
			else								
			{
				TranslateMessage(&msg);			
				DispatchMessage(&msg);			
			}
		}
		else										// If There Are No Messages

		{
			// Draw The Scene.  Watch For ESC Key And Quit Messages From DrawGLScene()

			if ((active && !DrawGLScene()) || keys[VK_ESCAPE])	// Active?  Was There A Quit Received?

			{
				done=TRUE;				
			}
			else									
			{
				SwapBuffers(hDC);
				if(pic == 1 || pic == 2 || pic == 3 || pic == 4 || pic == 5 || pic == 6 || pic == 7 || pic == 8 || pic == 9)
				{
				   pic_press=1;
				}
                if(screen != 0) //Start counting so we can "try" to position the cube correctly...

                {
                   if(switch_side_c == 0)
                   {					
				      move_side_c++;
                   }
				   if(adjust_near == 1)
				   {
                      move_near_c++;
                   }			
                }
                DrawGLScene();                                                                                                   
			}
...
  
The object reacts to the cycling like this:
  
//Ignore  the "GLCandace(...)" function

  if(screen == 2)
  { 	 
	//First Row

    GLCandace(1,0,-3.5,3.1f,-12.0,0.00,0.0,0.0,0); 	
	//The second cube is generated later to mask all other cubes

    GLCandace(1,2,3.5,3.1f,-12.0,0.0,0.0,0.0,0);
    //Second Row

    GLCandace(2,3,-3.5,-0.1f,-12.0,0.0,0.0,0.0,0);
    GLCandace(2,4,0.0,-0.1f,-12.0,0.0,0.0,0.0,0);
    GLCandace(2,5,3.5,-0.1f,-12.0,0.0,0.0,0.0,0);
    //Third Row

    GLCandace(3,6,-3.5,-3.1f,-12.0,0.0,0.0,0.0,0);
    GLCandace(3,7,0.0,-3.1f,-12.0,0.0,0.0,0.0,0);
    GLCandace(3,8,3.5,-3.1f,-12.0,0.0,0.0,0.0,0);
    //The second cube being generated

    if(move_side_c < 45)
    {
      GLCandace(1,1,0.0,3.1f,-12.0,0.0,-0.03,0.0,1);
    }           
    if(move_side_c > 45 && move_near_c !=30)
    {
       switch_side_c=1;
       adjust_near=1;
       GLCandace(1,1,finx,finy,finz,0.0,0.0,0.0,0);       
    }
    if(move_near_c > 45 && move_near_c < 130)
    {
       movx=0;
       movy=0; 
       GLCandace(1,1,finx,finy,finz,0.0,0.0,0.05,1);            
    }
    if(move_near_c > 130)
    {
       glDisable(GL_BLEND); 
       GLCandace(0,1,0.0,0.0,8.3,0.0,0.0,0.0,0);
  
I''m sorry if this has already been delt with, I looked through the tutorials, but I have not found an answer.

Share this post


Link to post
Share on other sites
Look into tutorial 21, I know you said you went through it but it involves the Performance timer and you should base your animation, movement whatever on the millseconds you get from the performance timer not on the frames... Hope that helps...

Share this post


Link to post
Share on other sites
I just had/fixed the same problem.

I used QueryPerformaceFrequecy and QueryPerformanceCounter. This the high-res timer you need. Basically you calculate the time difference between each frame and use this to calculate fps. Once you have that, you can delay until your fps syncs with a ''desired'' fps (i.e. 60 fps).

If you have the book featured on this site "OpenGL Game Programming", open the chapter 21 source file and check out HiResTimer.h. There are 4 memeber functions in there that show you obtain timing info. While testing the code out I did notice one error in the code:


  
float LockFPS(unsigned char targetFPS)
{
if (targetFPS == 0)
targetFPS = 1;

static LARGE_INTEGER s_lastTime = m_startTime;
LARGE_INTEGER currentTime;
float fps;

// delay to maintain a constant frame rate

do {
QueryPerformanceCounter(¤tTime);
fps = (float)m_ticksPerSecond.QuadPart/((float)(currentTime.QuadPart - s_lastTime.QuadPart));
} while (fps > (float)targetFPS);

// reset the timer

s_lastTime = m_startTime; // <- this needs to be s_lastTime = currentTime;


return fps;
} // end LockFPS()



Hope that helps.

-Q

Share this post


Link to post
Share on other sites