Advertisement Jump to content
Sign in to follow this  
ScyllaBus

C++ Can my game loop be optimized?

This topic is 450 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Sign in to follow this  

  • Advertisement
×

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!