Sign in to follow this  
schupf

Is this render loop ok?

Recommended Posts

schupf    221
Hello!

I have just implemented my render loop for my simple game:

[code]
void Root::startApplicationLoop() {

mUpdateInterval = 1000.0f / mUpdatesPerSecond; // time in ms between two updates/logic ticks

const int maxUpdatesPerSecond = 10; // maximum number of updates per second();

float nextUpdateTime = time();
mIsAppRunning = true;
int numUpdatesThisFrame;

while(mIsAppRunning) {
numUpdatesThisFrame = 0;

while(time() > nextUpdateTime) {

WindowUtilities::messagePump();
update();
nextUpdateTime += mUpdateInterval;

numUpdatesThisFrame++;


if(numUpdatesThisFrame >= maxUpdatesPerSecond) {
nextUpdateTime = time();

break;


}

}

renderOneFrame();

}

}
void WindowUtilities::messagePump() {
MSG msg;
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}

}






[/code]

In words: Per variable mUpdatesPerSecond I define how often update() is called per second (for example 100 times). update() is called mUpdatesPerSecond times per second and renderOneFrame() is called as often as possible. I want the logic steps be constant and rendering as often as possible. WindowUtilities::messagePump() just calls PeekMeesage in a while loop.

Do you think this render loop is ok? Or does it have serious drawbacks/flaws/errors?

Share this post


Link to post
Share on other sites
Texus    248
[color="#000000"]I don't see anything wrong with the code. The only difference between your loop and the loop I am using for my projects is that you don't call Update() and Render() after each other like I do.
Below you can see the loop I am using. You don't have to use it, as far as I can see your loop is just as good as mine.

If your mUpdatesPerSecond is 100 is your code then it only passes once trough "while(time() > nextUpdateTime)" and then you would also update and render directly after each other.

[code]
float TimeSinceLastRefresh = 0;
int MaxFPS = 100;

while (AppRunning)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

Timer->Update();
TimeSinceLastRefresh += Timer->GetElapsedTime();

if (TimeSinceLastRefresh >= 1.0f/MaxFPS)
{
Update();
Render();

TimeSinceLastRefresh -= (1.0f/MaxFPS);
}
}
[/code]
[/color]

Share this post


Link to post
Share on other sites
schupf    221
Our loops are slightly different. You call both update() and render() at most MaxFPS times per second.

I only limit update() (with mUpdatesPerSecond), but render() may be called as often as possible.

The main reason why I ask is I am not sure if the position of my messagePump() function is a good idea.
My code flow basically says: If its time to update, process all window messages and then call update(). Not sure if this is a good idea though;/

Share this post


Link to post
Share on other sites
Texus    248
You should ask the following thing: "Is it possible that the window is destroyed and you are still trying to render on it?"
Suppose the window is destroyed, but it isn't time to update, so you just call render.

I don't know if it is possible (probably not), but I would feel safer when calling messagePump right before rendering, because then I would be SURE that it is not possible.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this