在自动分配的表面上使用SDL_FreeSurface

Using SDL_FreeSurface on Automatically Allocated Surfaces

本文关键字:SDL FreeSurface 表面上 分配      更新时间:2023-10-16

我在开发的一款游戏中遇到了严重的内存使用问题。我让它一直运行,看到它使用了超过1.5 GB的内存,从最初的30 MB。我已经确定了两个函数的主要原因,它们被粘贴在下面。从研究这个问题,我得出的结论是,其中一个问题是,创建一个TTF表面使用TTF_RenderText_Blended创建一个新的表面,这是没有得到释放。如何释放这个自动生成的曲面?我不能使用SDL_FreeSurface,因为我没有表面名称。

我对第二个函数中发生的事情有点困惑。我假设发生了类似的事情(一个函数被调用并创建了第二个表面,而这个表面没有被释放),但我不确定是什么原因造成的。这不是一个问题,因为我计划实现这个函数的不同版本,这将不需要创建任何表面。

TTF功能:

void speak(int id, string message, SDL_Renderer *ren, TTF_Font *font, SDL_Color color, int x, int y)
{ 
    SDL_Surface *surf = TTF_RenderText_Blended(font, message.c_str(), color);
    if(surf == nullptr) cout << "surf error";
    SDL_Texture *texture = SDL_CreateTextureFromSurface(ren, surf);
    SDL_FreeSurface(surf);
    if(texture == nullptr) cout << "tex error";
    SDL_Rect rect;
    SDL_QueryTexture(texture, NULL, NULL, &rect.w, &rect.h);
    rect.x = x-rect.w/2 - camera_xpos*10;
    rect.y = y+sprite_set_array[idList[id].sprite].y_offset - rect.h - camera_ypos*10;
    SDL_RenderCopy(ren, texture, NULL, &rect);
}

第二个功能(用于显示精灵):

void displayAtPos(int id, int sprite_num, int x, int y, SDL_Window *win, SDL_Renderer *ren)             
{
   if(idList[id].type == 5) sprite_num = 11;
   string sprite = sprite_set_array[sprite_num].getString(idList[id].facing,     idList[id].sprite_counter);
    SDL_Texture *texture = nullptr;
    SDL_Surface *bmp = SDL_LoadBMP(sprite.c_str());
    if(bmp==nullptr) {bmp = SDL_LoadBMP("junk.bmp");}
    SDL_SetColorKey( bmp, SDL_TRUE, SDL_MapRGB(bmp->format, 255, 0, 255) );
    SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp);
    SDL_FreeSurface(bmp);
    if (tex == nullptr) { cout << "SDL_CreateTextureFromSurface Error: " << SDL_GetError() << endl; }
    SDL_Rect rect;
    rect.x = x;
    rect.y = y+sprite_set_array[idList[id].sprite].y_offset;
    SDL_QueryTexture(tex, NULL, NULL, &rect.w, &rect.h);
    SDL_RenderCopy(ren, tex, NULL, &rect);
    if(idList[id].active_effect > 0 && idList[id].active_effect_counter > 0)            //Display a texture from the status effects array.
    {
        SDL_RenderCopy(ren, effect_array[idList[id].active_effect_counter%3], NULL, &rect);
        idList[id].active_effect_counter--;
    }
}

你还需要销毁/释放SDL_Textures:

void SDL_DestroyTexture(SDL_Texture* texture)

如果可以的话,我还建议您存储SDL_Texture*。这样你就不用一直重新创建它了