Why are my SDL_ttf fonts so pixelated and ugly? Are there better ways of rendering fonts?
up vote
0
down vote
favorite
Here is an 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)
macos sdl sdl-ttf
add a comment |
up vote
0
down vote
favorite
Here is an 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)
macos sdl sdl-ttf
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 at 17:32
@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 at 22:45
1
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 fromsurfaceMessage
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 at 7:16
@keltar ah! that's exactly what I was looking for! I didn't know you could querySDL_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 at 8:23
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
Here is an 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)
macos sdl sdl-ttf
Here is an 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)
macos sdl sdl-ttf
macos sdl sdl-ttf
asked Nov 10 at 7:03
ubadub
1,960821
1,960821
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 at 17:32
@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 at 22:45
1
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 fromsurfaceMessage
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 at 7:16
@keltar ah! that's exactly what I was looking for! I didn't know you could querySDL_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 at 8:23
add a comment |
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 at 17:32
@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 at 22:45
1
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 fromsurfaceMessage
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 at 7:16
@keltar ah! that's exactly what I was looking for! I didn't know you could querySDL_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 at 8:23
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 at 17: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 at 17:32
@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 at 22:45
@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 at 22:45
1
1
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 at 7:16
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 at 7: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 at 8:23
@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 at 8:23
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
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.
FYIsurfaceMessage->w
doesn't seem to work, you have to useSDL_QueryTexture
. Anyways, thanks a lot!
– ubadub
Nov 11 at 9: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 at 11:16
No, that's not the issue;surfaceMessage->w
makes the compiler throw an error that says "Member access into incomplete typeSDL_Texture
"
– ubadub
Nov 11 at 19:58
I've used the same variable names as was in question, implying types are the same. SoSDL_Surface *surfaceMessage
have typeSDL_Surface*
, which can be accessed directly for its dimensions (defined inSDL_surface.h
, included automatically viaSDL.h
), whileSDL_Texture *Message
is opaque typeSDL_Texture*
that you can't dereference (something liketypedef SDL_Texture SDL_Texture;
- your side don't know what fields it have or even its size).
– keltar
Nov 12 at 4:50
I don't follow- isn't there only a single definition of SDL_Surface available if I includeSDL2.h
?
– ubadub
Nov 12 at 5:47
|
show 1 more comment
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
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.
FYIsurfaceMessage->w
doesn't seem to work, you have to useSDL_QueryTexture
. Anyways, thanks a lot!
– ubadub
Nov 11 at 9: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 at 11:16
No, that's not the issue;surfaceMessage->w
makes the compiler throw an error that says "Member access into incomplete typeSDL_Texture
"
– ubadub
Nov 11 at 19:58
I've used the same variable names as was in question, implying types are the same. SoSDL_Surface *surfaceMessage
have typeSDL_Surface*
, which can be accessed directly for its dimensions (defined inSDL_surface.h
, included automatically viaSDL.h
), whileSDL_Texture *Message
is opaque typeSDL_Texture*
that you can't dereference (something liketypedef SDL_Texture SDL_Texture;
- your side don't know what fields it have or even its size).
– keltar
Nov 12 at 4:50
I don't follow- isn't there only a single definition of SDL_Surface available if I includeSDL2.h
?
– ubadub
Nov 12 at 5:47
|
show 1 more comment
up vote
1
down vote
accepted
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.
FYIsurfaceMessage->w
doesn't seem to work, you have to useSDL_QueryTexture
. Anyways, thanks a lot!
– ubadub
Nov 11 at 9: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 at 11:16
No, that's not the issue;surfaceMessage->w
makes the compiler throw an error that says "Member access into incomplete typeSDL_Texture
"
– ubadub
Nov 11 at 19:58
I've used the same variable names as was in question, implying types are the same. SoSDL_Surface *surfaceMessage
have typeSDL_Surface*
, which can be accessed directly for its dimensions (defined inSDL_surface.h
, included automatically viaSDL.h
), whileSDL_Texture *Message
is opaque typeSDL_Texture*
that you can't dereference (something liketypedef SDL_Texture SDL_Texture;
- your side don't know what fields it have or even its size).
– keltar
Nov 12 at 4:50
I don't follow- isn't there only a single definition of SDL_Surface available if I includeSDL2.h
?
– ubadub
Nov 12 at 5:47
|
show 1 more comment
up vote
1
down vote
accepted
up vote
1
down vote
accepted
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.
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.
answered Nov 11 at 9:06
keltar
12.2k12534
12.2k12534
FYIsurfaceMessage->w
doesn't seem to work, you have to useSDL_QueryTexture
. Anyways, thanks a lot!
– ubadub
Nov 11 at 9: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 at 11:16
No, that's not the issue;surfaceMessage->w
makes the compiler throw an error that says "Member access into incomplete typeSDL_Texture
"
– ubadub
Nov 11 at 19:58
I've used the same variable names as was in question, implying types are the same. SoSDL_Surface *surfaceMessage
have typeSDL_Surface*
, which can be accessed directly for its dimensions (defined inSDL_surface.h
, included automatically viaSDL.h
), whileSDL_Texture *Message
is opaque typeSDL_Texture*
that you can't dereference (something liketypedef SDL_Texture SDL_Texture;
- your side don't know what fields it have or even its size).
– keltar
Nov 12 at 4:50
I don't follow- isn't there only a single definition of SDL_Surface available if I includeSDL2.h
?
– ubadub
Nov 12 at 5:47
|
show 1 more comment
FYIsurfaceMessage->w
doesn't seem to work, you have to useSDL_QueryTexture
. Anyways, thanks a lot!
– ubadub
Nov 11 at 9: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 at 11:16
No, that's not the issue;surfaceMessage->w
makes the compiler throw an error that says "Member access into incomplete typeSDL_Texture
"
– ubadub
Nov 11 at 19:58
I've used the same variable names as was in question, implying types are the same. SoSDL_Surface *surfaceMessage
have typeSDL_Surface*
, which can be accessed directly for its dimensions (defined inSDL_surface.h
, included automatically viaSDL.h
), whileSDL_Texture *Message
is opaque typeSDL_Texture*
that you can't dereference (something liketypedef SDL_Texture SDL_Texture;
- your side don't know what fields it have or even its size).
– keltar
Nov 12 at 4:50
I don't follow- isn't there only a single definition of SDL_Surface available if I includeSDL2.h
?
– ubadub
Nov 12 at 5:47
FYI
surfaceMessage->w
doesn't seem to work, you have to use SDL_QueryTexture
. Anyways, thanks a lot!– ubadub
Nov 11 at 9:26
FYI
surfaceMessage->w
doesn't seem to work, you have to use SDL_QueryTexture
. Anyways, thanks a lot!– ubadub
Nov 11 at 9: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 at 11:16
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 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 at 19:58
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 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 at 4:50
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 at 4:50
I don't follow- isn't there only a single definition of SDL_Surface available if I include
SDL2.h
?– ubadub
Nov 12 at 5:47
I don't follow- isn't there only a single definition of SDL_Surface available if I include
SDL2.h
?– ubadub
Nov 12 at 5:47
|
show 1 more comment
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53236762%2fwhy-are-my-sdl-ttf-fonts-so-pixelated-and-ugly-are-there-better-ways-of-renderi%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
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 at 17:32
@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 at 22:45
1
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 at 7: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 at 8:23