Home > Back-end >  I get oom kills after a while because I redraw an image evry frame
I get oom kills after a while because I redraw an image evry frame

Time:06-13

code:

#include"global.h"
#include"tools/entity.h"
#include"tools/input.c"
static const int width = 800;
static const int height = 600;
int main (int argc, char **argv)
{
    SDL_Init(SDL_INIT_VIDEO);
    int init = IMG_Init(IMG_INIT_PNG);
    if((init & IMG_INIT_PNG) != IMG_INIT_PNG) {
        printf("Couldnt load images :P");
    }   
    // Create the window
    SDL_Window *window = SDL_CreateWindow("Ferengine",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,width,height,SDL_WINDOW_SHOWN);
    // renderer
    SDL_Renderer *renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);    
//  SDL_Surface * image = IMG_Load("funnyman.png");
//  if(!image) { printf("Could not load image because : %s\n",IMG_GetError()); }
//  SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, image);
    // settings
/*  SDL_SetRenderDrawColor(renderer,255,0,0,255);
    SDL_SetWindowOpacity(window,1.0f);
*/
    
    entity2D player;
    player.posx = 0;
    player.posy = 0;
    player.sprite = "funnyman.png";
    int speed = 100;
    // loop 
    bool running = true;
    SDL_Event event;
    while(running) 
    {
        while(SDL_PollEvent(&event))
        {
            if(event.type == SDL_QUIT)
            {
                running = false;
            }
        }   
    SDL_RenderClear(renderer);
//  SDL_RenderCopy(renderer, texture, NULL, NULL);
    drawImage("funnyman.png",renderer,10,10,100,100);
    drawEntity(player,renderer,100,100);
    switch(getKeyPressed()) {
        case SDLK_w:
            player.posy  = 1 * speed;
            break;
        case SDLK_s:
            player.posy -= 1 * speed;
            break;
        case SDLK_d:
            player.posx  = 1 * speed;
            break;
        case SDLK_a:
            player.posx -= 1 * speed;
            break;
        case SDLK_q:
            running = false;
        default:
            break;
    }
    SDL_RenderPresent(renderer);

    }
    // release resources
    IMG_Quit();
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

when I run this (I wrote some stuff to draw entity's and images) it works and the character moves but when I don't move for a while it just closes the window also if you were wondering getKeyPressed() returns an int(because sdlkeycode is an int) so when I run gcc -o Build/Ferengine Source/main.c -lSDL2 -lSDL2_image -ldl with this code it redraws the image every frame but because of that I get oom kills so I need a way to only have to draw the image once without it getting cleared off screen (removing render clear doesnt work) and for the player only clear the screen once the player has moved

CodePudding user response:

You're most likely running out of memory and getting OOM killed, probably because your drawImage() (which you didn't include here) is reloading the texture from file every frame.

CodePudding user response:

I fixed it by changing everything except for draw to only run once https://pastebin.com/Lu44Majk

#include"../global.h" // includes sdl,sdl2_image, and std libraries
void unloadImage(SDL_Texture * texture) {
    SDL_DestroyTexture(texture);
}
SDL_Rect dstrect;
SDL_Rect srcrect;
int initImgSys() {
    int init = IMG_Init(IMG_INIT_PNG);
    if((init & IMG_INIT_PNG) != IMG_INIT_PNG) {
        printf("Couldnt init SDL2_image do you have it installed?");
    }
    return 0;
}
SDL_Surface *loadImage (char *filename) {
 
    SDL_Surface * image = IMG_Load(filename);
    if(!image) { printf("Could not load image because : %s\n",IMG_GetError()); EXIT_FAILURE; }
 
    return image;
}
SDL_Texture *createImageTexture(SDL_Surface * image,SDL_Renderer * rend) {
    SDL_Texture * texture = SDL_CreateTextureFromSurface(rend, image);
    SDL_FreeSurface(image);
    return texture;
}
int drawImage (SDL_Texture *texture,SDL_Renderer *rend,int posx,int posy,int width,int height) {
    dstrect.x = posx;
    dstrect.y= posy;
    dstrect.w = width;
    dstrect.h = height;
    SDL_RenderCopy(rend, texture, NULL, &dstrect);
    SDL_Event event;
    while(SDL_PollEvent(&event))
    {
        if(event.type == SDL_QUIT)
        {
            unloadImage(texture);
            IMG_Quit();
        }
    }
    return 0;
}

example: https://pastebin.com/d3aUJiPA

#include"global.h"
#include"tools/entity.h" // has image.h included
#include"tools/input.c"
static const int width = 800;
static const int height = 600;
int main (int argc, char **argv)
{
    SDL_Init(SDL_INIT_VIDEO);
    int init = IMG_Init(IMG_INIT_PNG);
    if((init & IMG_INIT_PNG) != IMG_INIT_PNG) {
        printf("Couldnt load images :P");
    }   
    // Create the window
    SDL_Window *window = SDL_CreateWindow("Ferengine",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,width,height,SDL_WINDOW_SHOWN);
    // renderer
    SDL_Renderer *renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);    
//  SDL_Surface * image = IMG_Load("funnyman.png");
//  if(!image) { printf("Could not load image because : %s\n",IMG_GetError()); }
//  SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, image);
    // settings
/*  SDL_SetRenderDrawColor(renderer,255,0,0,255);
    SDL_SetWindowOpacity(window,1.0f);
*/
   // create sprites
    SDL_Surface * funnyman_surface = loadImage("funnyman.png");
    SDL_Texture * funnyman = createImageTexture(funnyman_surface,renderer);
    entity2D player;
    player.posx = 0;
    player.posy = 0;
    player.sprite = funnyman;
    int speed = 100;
 
    // loop 
    bool running = true;
    SDL_Event event;
    while(running) 
    {
        while(SDL_PollEvent(&event))
        {
            if(event.type == SDL_QUIT)
            {
                running = false;
            }
        }   
    SDL_RenderClear(renderer);
//  SDL_RenderCopy(renderer, texture, NULL, NULL);
    switch(getKeyPressed()) {
        case SDLK_w:
            player.posy  = 1 * speed;
            break;
        case SDLK_s:
            player.posy -= 1 * speed;
            break;
        case SDLK_d:
            player.posx  = 1 * speed;
            break;
        case SDLK_a:
            player.posx -= 1 * speed;
            break;
        case SDLK_q:
            running = false;
        default:
            break;
    }
 
  drawImage(funnyman,renderer,0,12,100,100);
  drawEntity(player,renderer,100,100);
       SDL_RenderPresent(renderer);
 
    }
    // release resources
    IMG_Quit();
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
 
    return 0;
}
  • Related