#1 Members - Reputation: 179
Posted 31 October 2012 - 07:44 PM
I am getting some strange results from my framerate calculation. It seems to have a mind of its own. It wants to stay at about 60 fps even if I set it to 80fps. It does run though if I set it to 50fps.
I am getting smooth movement at 60fps but at 50fps the waiting part kicks in and starts to jitter the movement. I have given the entire while loop.
it works I've tested it but I dont know why it stays at 60 fps. Please help I'm at my wits end. Here is what I have done so far...
[source lang="cpp"] MSG msg; DWORD ticks = GetTickCount() / 1000; DWORD ticksMS = GetTickCount(); ticks = 0; int iFrame = 0; // the current frame int iFrameRate = 60; // limits the framerate g_uFrameRate = 0; // global framerate long iWaited = 0; // length of time waited int iNumSecs = 0; // number of seconds gone by in game loop char c[80]; // used as debug text string s; DWORD fDelta = 0.0f; FILE* pFile; char buffer[100]; int iFrameCycles = 0; fopen_s (&pFile, "myfile.txt" , "w"); if (pFile == NULL) perror ("Error opening file"); while (g_App.GetD3DStatus()) { while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } if (msg.message == WM_QUIT) break; if (KEY_DOWN(VK_ESCAPE)) PostMessage(hWnd, WM_DESTROY, 0, 0); if (KEY_DOWN(VK_MBUTTON)) PostMessage(hWnd, WM_DESTROY, 0, 0); // only run if more than 1 second has passed if (ticks < (GetTickCount() / 1000)) { // save the framerate to tell CApplication, sprites and meshes g_uFrameRate = iFrame; // values iWaited = 0; // reset the amount of time waited ticks = GetTickCount() / 1000; // rest ticks to the current time ticksMS = GetTickCount(); iFrame = 0; // reset the number of frames to zero iNumSecs += 1; // increment the number of secs gone by iFrameCycles = 0; // the number of revolutions per second } // pause if we have rendered more than the framerate in 1 sec if (iFrame >= iFrameRate) { // calc amount of ms left over fDelta = 1000 - (GetTickCount() - ticksMS); } else { // check for user input g_App.DetectInput(); // render g_App.Render(); //Sleep(20); // incrememnt the frame number iFrame++; } // endelse iFrameCycles++; } // end while (g_App.GetD3DStatus()) fclose (pFile);[/source]
also here is my Movement code:
[source lang="cpp"] void CShape::Orbit(float fX, float fY, float fZ) { // calc xyz velocity's cirular points m_fXV = (float)(sin(fX) * 12.0f) * 20.0f; m_fYV = 0; m_fZV = (float)(cos(fZ) * 25.0f) * 20.0f; // set the spacial coords equal to triad velocities // make sure that there is no divide by zero and // divide the velocity by the current framerate to give // the per second unit of movement. if (m_fXV != 0) m_fX = m_fXV * fT; if (m_fYV != 0) m_fY = m_fYV * fT; if (m_fZV != 0) m_fZ = m_fZV * fT; // apply this to a matrix D3DXMatrixTranslation(&m_matTranslate, m_fX, m_fY, m_fZ); }// Orbit[/source]
#2 Crossbones+ - Reputation: 3535
Posted 31 October 2012 - 09:41 PM
it works I've tested it but I dont know why it stays at 60 fps.
a few lines in the code...
int iFrameRate = 60; // limits the framerate
Jokes aside, I think the problem is that your Render() method calls the D3D Present() function, which pushes the current frame to the screen - this may be subject to its own framerate limitation, for instance vertical synchronization. Try taking that call out and see if the loop runs at the correct rate now, if not, try removing functions one by one until you locate the problem.
Also, GetTickCount() is not very accurate, so you might observe jitter beyond 40 fps or so, the "improved" counter is QueryPerformanceCounter/Frequency.
#3 Members - Reputation: 160
Posted 01 November 2012 - 11:43 AM
Because looking at your code the way you calculate frame rate seems to be all over the place.
Basically using a couple methods namely: QueryPerformanceFrequency(LARGE_INTEGER); and QueryPerformanceCounter(LARGE_INTEGER)
You can find both the DeltaTime and TotalTime of the application instance. Then using those values you can calculate FramePerSecond and everything else over the moon.
An example of this can be found here http://mengine.googl...c/GameTimer.cpp
written by Frank Luna writer of the "Introduction to 3D game programming using DirectX" series.
Look at it closely and see essentially what is being done in each function.
Then look at the following function that uses the GameTimer class:
void D3DApp::CalculateFrameStats()
{
// Code computes the average frames per second, and also the
// average time it takes to render one frame. These stats
// are appended to the window caption bar.
static int frameCnt = 0;
static float timeElapsed = 0.0f;
frameCnt++;
// Compute averages over one second period.
if( (mTimer.TotalTime() - timeElapsed) >= 1.0f )
{
float fps = (float)frameCnt; // fps = frameCnt / 1
float mspf = 1000.0f / fps;
std::wostringstream outs;
outs.precision(6);
outs << mMainWndCaption << L" "
<< L"FPS: " << fps << L" "
<< L"Frame Time: " << mspf << L" (ms)";
SetWindowText(mhMainWnd, outs.str().c_str());
// Reset for next average.
frameCnt = 0;
timeElapsed += 1.0f;
}
}
Again ALL CREDIT TO FRANK LUNA.
This function calculates the frames per second and displays it to the application window title bar.
Now limiting the frame rate to 60 shouldn't be hard once you have a nice object oriented way to calculate the frames per second of your application.
Edited by Debunez, 01 November 2012 - 11:46 AM.
#4 Members - Reputation: 1551
Posted 01 November 2012 - 01:08 PM
---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)
#5 Members - Reputation: 179
Posted 01 November 2012 - 06:19 PM
I dont know how to set the V-Sync, but my research took me to msdn.microsoft.com/en-us/library/windows/desktop/bb173393%28v=vs.85%29.aspx also click the link at the bottom which talks about 'D3DSWAPEFFECT enumeration'I'm sure it's a V-Sync issue. You're graphics setting is probably set to V-Sync enabled
Mine is D3DSWAPEFFECT_DISCARD.
I have included to files which are the output of the framerate calc. the first is windowed the second is fullscreen. Notice the windowed one keeps going back to 60fps.
WINDOWED:
second = 0 fps = 0 delta (ms) = 0 iFrameCycles = 0 second = 1 fps = 46 delta (ms) = 0 iFrameCycles = 46 second = 2 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 3 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 4 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 5 fps = 60 delta (ms) = 2 iFrameCycles = 3484 second = 6 fps = 60 delta (ms) = 18 iFrameCycles = 4340 second = 7 fps = 60 delta (ms) = 17 iFrameCycles = 1338 second = 8 fps = 60 delta (ms) = 17 iFrameCycles = 1548 second = 9 fps = 60 delta (ms) = 17 iFrameCycles = 2290 second = 10 fps = 60 delta (ms) = 17 iFrameCycles = 1982 second = 11 fps = 60 delta (ms) = 17 iFrameCycles = 3684 second = 12 fps = 60 delta (ms) = 17 iFrameCycles = 2891 second = 13 fps = 60 delta (ms) = 18 iFrameCycles = 4049 second = 14 fps = 60 delta (ms) = 17 iFrameCycles = 5430 second = 15 fps = 60 delta (ms) = 1 iFrameCycles = 16662 second = 16 fps = 60 delta (ms) = 17 iFrameCycles = 9202 second = 17 fps = 60 delta (ms) = 17 iFrameCycles = 5426 second = 18 fps = 60 delta (ms) = 17 iFrameCycles = 7609 second = 19 fps = 60 delta (ms) = 18 iFrameCycles = 5890 second = 20 fps = 60 delta (ms) = 17 iFrameCycles = 7377 second = 21 fps = 60 delta (ms) = 17 iFrameCycles = 6118 second = 22 fps = 60 delta (ms) = 17 iFrameCycles = 5243 second = 23 fps = 60 delta (ms) = 17 iFrameCycles = 6329 second = 24 fps = 60 delta (ms) = 18 iFrameCycles = 16050 second = 25 fps = 60 delta (ms) = 2 iFrameCycles = 16479 second = 26 fps = 60 delta (ms) = 17 iFrameCycles = 14001 second = 27 fps = 60 delta (ms) = 17 iFrameCycles = 12259 second = 28 fps = 60 delta (ms) = 17 iFrameCycles = 5991 second = 29 fps = 60 delta (ms) = 17 iFrameCycles = 11231 second = 30 fps = 60 delta (ms) = 18 iFrameCycles = 3907
FULLSCREEN:
second = 0 fps = 0 delta (ms) = 0 iFrameCycles = 0 second = 1 fps = 46 delta (ms) = 0 iFrameCycles = 46 second = 2 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 3 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 4 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 5 fps = 60 delta (ms) = 2 iFrameCycles = 3484 second = 6 fps = 60 delta (ms) = 18 iFrameCycles = 4340 second = 7 fps = 60 delta (ms) = 17 iFrameCycles = 1338 second = 8 fps = 60 delta (ms) = 17 iFrameCycles = 1548 second = 9 fps = 60 delta (ms) = 17 iFrameCycles = 2290 second = 10 fps = 60 delta (ms) = 17 iFrameCycles = 1982 second = 11 fps = 60 delta (ms) = 17 iFrameCycles = 3684 second = 12 fps = 60 delta (ms) = 17 iFrameCycles = 2891 second = 13 fps = 60 delta (ms) = 18 iFrameCycles = 4049 second = 14 fps = 60 delta (ms) = 17 iFrameCycles = 5430 second = 15 fps = 60 delta (ms) = 1 iFrameCycles = 16662 second = 16 fps = 60 delta (ms) = 17 iFrameCycles = 9202 second = 17 fps = 60 delta (ms) = 17 iFrameCycles = 5426 second = 18 fps = 60 delta (ms) = 17 iFrameCycles = 7609 second = 19 fps = 60 delta (ms) = 18 iFrameCycles = 5890 second = 20 fps = 60 delta (ms) = 17 iFrameCycles = 7377 second = 21 fps = 60 delta (ms) = 17 iFrameCycles = 6118 second = 22 fps = 60 delta (ms) = 17 iFrameCycles = 5243 second = 23 fps = 60 delta (ms) = 17 iFrameCycles = 6329 second = 24 fps = 60 delta (ms) = 18 iFrameCycles = 16050 second = 25 fps = 60 delta (ms) = 2 iFrameCycles = 16479 second = 26 fps = 60 delta (ms) = 17 iFrameCycles = 14001 second = 27 fps = 60 delta (ms) = 17 iFrameCycles = 12259 second = 28 fps = 60 delta (ms) = 17 iFrameCycles = 5991 second = 29 fps = 60 delta (ms) = 17 iFrameCycles = 11231 second = 30 fps = 60 delta (ms) = 18 iFrameCycles = 3907
FULSCREEN @80fps (aimed at but it doesnt increase):
second = 0 fps = 0 delta (ms) = 0 iFrameCycles = 0 second = 1 fps = 1 delta (ms) = 0 iFrameCycles = 1 second = 2 fps = 62 delta (ms) = 0 iFrameCycles = 62 second = 3 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 4 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 5 fps = 61 delta (ms) = 0 iFrameCycles = 61 second = 6 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 7 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 8 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 9 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 10 fps = 61 delta (ms) = 0 iFrameCycles = 61 second = 11 fps = 61 delta (ms) = 0 iFrameCycles = 61 second = 12 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 13 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 14 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 15 fps = 61 delta (ms) = 0 iFrameCycles = 61 second = 16 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 17 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 18 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 19 fps = 61 delta (ms) = 0 iFrameCycles = 61 second = 20 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 21 fps = 61 delta (ms) = 0 iFrameCycles = 61 second = 22 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 23 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 24 fps = 61 delta (ms) = 0 iFrameCycles = 61 second = 25 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 26 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 27 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 28 fps = 60 delta (ms) = 0 iFrameCycles = 60 second = 29 fps = 61 delta (ms) = 0 iFrameCycles = 61 second = 30 fps = 60 delta (ms) = 0 iFrameCycles = 60
@Debunez: Thanks I'm ordering the book. I am looking through the timer code and trying to understand it.An example of this can be found here http://mengine.googl...c/GameTimer.cpp
written by Frank Luna writer of the "Introduction to 3D game programming using DirectX" series
@BeerNutts: Ahh so looking at the third output above I am trying to call the render loop and something there is prohibiting me from continuing to call it more than 60/61fps.so you won't update your screen faster than your monitor's V-Sync (which is typically 60 HZ)
Dont I want to keep V-Sync on though? Can anyone have a look at the movement code because I want to make sure that an object moves the same amount on a 100hz computer just as a 60hz one. Maybe I can just rely on this (seems like) 'automatic' feature...!
#6 Crossbones+ - Reputation: 3535
Posted 01 November 2012 - 06:23 PM
Vertical synchronization is meaningful only in fullscreen mode. This is your problem.I have included to files which are the output of the framerate calc. the first is windowed the second is fullscreen. Notice the windowed one keeps going back to 60fps.
Nuh-uh. VSync can be overriden through the graphic driver's control panel, so you cannot rely on it being active even if you explicitly ask for it. And as you can see, it cannot be used in windowed mode. If you want to ensure the game runs at the same perceived speed regardless of framerate you need to use other methods, usually taking into account the elapsed time between two frames (there was this article that might come in handy though it's more about physics).Dont I want to keep V-Sync on though? Can anyone have a look at the movement code because I want to make sure that an object moves the same amount on a 100hz computer just as a 60hz one. Maybe I can just rely on this (seems like) 'automatic' feature...!
Edited by Bacterius, 01 November 2012 - 06:23 PM.
#7 Members - Reputation: 179
Posted 01 November 2012 - 06:23 PM
FULLSCREEN 80fps (m_pD3DDevice->Present(NULL, NULL, NULL, NULL); COMMENTED OUT):
second = 0 fps = 0 delta (ms) = 0 iFrameCycles = 0 second = 1 fps = 80 delta (ms) = 126 iFrameCycles = 186147 second = 2 fps = 80 delta (ms) = 2 iFrameCycles = 239753 second = 3 fps = 80 delta (ms) = 18 iFrameCycles = 237041 second = 4 fps = 80 delta (ms) = 17 iFrameCycles = 236471 second = 5 fps = 80 delta (ms) = 17 iFrameCycles = 240157 second = 6 fps = 80 delta (ms) = 17 iFrameCycles = 237241 second = 7 fps = 80 delta (ms) = 17 iFrameCycles = 235768 second = 8 fps = 80 delta (ms) = 18 iFrameCycles = 234334 second = 9 fps = 80 delta (ms) = 17 iFrameCycles = 237221 second = 10 fps = 80 delta (ms) = 17 iFrameCycles = 237300
so my code does really work but with present commented out. So how do I find out which V-Sync/s I need???






