static LARGE_INTEGER frequency, time1, time2;
static double accumulator = 0.f;
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&time1);
while (message.message != WM_QUIT)
{
if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
QueryPerformanceCounter(&time2);
accumulator += ( (time2.QuadPart - time1.QuadPart)/frequency.QuadPart );
time1.QuadPart = time2.QuadPart;
while (accumulator >= 16)
{
UpdateDXGame();
accumulator -= 16;
}
RenderDXGame();
}
sprite render is very slow
Thats because your time calculation is wrong. You do an integer division, then save the result in a double.
The easy fix is to cast frequency.QuadPart to double to get a floating point division.
The better fix would be to accumulate the integer ticks, then change the comparison such that it compares with frequency.QuadPart/60.
FrameTimer timer;
const float delta = 1.0f / 60.0f;
float accumulator = delta;
while(msg.message != WM_QUIT)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
float t = timer.elapsed();
accumulator += t;
while(accumulator >= delta)
{
app.update(delta); // delta used to update physics etc
accumulator -= delta;
}
app.render(accumulator / delta); // blend parameter used to interpolate between previous and current positions for render
}
And here is implementation of FrameTimer (accuracy is fine for me using float here):class FrameTimer
{
public:
FrameTimer();
float elapsed();
private:
LARGE_INTEGER frequency;
LARGE_INTEGER lastCount;
};
FrameTimer::FrameTimer()
{
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&lastCount);
}
float FrameTimer::elapsed()
{
LARGE_INTEGER count;
QueryPerformanceCounter(&count);
float time = static_cast<float>(count.QuadPart - lastCount.QuadPart)/static_cast<float>(frequency.QuadPart);
lastCount = count;
return time > 0.25f ? 0.25f : time;
}
I've used this approach in a whole bunch of games now, but if there is something amiss with my implementation of FYT, I'd be happy to hear about it.
static LARGE_INTEGER frequency, time1, time2;
static double accumulator = 0.002;//why?
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&time1);
while (message.message != WM_QUIT)
{
if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
QueryPerformanceCounter(&time2);
frametime = (((double)time2.QuadPart - (double)time1.QuadPart)
/ (double)frequency.QuadPart);
accumulator += frametime;
time1.QuadPart = time2.QuadPart;
while (accumulator >= 0.002)
{
UpdateDXGame();
accumulator -= 0.002;
getfps();
}
RenderDXGame();
}
and I remembered converting longlong to double
@Aardvajk I use almost the same code with yours and it can only move very slowly at 60fps. I have to raise fps to 500 to speed it up. for example, the velocity is 0.75f per second at 500fps, and it perform good. But when at 60fps, I have to increase the speed to 8.f or even more, which produce a very unsmooth movement(the object seems to be jumping on the screen).
Setting aside that your code is not very much like Aardvajk's in important details (for example you process only a single message per frame, quite unlike the original), I strongly suspect your speeds are not 'per second' as you think but 'per frame'. It's rather telling you decrease your target frame rate by a factor of approximately 8 and then have to increase your speed by a factor of approximately 8 to get similar results.
Edit: some pseudo code:
int updatesPerSecond = 60;
float secondsPerUpdateStep = 1.0f / static_cast<float>(updatesPerSecond);
float mySpeedPerSecond = 10.0f;
// you appear to be doing this every update:
myPosition = myPosition + mySpeedPerSecond;
// you should be doing this:
myPosition = myPosition + secondsPerUpdateStep * mySpeedPerSecond;
0.002 is a strange delta. That is 1 / 500, which is a tiny amount. My delta is 1 60th of a second, i.e. my physics is running at 60 fps. Your is saying you want to simulate at 500 frames per second, which would make your update absolutely tiny.
But its hard to follow exactly. BitMaster seems to have done a better job than me of understanding your code.
A speed has (for example) the unit pixel/second. A position has the unit pixel. The assignment
myPosition = myPosition + mySpeedPerSecond;
then should immediately give you pause because you try to add something with the unit pixel and pixel/second together. You cannot do that.Let's check do a unit check for
myPosition = myPosition + secondsPerUpdateStep * mySpeedPerSecond;
though:[pixel] = [pixel] + [seconds] * [pixel/seconds] = [pixel] + [seconds * pixel / seconds] = [pixel] + [pixel]
That checks out.
As BitMaster said, make the PeekMessage check a while. Process all messages from a queue or you have extremely delayed window behaviour (dragging your window should lag like hell). It's not solving the main problem, but could be the cause of a few others.
while ( PeekMessage( &message, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &message );
DispatchMessage( &message );
}
why can't I mark this topic as solved?...
We don't mark topics as solved on this forum, as although it may have solved the problem for you, it might not be the solution for someone else :) besides this isn't stack exchange :)