Choppy Performance for Moving Graphics

I have two programs right now. One moves an image from left to right and the other moves a rectangle the same. For the image, the movement is jerky and it shudders as it moves. With the rectangle, the movement is also jerky, and the left and right sides distort. Also, sometimes the rectangle turns to a dark gray for the last 100 out of 1000 loops (initially blue rectangle on black background).

In order to fix this, I have tried several solutions. I tried sleeping X time after each loop, I tried creating a frame rate and sleeping until the time difference matched or exceeded the frame time, I tried using a variable based on the time difference and desired fps to update the movement, and I have tried counter loops. None of them work and produce a similar effect.

So my question is, how can I create a proper timing loop and/or movement formula for my image and shape movement in order to create smooth movements? I don’t want people to get motion sick playing my games :slight_smile:

I am running SDL2/C++ on Ubuntu 16.04. Here is some code for one of my rectangle attempts:
#include </usr/include/SDL2/SDL.h>
#include
void init(SDL_Window * &win, SDL_Renderer * &ren,
int w, int h){
SDL_Init(SDL_INIT_EVERYTHING);
win = SDL_CreateWindow(“Template”,
100, 100, w, h, SDL_WINDOW_SHOWN);
ren = SDL_CreateRenderer(win, -1,
SDL_RENDERER_ACCELERATED |
SDL_RENDERER_PRESENTVSYNC);
}
SDL_Rect makeRect(int x, int y, int w, int h){
SDL_Rect rect;
rect.x = x;
rect.y = y;
rect.w = w;
rect.h = h;
return rect;
}
void clearScreen(SDL_Renderer * &ren){
SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
SDL_RenderClear(ren);
}
int main(int argc, char* argv[]){
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
float speed = 0.2;
float t0;
float position_X = 50.0;
float fps = 60;
float fpms = fps / 1000.0;
SDL_Window *window;
SDL_Renderer *renderer;
init(window, renderer, SCREEN_WIDTH, SCREEN_HEIGHT);
SDL_Rect r = makeRect(50, 50, 50, 50);
t0 = SDL_GetTicks();
for (int i = 0; i < 1000; i++){
clearScreen(renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
SDL_RenderFillRect(renderer, &r);
SDL_RenderPresent(renderer);
position_X += speed;
while ((SDL_GetTicks() - t0) < fpms);
t0 = SDL_GetTicks();
r.x = (int)position_X;
std::cout << "Position: " << (int)position_X << std::endl;
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

Something so simple shouldn’t be choppy at all. Can you post your code so we can look at it?

I have posted my code for one of the rectangle movement attempts. I am having trouble formatting it correctly with the forum’s code, so I apologize if it looks strange.

So one thing I see here which may be causing issues is,

SDL_RENDERER_PRESENTVSYNC forces v-sync “Runs at the max refresh rate of your monitor”

Try remove

while ((SDL_GetTicks() - t0) < fpms);
t0 = SDL_GetTicks();

Looks to me like you’re spinwaiting in there when what you really want is vsync.

Thank you for letting me know that about the v-sync. Most of my code came from a tutorial I modified, so I didn’t fully understand all of it.

I removed the lines you suggested, but unfortunately the problem persists.

I will send on a sample and you can let me know if its also having the same issues.

1 Like

Thank you, I will test it out.

Please ask if you any questions you have about this code.
Don’t forget to add the includes you use .
Example include </usr/include/SDL2/SDL.h>

int main(int argc, char **args) {

    bool quit = false;

    SDL_Init( SDL_INIT_EVERYTHING );
    SDL_Window* window = SDL_CreateWindow( "", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, 0 );
    SDL_Renderer* renderer = SDL_CreateRenderer( window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC );

    // You don't need to create a function to initialize a SDL_Rect
    SDL_Rect rect {0, 0, 100, 100};

    SDL_Event e;
    while (!quit) {
        while (SDL_PollEvent(&e)) {
            if (e.type == SDL_QUIT) {
                quit = true;
            }
        }
        // This just resets the rect to position 0 when it goes off the screen so you can see the movement
        rect.x += 2;
        if (rect.x > 800) {
            rect.x = -100;
        }

        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);

        SDL_RenderClear(renderer);
        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
        SDL_RenderFillRect(renderer, &rect);
        SDL_RenderPresent(renderer);

    }
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

Thanks much for sending me an example.

I see a red rectangle going from left to right. The performance looks a bit choppier than the blue rectangle’s movement. The best I can describe the problem is that there is an area on both the left and right sides of the rectangle, of the same height as the rectangle and about 10 pixels in width that doesn’t get drawn correctly. It’s almost like narrow rectangles of different heights are being subtracted from the red rectangle as it moves.

Here is a screenshot:

This may not be a SDL issue hmmm.
Can you tell me how you built / compiled the files.
Are you running a dedicated graphics card ?

Also run top in a terminal to see what the top 10 process running are and whats there memory consumption. Maybe related.

I used gedit to create my cpp files and then I use the following command in the terminal to create an executable:
g++ *.cpp -std=c++11 -o sample -lSDL2

I run the program with:
./sample

I do have a dedicated graphics card. Here is a list of my top 6 processes, because the rest jump around and change CPU from 0 to 0.5 and MEM stays at 0.0:
Xorg 100% CPU, 0.1% MEM
compiz 40% CPU, 0.1% MEM
Web Content 5% CPU, 0.1% MEM
firefox 5% CPU, 0.2% MEM
ibus-daemon 0.7% CPU, 0.0% MEM
top 0.7% CPU, 0.0% MEM

Have a quick google on why xorg is 100%
It could be the issue I reckon. If you cpu is getting hammered then everything else will be slow.

It appears that my graphics card does not have a compatible driver in Ubuntu 16.04, so the system resources are being eaten up to create the GUI interface. I tried some suggestions, but it looks like short of installing a new graphics card or downgrading the OS, that I need to find another computer to work on.

Thank you for all of your help, and I will post back here when I have run the code on another computer so I can 100% confirm that it was a problem with my computer only.

I ran your code on a Windows XP machine and it works perfectly. I can only conclude then that my old, unsupported graphics card is preventing my Linux machine from properly rendering the SDL output. Problem solved!