2

Here is an example:

example Here is the corresponding code:

TTF_Font *Sans = TTF_OpenFont("resources/fonts/lato/Lato-Semibold.ttf", 36);

    if( Sans == NULL )
    {
        std::cout << "Failed to load font! SDL_ttf Error: " << TTF_GetError() << std::endl;
    }

    else
    {
        SDL_Color White = {255, 255, 255};

        SDL_Surface *surfaceMessage = TTF_RenderText_Blended(Sans, "GAME OVER", White);

        SDL_Texture *Message = SDL_CreateTextureFromSurface(renderer_, surfaceMessage);

        SDL_Rect Message_rect;
        Message_rect.x = 100;
        Message_rect.y = 100;
        Message_rect.w = 500;
        Message_rect.h = 500;

        SDL_RenderCopy(renderer_, Message, NULL, &Message_rect);
        SDL_RenderPresent(renderer_);

}

(yes, I free the surface later)

ubadub
  • 3,571
  • 21
  • 32
  • 36 is not very large font size, and you're scaling it to 500x500 output with bilinear interpolation. It's no wonder result is, well, interpolated. Rendering with bigger font size would probably be easiest solution (not saying it is the best though). – keltar Nov 10 '18 at 17:32
  • 1
    @keltar I tried that. Certainly better, but even at very large sizes, while it's a lot less pixelated it's still... rather mediocre looking. Are there better ways? – ubadub Nov 10 '18 at 22:45
  • 2
    Rescaling will always produce blurier image. This text is unlikely to be square, but you putting it into square image, so it will be tilted on vertical direction. Why use scaling at all if you're going for font quality? Take dimensions from `surfaceMessage` and use that as target width/height, adjust font size if required. Other ways would be prerended image in some graphics editor, or SDF fonts (may be very hard to use with SDL as no shaders exposed). – keltar Nov 11 '18 at 07:16
  • @keltar ah! that's exactly what I was looking for! I didn't know you could query `SDL_Texture` for a width and height to ensure a proper resolution. If you post that as an answer, I'll accept it. Thank you so much! – ubadub Nov 11 '18 at 08:23

1 Answers1

6

TTF_RenderText_Blended and other SDL_ttf font rendering functions produces surface based on font size specified when font was opened (along with font style itself and symbols in the text line). You rescale that result to 500x500 rectangle, which causes both proportions distortion and blurier image, as source image have different dimensions.

To avoid that you should avoid rescaling first - use surfaceMessage->w and surfaceMessage->h (or SDL_QueryTexture on Message) to get original dimensions, then RenderCopy to the same sized rectangle.

Of course if text is static and not localised pre-rendering this static image in some graphics editor is also a good option.

As a side note, it may be copy-paste oversimplification, but it appears you opening font and recreating your target texture on each frame. This is very slow and provides almost no benefits.

keltar
  • 17,711
  • 2
  • 37
  • 42
  • FYI `surfaceMessage->w` doesn't seem to work, you have to use `SDL_QueryTexture`. Anyways, thanks a lot! – ubadub Nov 11 '18 at 09:26
  • I can't imagine implementation where texture dimensions will differ from surface's it was created from. Are you saying that's the case for you? – keltar Nov 11 '18 at 11:16
  • No, that's not the issue; `surfaceMessage->w` makes the compiler throw an error that says "Member access into incomplete type `SDL_Texture`" – ubadub Nov 11 '18 at 19:58
  • I've used the same variable names as was in question, implying types are the same. So `SDL_Surface *surfaceMessage` have type `SDL_Surface*`, which can be accessed directly for its dimensions (defined in `SDL_surface.h`, included automatically via `SDL.h`), while `SDL_Texture *Message` is opaque type `SDL_Texture*` that you can't dereference (something like `typedef SDL_Texture SDL_Texture;` - your side don't know what fields it have or even its size). – keltar Nov 12 '18 at 04:50
  • I don't follow- isn't there only a single definition of SDL_Surface available if I include `SDL2.h`? – ubadub Nov 12 '18 at 05:47
  • It appears you're confusing [SDL_Surface](https://hg.libsdl.org/SDL/file/5a95fbfd3617/include/SDL_surface.h#l69) (which have full structure definition exposed, so fields can be accessed) with [SDL_Texture](https://hg.libsdl.org/SDL/file/5a95fbfd3617/include/SDL_render.h#l127) (which does not). These are different things and serves different purposes, and you already use `SDL_CreateTextureFromSurface` to create new texture from surface. – keltar Nov 12 '18 at 06:22