Cannot move Rect

This seems to be the problem, except when I try to call draw() in my loop function, the window just goes white with black trying to clip in.

I don’t quite understand how you mean. I think the normal procedure is to first call SDL_RenderClear, and then use “Render” functions such as SDL_RenderCopy or SDL_RenderFillRect to draw the stuff that you want to display, and finally you call SDL_RenderPresent to update the screen. This is done every frame.

This is all the current code in my draw function.

screenSurface = SDL_GetWindowSurface(window);
    SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0x00, 0x00, 0x00));
    SDL_UpdateWindowSurface(window);

    SDL_RenderClear(renderer);

    //Paddle 1

    paddle1.w = 15;
    paddle1.h = paddle1h;
    paddle1.x = 30 - paddle1.w / 2;
    paddle1.y = paddle1y;

    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderFillRect(renderer, &paddle1);

    //Paddle 2

    paddle2.w = 15;
    paddle2.h = 120;
    paddle2.x = 1250 - paddle2.w / 2;
    paddle2.y = Height/2 - paddle2.h / 2;

    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderFillRect(renderer, &paddle2);

    //Ball

    ballSurface = IMG_Load("assets/ball.png");
    ballTexture = SDL_CreateTextureFromSurface(renderer, ballSurface);
    SDL_FreeSurface(ballSurface);

    destR.h = 16;
    destR.w = 16;
    destR.x = Width/2 - destR.w / 2;
    destR.y = Height/2;

    SDL_RenderCopy(renderer, ballTexture, NULL, &destR);

    //Text

    char *fontPath;
    fontPath = "assets/font.ttf";

    font = TTF_OpenFont(fontPath, 48);
    if(font == NULL) printf("Couldn't find font!\n");

    getTextRect(renderer, Width / 4, 50, "00", font, &fontScore1Texture, &fontScore1Rect);
    getTextRect(renderer, 960, 50, "00", font, &fontScore2Texture, &fontScore2Rect);

    SDL_RenderCopy(renderer, fontScore1Texture, NULL, &fontScore1Rect);
    SDL_RenderCopy(renderer, fontScore2Texture, NULL, &fontScore2Rect);

    SDL_RenderPresent(renderer);

But when I call draw() in my loop function, it just makes the screen white with black trying to clip in, and it doesnt manage memory correctly as its just… goes up (Does not do this when not called every frame)

I don’t understand what this means, but perhaps it doesn’t matter because I see some problems…

The documentation for SDL_GetWindowSurface says:

You may not combine this with 3D or the rendering API on this window.

I think you should remove the following lines:

screenSurface = SDL_GetWindowSurface(window);
SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0x00, 0x00, 0x00));
SDL_UpdateWindowSurface(window);

Drawing the background colour is the job of SDL_RenderClear. Just make sure to call SDL_SetRenderDrawColor to specify what background colour you want before calling SDL_RenderClear.

It’s because you are not freeing the ball texture using SDL_DestroyTexture and you are not freeing the font using TTF_CloseFont.

Creating surfaces, textures and fonts is relatively slow. It’s probably not something you want to do every frame. Instead I would suggest that you do it once at the start and then you keep reusing the same textures and fonts for the rest of the game (or until you don’t need them anymore).

Thanks it works now :slight_smile:

I updated my cleanup function to this, however it still doesnt manage memory correctly.

int cleanup() {
    TTF_CloseFont(font);
    SDL_DestroyTexture(ballTexture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    TTF_Quit();
    IMG_Quit();
    SDL_Quit();

    return 0;
}

Have you updated your draw() function so that it doesn’t create a new texture and font each time it’s called? If it’s still the same as before then you are only freeing the last texture and font that you created. The ones you created earlier are “leaked”.

It’s of course also possible that there are other memory leaks in the code that you haven’t shown (e.g. in getTextRect).

Yeah I updated the draw function:

int draw() {
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);

    //Paddle 1

    paddle1.w = 15;
    paddle1.h = paddle1h;
    paddle1.x = 30 - paddle1.w / 2;
    paddle1.y = paddle1y;

    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderFillRect(renderer, &paddle1);

    //Paddle 2

    paddle2.w = 15;
    paddle2.h = paddle1h;
    paddle2.x = 1250 - paddle2.w / 2;
    paddle2.y = paddle2y;

    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderFillRect(renderer, &paddle2);

    //Ball

    destR.h = 16;
    destR.w = 16;
    destR.x = Width/2 - destR.w / 2;
    destR.y = Height/2;

    SDL_RenderCopy(renderer, ballTexture, NULL, &destR);

    //Text

    getTextRect(renderer, Width / 4, 50, "00", font, &fontScore1Texture, &fontScore1Rect);
    getTextRect(renderer, 960, 50, "00", font, &fontScore2Texture, &fontScore2Rect);

    SDL_RenderCopy(renderer, fontScore1Texture, NULL, &fontScore1Rect);
    SDL_RenderCopy(renderer, fontScore2Texture, NULL, &fontScore2Rect);

    SDL_RenderPresent(renderer);

With an init function

font = TTF_OpenFont("assets/font.ttf", 48);
    if(font == NULL) printf("Couldn't find font!\n");

    ballSurface = IMG_Load("assets/ball.png");
    ballTexture = SDL_CreateTextureFromSurface(renderer, ballSurface);
    SDL_FreeSurface(ballSurface);

And here’s getTextRect:

int textWidth;
    int textHeight;
    SDL_Color textColor = {255, 255, 255, 255};
    SDL_Surface* surface = TTF_RenderText_Solid(font, text, textColor);

    *texture = SDL_CreateTextureFromSurface(renderer, surface);
    textWidth = surface->w;
    textHeight = surface->h;
    SDL_FreeSurface(surface);
    rect->x = x;
    rect->y = y;
    rect->w = textWidth;
    rect->h = textHeight;

You create a texture inside getTextRect. Do you free it?

I updated my cleanup to do this, it’s still having memory problems

int cleanup() {
    TTF_CloseFont(font);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyTexture(ballTexture);
    SDL_DestroyTexture(fontScore1Texture);
    SDL_DestroyTexture(fontScore2Texture);
    SDL_DestroyWindow(window);
    TTF_Quit();
    IMG_Quit();
    SDL_Quit();

    return 0;
}

I think it’s the same type of problem as I described earlier.

[…] you are only freeing the last texture […] The ones you created earlier are “leaked”.

How many times do you call SDL_CreateTextureFromSurface compared to SDL_DestroyTexture? If it’s not the same number of times then you definitly have a problem. Think about it.

I’m calling both 3 times. 1 time from ballTexture = SDL_CreateTextureFromSurface(renderer, ballSurface);, and two from getTextRect

But don’t you call getTextRect more than twice?

No, it’s only twice as of now

So you are only calling draw() once???

Note that I’m not talking about the number of times they are written in the code. I’m talking about the number of times that those functions gets called when you run your program.

If you really are calling draw() only once, which ends up calling getTextRect only twice in total, then you shouldn’t see memory usage increase more and more the longer your program runs. If that’s the case then the memory leak is probably somewhere else.

If what you see is instead just that the memory usage does not drop down to near zero after calling cleanup() then I would not be too concerned about that. It’s pretty normal.

Holy I just realized I’m dumb - the one time it calls draw() is in a loop

Ah the memory usage stops if I bring it out the loop, but the rect doesnt move when I press s

Yeah, it most probably should be called from inside the loop.

Back to the question of how many times SDL_CreateTextureFromSurface gets called compared to SDL_DestroyTexture? Do you now see why this is a problem?

Yeah… I just fixed it thankfully though thanks for all your help :slight_smile: