Tilemap is eating a lot of memory (SDL)

Hello!

I'm making a 2D game and right now I have created a tilemap that is being loaded from a text file and afterwards rendered to the screen. The problem is that I render the tilemap into the main game loop, and this makes it so that the tilemap is eating my memory. After 4 seconds 2GB of my memory is gone. The thing is that I didn't have this problem before when I was using the SDL_blitsurface. After I change to using textures instead, it seems like the program dosen't clear the memory from the previous time the tilemap was pasted to the screen.

Here is my code:

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <iostream>
#include <SDL.h>
#include <fstream>
#include <vector>
#include "src/init.h"
#include "src/tiles.h"
#include "src/draw.h"
#include "src/playerMovement.h"

using namespace std;

SDL_Surface *screenSurface;
SDL_Renderer *renderer;
SDL_Texture *tileTexture;
SDL_Window *window;

int mouseX;
int mouseY;

int main(int argc, char* argv[])
{
    bool quit = false;
    uint32_t FrameStartTimeMs = 0;

    initialize *init = new initialize();
    close *freeMem = new close();
    readMapFromFile *readTileMap = new readMapFromFile();
    playerMovement *movePlayer = new playerMovement();
    drawPlayer *drawPly = new drawPlayer();

    ///Initialize Window
    init->initWindow();

    ///Import Map
    readTileMap->readTileMap();

    tile MAP[TILES_X][TILES_Y];

    while(!quit)
    {
    SDL_GetMouseState(&mouseX,&mouseY);
    FrameStartTimeMs = SDL_GetTicks();

    ///Wait for Inputs
    while (SDL_PollEvent(&event)!= 0)
    {
        if (event.type == SDL_QUIT)
        {
            quit = true;
        }
        if (event.type == SDL_KEYDOWN)
        {
            movePlayer->playerKeyDown();
        }
        else if (event.type == SDL_KEYUP)
        {
            movePlayer->playerKeyUp();
        }
    }

    movePlayer->movePlayer();

    ///Draw Tiles
    for(int y = 0; y < TILES_Y; ++y)
    {
        for(int x = 0; x < TILES_X; ++x)
        {
        Vector2<int> position;

        position.x = x*tile::TILESIZE_X;
        position.y = y*tile::TILESIZE_Y;

        switch(tileMap[y][x])
        {
           case 0:
           break;

           case 1:
           MAP[x][y].render(position.x, position.y,1);
           break;

           case 2:
           MAP[x][y].render(position.x, position.y,2);
           break;

           case 3:
           MAP[x][y].render(position.x, position.y,3);
           break;
        }
        }
    }

    drawPly->drawPlayerSprite(playerMoveX,playerMoveY);

    ///Update Screen
    SDL_RenderPresent(renderer);

    ///60 FPS
    while(SDL_GetTicks() - FrameStartTimeMs < 1000/FPS);
    }

    ///Free Memory
    freeMem->freeMemory();
    return 0;
}


some parts of tiles.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
SDL_Surface *tileSurface = SDL_LoadBMP("tiles.bmp");

void tile::render(int PositionX, int PositionY, int type)
{
    tileTexture = SDL_CreateTextureFromSurface(renderer, tileSurface);

    switch(type)
    {
    case 1:
    tileRectDst.x = PositionX;
    tileRectDst.y = PositionY;
    SDL_RenderCopy(renderer,tileTexture,&tileRectSrc[WALL],&tileRectDst);
    break;

    case 2:
    tileRectDst.x = PositionX;
    tileRectDst.y = PositionY;
    SDL_RenderCopy(renderer,tileTexture,&tileRectSrc[GRASS],&tileRectDst);
    break;

    case 3:
    tileRectDst.x = PositionX;
    tileRectDst.y = PositionY;
    SDL_RenderCopy(renderer,tileTexture,&tileRectSrc[WATER],&tileRectDst);
    break;
    }
}

Last edited on
In the render function you call SDL_CreateTextureFromSurface to create a texture but you never free it with SDL_DestroyTexture. That is why you have a memory leak.

Creating a texture is a relatively costly operation. You probably should hang on to the texture for as long as you are using it so that you don't have to recreate it every time you call render.
Last edited on
@Peter87

Thanks, it fixed the memory leak problem, but I have still some problems. I have created a player sprite that I could move around the screen. But the sprite movement feels laggy and if I draw fewer tiles the player sprite starts suddenly to move smoother. The memory and the cpu usage are low so I think it must be a problem with the way I render things.

draw.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <SDL.h>
#include <fstream>
#include <vector>
#include <windows.h>
#include "init.h"
#include "draw.h"

SDL_Rect playerDst;
SDL_Rect playerSrc;
SDL_Surface *playerSurface = SDL_LoadBMP("player.bmp");
SDL_Texture *playerTexture;

void drawPlayer::drawPlayerSprite(int playerX, int playerY)
{
    playerTexture = SDL_CreateTextureFromSurface(renderer, playerSurface);
    playerDst.x = playerX;
    playerDst.y = playerY;
    playerDst.w = 50;
    playerDst.h = 50;
    SDL_RenderCopy(renderer,playerTexture,NULL,&playerDst);
    SDL_DestroyTexture(playerTexture);
}


playerMovement.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <iostream>
#include <SDL.h>
#include "init.h"
#include "playerMovement.h"
#include "draw.h"

bool up = false;
bool down = false;
bool left = false;
bool right = false;

int playerMoveX = 1366/2;
int playerMoveY = 768/2;
float speed = 400.0 / FPS;

SDL_Event event;

void playerMovement::playerKeyDown()
{
    if (event.key.keysym.sym == SDLK_UP)
    {
    up = true;
    }
    if (event.key.keysym.sym == SDLK_DOWN)
    {
    down = true;
    }
    if (event.key.keysym.sym == SDLK_LEFT)
    {
    left = true;
    }
    if (event.key.keysym.sym == SDLK_RIGHT)
    {
    right = true;
    }
}

void playerMovement::playerKeyUp()
{
    if (event.key.keysym.sym == SDLK_UP)
    {
    up = false;
    }
    if (event.key.keysym.sym == SDLK_DOWN)
    {
    down = false;
    }
    if (event.key.keysym.sym == SDLK_LEFT)
    {
    left = false;
    }
    if (event.key.keysym.sym == SDLK_RIGHT)
    {
    right = false;
    }
}

void playerMovement::movePlayer()
{
    if (up == true)
    {
    playerMoveY -=speed;
    }

    if (down == true)
    {
    playerMoveY +=speed;
    }

    if (left == true)
    {
    playerMoveX -=speed;
    }

    if (right == true)
    {
    playerMoveX +=speed;
    }
}
Last edited on
Topic archived. No new replies allowed.