Jump to content
  • Advertisement
Sign in to follow this  
ScyllaBus

C++ Can my game loop be optimized?

Recommended Posts

Using my loop based on this: https://gafferongames.com/post/fix_your_timestep/

Trying to get my game to run at fixed 60FPS (both update and render) for all machines. Studied the link above and have been stuck on this game loop for weeks trying to get it to work smoothly to glide this image across the screen. I had dealt constantly with jittering and possible tearing. I can't recall what I did to fix it exactly, but I believe it may have something to do with not rounding a variable properly (such as delta).

 

So yeah, currently the loop works but I'm afraid as I develop the game more and have to render more, eventually something I'm doing in my loop could cause slowdowns or larger CPU usage. Does the structure of the game loop below seem okay or is there something I can do to optimize it?

The 2D game is a generic sidescroller. Not too heavy on physics, mainly just simple platformer physics. I feel as though I'm using way too much CPU.

 

void Game::mainLoop() {
    double fps = 60.0f;

    int frameSkip = 5;
    int deltaSkip = frameSkip;

    double miliPerFrame = 1000.0 / fps;

    double xx = 0.0f;

    double playSpeed = 5;

    Uint64 previous = SDL_GetPerformanceCounter();

    double accumulator = 0.0f;

    bool shouldRender = false;

    bool running = true;

    while(running){

        Uint64 current = SDL_GetPerformanceCounter();

        double elapsed = (current-previous) * 1000;
        elapsed = (double) (elapsed / SDL_GetPerformanceFrequency() );

        previous = current;

        // handleEvents()
        handleEvents();

        // when we press escape reset x to 0 to keep testing
        // when he goes off screen
        if(key_states[SDL_SCANCODE_ESCAPE]) xx = 0;

        accumulator+=elapsed;

        if(accumulator >= miliPerFrame * frameSkip) accumulator = 0;

        shouldRender = accumulator >= miliPerFrame;


        while(accumulator >= miliPerFrame){


            // update()
            //cout << playSpeed << endl;
            double delta = ceil(elapsed);

            if(delta > deltaSkip) delta = 1;
            //if(elapsed >= 1) delta = elapsed;
            xx+= playSpeed * delta;// * (1 / fps);
            // /update()

            accumulator -= miliPerFrame; //get what's left over

        }
      
        if(shouldRender){
          // render()
          SDL_SetRenderDrawColor(gameRenderer, 0xFF, 0xFF, 0xFF, 0xFF);
          SDL_RenderClear(gameRenderer);
          imageController.drawImage("colorkeytest", floor(xx), 0);
          SDL_RenderPresent(gameRenderer);
          // /render()
        }      


    }
}

 

Edited by ScyllaBus

Share this post


Link to post
Share on other sites
Advertisement

I'm out of practice with SDL, so can't comment on the best-practice SDL. But I'm familiar with the Fix Your Timestep article and have used it to guide my own game development.

First, I'm a little unclear as to what some of your code does, because the calculations with current, previous, elapsed, and delta are hard to follow. What exactly is elapsed? What's up with xx, playSkip, and delta? Why does delta reset to 1 (shouldn't it reset to 0? But then again... don't follow what delta actually is for.. in fact, that whole while loop is funky)?

Also, are you sure you know where your bottlenecks are? E.g., what happens in handleEvents()?

And, where is your fixed timestep? There's some accumulator math in the while loop, but nothing where you're updating your game world based on a fixed dt.

I'm out of practice with SDL, but I can try to offer some feedback (I'm familiar with the Fix Your Timestep article and have used it to guide my own game development).

First, I'm a little unclear as to what the xx variable does. Also, the calculations with current, previous, elapsed, and delta are hard to follow. What exactly is elapsed? What's up with xx, playSkip, and delta? Why does delta reset to 1 (shouldn't it reset to 0? But then again... don't follow what delta actually is for)

Also, are you sure you know where your bottlenecks are? E.g., what happens in handleEvents()? And where is your fixed timestep? I see a while loop where you do some math, but nothing where you're updating your game world based on a fixed dt. 

Share this post


Link to post
Share on other sites
On 10/22/2017 at 9:15 AM, ScyllaBus said:

So yeah, currently the loop works but I'm afraid as I develop the game more and have to render more, eventually something I'm doing in my loop could cause slowdowns or larger CPU usage. Does the structure of the game loop below seem okay or is there something I can do to optimize it?

If you have nothing to prove it is and where it is slow, then it's not slow. Until you can prove it, at least. Except for on-the-spot optimizations and on-the-planning optimizations (which can easily become premature optimizations), nothing else should be optimized until your profiler DOES tell you that something is too slow.

Instead, focus on features until your frame rate drops, or the project is on polishing phase. Fast code usually is dozens of times slower to change, and you'll need to change things a lot.

This being said, it seems like you're not putting the loop thread to sleep. This means that the loop will run at 100% even if there is nothing to do, constantly checking if it should run a logic iteration and if should render. In other words, your task manager will show the executable as a beast even when it is actually using the processor to process nothing. Be aware that once you put your thread to sleep, it is the Operational System that will bring it back to life, but you won't have full control on "when" that'll be.

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  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!