简体   繁体   English

SDL2渲染文本问题

[英]SDL2 rendering text issues

I have a menu where there is a lot of text being rendered that can change in size/color/position, so I made two functions in my menu class...: 我有一个菜单,其中渲染了很多可以改变大小/颜色/位置的文本,因此我在菜单类中做了两个功能...:

void drawText(string text,int text_size,int x,int y, Uint8 r,Uint8 g,Uint8 b);
void updateTexts();

The updateTexts() function sits in the game loop and contains many drawText functions, When I launch the program I notice the programs memory gradually increase from 4mb about 1gb (it should stay at 4mb) then it crashes. updateTexts()函数位于游戏循环中,并包含许多drawText函数,当我启动程序时,我注意到程序的内存从4mb逐渐增加到大约1gb(应该保持在4mb),然后崩溃。 I assume the problem exists because TTF_OpenFont" is run constantly though I needed a way to be able to create new font sizes on the fly as my menu changes based on the users input. 我认为存在问题是因为TTF_OpenFont“一直运行,尽管我需要一种方法来根据用户输入即时更改菜单来创建新的字体大小。

Is there a better way to do this? 有一个更好的方法吗?

code for the two functions: 这两个功能的代码:

void Menu::drawText(string text,int text_size,int x,int y, Uint8 r,Uint8 g,Uint8 b)
{
    TTF_Font* arial = TTF_OpenFont("arial.ttf",text_size);
    if(arial == NULL)
    {
        printf("TTF_OpenFont: %s\n",TTF_GetError());
    }
    SDL_Color textColor = {r,g,b};
    SDL_Surface* surfaceMessage = TTF_RenderText_Solid(arial,text.c_str(),textColor);
    if(surfaceMessage == NULL)
    {
        printf("Unable to render text surface: %s\n",TTF_GetError());
    }
    SDL_Texture* message = SDL_CreateTextureFromSurface(renderer,surfaceMessage);
    SDL_FreeSurface(surfaceMessage);
    int text_width = surfaceMessage->w;
    int text_height = surfaceMessage->h;
    SDL_Rect textRect{x,y,text_width,text_height};

    SDL_RenderCopy(renderer,message,NULL,&textRect);
}

void Menu::updateTexts()
{
    drawText("Item menu selection",50,330,16,0,0,0);
    drawText("click a menu item:",15,232,82,0,0,0);
    drawText("item one",15,59,123,0,0,0);
    drawText("item two",15,249,123,0,0,0);
    drawText("item three",15,439,123,0,0,0);
    drawText("item four",15,629,123,0,0,0);
}

Each opened font, created surface and created texture uses memory. 每个打开的字体,创建的表面和创建的纹理都使用内存。

If collection of different resources that you require is limited, eg only 3 different text_size , it's better to create them once and then reuse. 如果您需要的不同资源的收集受到限制,例如仅3个不同的text_size ,则最好一次创建一次然后重用。 For example by storing them in some kind of cache: 例如,通过将它们存储在某种缓存中:

std::map<int, TTF_Font*> fonts_cache_;

TTF_Font * Menu::get_font(int text_size) const
{
  if (fonts_cache_.find(text_size) != fonts_cache_.end())
  {
    // Font not yet opened. Open and store it.
    fonts_cache_[text_size] = TTF_OpenFont("arial.ttf",text_size);
    // TODO: error checking...
  }

  return fonts_cache_[text_size];
}

void Menu::drawText(string text,int text_size,int x,int y, Uint8 r,Uint8 g,Uint8 b)
{
  TTF_Font* arial = get_font(text_size)
  ...
}

Menu::~Menu()
{
  // Release memory used by fonts
  for (auto pair : fonts_cache_)
    TTF_CloseFont(pair.second);
  ...
}

For dynamic resources that should be allocated on each method invocation you should not forget to free them. 对于应在每次方法调用中分配的动态资源,您不应忘记释放它们。 Currently you are not releasing memory of TTF_Font* arial , SDL_Texture* message ; 当前,您不释放TTF_Font* arialSDL_Texture* message内存; do: 做:

void Menu::drawText(string text,int text_size,int x,int y, Uint8 r,Uint8 g,Uint8 b)
{
  ...
  TTF_CloseFont(arial);
  SDL_DestroyTexture(message);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM