SDL_FontCache icon indicating copy to clipboard operation
SDL_FontCache copied to clipboard

Drawing text disapear after window resize

Open psykokwak-com opened this issue 4 years ago • 16 comments

Hi all, When the renderer is created with SDL_RENDERER_ACCELERATED flag, the drawing text disapear after resizing the window. Using the SDL_RENDERER_SOFTWARE flag, it works well.

psykokwak-com avatar Mar 24 '20 08:03 psykokwak-com

Hi, I just found this library and came across the same issue.

If you edit this line 1185. It seems to work with the following flag which is 1.

fc_has_render_target_support = (info.flags & SDL_RENDERER_SOFTWARE);

It will also work with flag of 8192.


Also tested with SDL_RenderSetLogicalSize which is nice. @grimfang4 Thanks!

horseyhorsey avatar Apr 05 '20 06:04 horseyhorsey

Thansk. It works. I simply disabled this flag : fc_has_render_target_support = 0;

psykokwak-com avatar Apr 05 '20 08:04 psykokwak-com

Changing breaks UTF-8.

image

horseyhorsey avatar Apr 05 '20 09:04 horseyhorsey

You are right. UTF8 is broken :/

psykokwak-com avatar Apr 05 '20 09:04 psykokwak-com

Line 978: if(!fc_has_render_target_support)

if(fc_has_render_target_support > 0)

horseyhorsey avatar Apr 05 '20 10:04 horseyhorsey

No. UTF-8 is still broken.

psykokwak-com avatar Apr 05 '20 11:04 psykokwak-com

Can you post a program that demonstrates this for further investigation? Resizing a window shouldn't cause the context to be lost, as far as I understand, though fullscreening might. If the context is lost, then textures would be dropped. SDL can restore some textures, which might be what is happening here when comparing textures created with SDL_CreateTextureFromSurface() and textures created as render targets. With a definite repro case, I can look further into this.

When disabling render targets like what was suggested above, you are losing the ability to render new glyphs onto the cache level textures at drawtime. That's why UTF-8 would not work. If you know which glyphs you will need, you can work around this by preloading them with FC_SetLoadingString(). It does seem like sometimes this might be desirable, so maybe we can add a function and manual setting for disabling render target support.

grimfang4 avatar Apr 05 '20 19:04 grimfang4

Ok, Here a minimal test case :

int main(int argc, char** argv)
{
  if (SDL_Init(SDL_INIT_VIDEO) != 0)
    return -1;

  if (TTF_Init())
    return -1;

  // This change nothing
  /*
  SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");

  if (SDL_GL_SetSwapInterval(-1))
    SDL_GL_SetSwapInterval(1);
  */

  SDL_Window *_pWindow = SDL_CreateWindow("test window",
    SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720,
    SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_MAXIMIZED);
  if (!_pWindow)
    return -1;


  // Using this line makes the text disappear as soon as I resize the window
  // Removing the SDL_RENDERER_TARGETTEXTURE changes nothing
   SDL_Renderer *_pRenderer = SDL_CreateRenderer(_pWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE);

   // Using this line makes things working right :)
   // Removing the SDL_RENDERER_TARGETTEXTURE changes nothing
   //SDL_Renderer *_pRenderer = SDL_CreateRenderer(_pWindow, -1, SDL_RENDERER_SOFTWARE | SDL_RENDERER_TARGETTEXTURE);

   // This changes nothing
   //SDL_SetRenderDrawBlendMode(_pRenderer, SDL_BLENDMODE_BLEND);

   FC_Font *_pFontTextHeader = FC_CreateFont();
   FC_LoadFont(_pFontTextHeader, _pRenderer, "res/header.ttf", 14, FC_MakeColor(200, 200, 200, 255), TTF_STYLE_NORMAL);

   int counter = 0;
   while (42)
   {
     SDL_Event ev;
     while (SDL_PollEvent(&ev))
     {
       if (ev.type == SDL_QUIT)
         return -2;
     }

     int windowWidth = SDL_GetWindowSurface(_pWindow)->w;
     int windowHeight = SDL_GetWindowSurface(_pWindow)->h;

     // Draw black background
     SDL_Rect recBg = { 0, 0, windowWidth, windowHeight };
     SDL_SetRenderDrawColor(_pRenderer, 0, 0, 0, 255);
     SDL_RenderFillRect(_pRenderer, &recBg);

     // Using test text with UTF8 symbol (°)
     FC_DrawAlign(_pFontTextHeader, _pRenderer, static_cast<float>(windowWidth / 2), static_cast<float>(windowHeight / 2), FC_ALIGN_CENTER, u8"°° %d °°", counter++);

     SDL_RenderPresent(_pRenderer);

     SDL_Delay(100);
   }

  return 0;
}

psykokwak-com avatar Apr 05 '20 19:04 psykokwak-com

Can you post a program that demonstrates this for further investigation? Resizing a window shouldn't cause the context to be lost, as far as I understand, though fullscreening might.

I used your demo for my tests.

  • Add accelerated and resize for textures to disappear on resize with UTF-8 intact. main.c 326 window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); main.c 333 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);

  • A hack to fix resize but break UTF-8

SDL_FontCache.c 1185 fc_has_render_target_support = (info.flags & 0);

horseyhorsey avatar Apr 06 '20 06:04 horseyhorsey

For information, I have this issue on Windows (10) with SDL2-2.0.12.x64 and SDL2_ttf-2.0.15.x64

psykokwak-com avatar Apr 09 '20 07:04 psykokwak-com

Any news ?

psykokwak-com avatar May 29 '20 14:05 psykokwak-com

I'm also getting the same error.

ghost avatar Dec 29 '20 02:12 ghost

Got the same problem. Work around was to free the font FC_FreeFont, then recreate FC_CreateFont and load again FC_LoadFont on the window resise event SDL_WINDOWEVENT_SIZE_CHANGED. Not ideal but can live with that.

manupinot avatar Jan 24 '21 09:01 manupinot

By the way, the problem is on windows 10, it works fine on Linux.

manupinot avatar Jan 24 '21 09:01 manupinot

I have also had a report that on Windows resizing my game's window results in text disappearing.

I found this thread https://discourse.libsdl.org/t/sdl2-0-10-textures-disappearing-renderer-causing-error-when-resizing-window-with-a-render-target-texture/26598

which suggests using an SDL hint to use opengl instead of directX.

From the error message I assume it’s not using OpenGL but Direct3D, which is the default on Windows. It might be interesting to see if OpenGL behaves differently, which you can do by setting this hint before creating the renderer:

SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl");

I add this line right before I created the renderer, and it seems to have resolved the issue for me (tested using Wine on my Ubuntu 20.04 system).

So in terms of solving the issue, maybe the directX vs OpenGL thing is a clue?

gbgames avatar Apr 12 '22 03:04 gbgames

To fix this issue under direct3d, you have to handle the SDL_RENDER_TARGETS_RESET SDL event type then call FC_ResetFontFromRendererReset() on your fonts objects. Sometime d3d context asks for SDL_RENDER_TARGETS_RESET that require we recreate SDL_TEXTUREACCESS_TARGET textures.

The simplest solution is to keep all your font objects references to a global std::vector<FC_Font *> then :


  while (SDL_PollEvent(&ev))
  {
    if (ev.type == SDL_RENDER_TARGETS_RESET) {
        for (FC_Font* font : _FC_FontList)
            FC_ResetFontFromRendererReset(font, _pRenderer, SDL_RENDER_TARGETS_RESET);
    }
  }

psykokwak-com avatar Apr 17 '22 12:04 psykokwak-com