Advertisement

SDL_ttf Rendering Issues

Started by January 25, 2005 11:23 PM
7 comments, last by Rhaal 19 years, 7 months ago
For some reason, the following is crashing. It worked fine before I changed the rendering mode to blended. I'm clueless.

void DisplayText(string text, int x, int y, int fr, int fg, int fb)
{
  // Set the text color
  SDL_Color foreground = { fr, fg, fb };

  // Render the text to a temporary surface
  SDL_Surface* temp = TTF_RenderText_Blended(ftForgot, text.c_str(), foreground);

  // Blit the temporary surface to the display
  Renderer.Blit(*temp, *sfScreen, x, y);

  // Free the temporary surface
  SDL_FreeSurface(temp);
}




Edit: 'ftForgot' is a font that is within scope. Edit: Render code:

void tehRenderer::Blit(SDL_Surface &source, SDL_Surface &destination, int x, int y)
{
  // Destination area to draw the image.
  SDL_Rect DesRect = { x, y };

  // Blit to the surface. Source is NULL so the entire surface will be drawn.
  SDL_BlitSurface(&source, NULL, &destination, &DesRect);
}
- A momentary maniac with casual delusions.
The first idea is that TTF_RenderText_Blended is returning NULL because it failed, and then you derefrence the NULL pointer. Add in a check to alert you if temp == 0. I think that is what is causing the crash.

On this page is a small excerpt:

Quote:
Also,TTF_RenderText_Blended(   TTF_Font *font, // This is the TTF_Font to use.   char *cstr, // This is the text to render.   SDL_Color &clr, // This is the color to use.);TTF_RenderText_Blended() just makes it look prettier by (more or less) darkening the edges of the text. I'm pretty sure that it uses alpha blending, if you care.And,TTF_RenderText_Shaded(   TTF_Font *font, // This is the TTF_Font to use.   char *cstr, // This is the text to render.   SDL_Color &clrFg, // Foreground color to use.   SDL_Color &clrBg, // Background color to use.);TTF_RenderText_Shaded() is the only one of the three that actually puts a background in for you. The result of this looks the same as blitting TTF_RenderText_Blended() onto a rectangle of color clrBg. 



I would suggest trying to use the shaded function and see if that works. If it fails, then I think the problem would be something with the 'alpha blending' that the author has suggested he thinks that the function uses. I guess it is an incompatible feature.
Advertisement


I still can't work it out. Shaded works fine, but I've switched from it because I don't want a background color on my text. I tried using shaded, then changing the transparency on the temp surface, but that didn't work either. Above is a picture when the debugger reaches the line
SDL_Surface* temp = TTF_RenderText_Blended(ftForgot, text.c_str(), foreground);


It appears that the previous line is not working, but I can't figure it out. The text is showing up red like that, and there are little 'y' characters after each value. Does this mean anything? I'm proficient with my c++, but really really really need to brush up on my debugging!
- A momentary maniac with casual delusions.
That just means the character translation, its fine. That data type as you see is an unsigned char, so it's showing that. However, I'm thinking that if im not mistaken you are drawing it in black (255,255,255). Try using (0,0,0) for that function instead - it may be a logical error with that function. I thought white was (255,255,255) though. Or just try like 255,0,0 or just some other color. and see if that works.

Also, break after the line:

SDL_Surface* temp = TTF_RenderText_Blended(ftForgot, text.c_str(), foreground);


If temp == 0 as it is in that debug screen, then that function is just failing and you cannot use it at all. I would not know how to remedy that problem than other than just using the blended and setting the back color to black, then making black the transparent color on the surface.
I am firmly convinced that this is a flaw in SDL_ttf. Simply changing to shaded mode should not cause this. I am using a 32 bit surface, but the problem is with the NULL returning from the shaded function. I think it's time to start looking into another font library.
- A momentary maniac with casual delusions.
Quote: Original post by Rhaal
I am firmly convinced that this is a flaw in SDL_ttf. Simply changing to shaded mode should not cause this. I am using a 32 bit surface, but the problem is with the NULL returning from the shaded function. I think it's time to start looking into another font library.


I agree! However you should not let one bad apple spoil the bunch [smile]. You can opt not to use that function for I do not think there are that many alternatives for easy system fonts in SDL. SDL_ttf is built upon the freetype library, so it could reside in there as well. You should get on the mailing list and report it as a potential bug. Who knows, it just might be something they missed.
Advertisement
I got it! I put a breakpoint on line 1 of my init function, and found the bug.

In the original code, I was calling TTF_Init() at the end of my Init function. Well, I found a performance issue. My DisplayText() function was loading the font. Since DisplayText() is called 60 times/second, it lagged.

To fix this, I made the font pointer global, move the initialization of it to my Init() function, and had DisplayText just use the font. I forgot to move the TTF_Init() function up in my code! That's all it was!

Old code:
void Init(){  // Initialize SDL components  SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);  // Setup the video mode  sfScreen = SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 0, SDL_ANYFORMAT | SDL_DOUBLEBUF | SDL_HWPALETTE |SDL_HWSURFACE);  // Set the title of the window  SDL_WM_SetCaption(WINDOW_CAPTION, 0);  // Get the number of ticks since SDL was initialized  gTimer = SDL_GetTicks();  // Fill the BMP surface  sfBG = SDL_LoadBMP("data/img/bg/bg1.bmp");  // Fmod stuff  FSOUND_Init(32000, 64, 0);  Player.LoadSong("data/music/cor.mp3", "Champion of RON", "vuxnut");  // Init font  ftForgot = TTF_OpenFont("data/fonts/forgot.ttf", 14);  // At this point the compiler is thinking WTF? Font?  // Initialize the stack with the exit state  StateStruct state;  state.StatePointer = gsExit;  gStateStack.push(state);  // Add a pointer to the menu state  state.StatePointer = gsMenu;  gStateStack.push(state);  // Initialize the TTF library  TTF_Init();  // And at this point the compiler is thinking OMGWTFLOL!	}


Fixed code:
void Init(){  // Initialize SDL components  SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);  // Setup the video mode  sfScreen = SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 0, SDL_ANYFORMAT | SDL_DOUBLEBUF | SDL_HWPALETTE |SDL_HWSURFACE);  // Set the title of the window  SDL_WM_SetCaption(WINDOW_CAPTION, 0);  // Get the number of ticks since SDL was initialized  gTimer = SDL_GetTicks();  // Fill the BMP surface  sfBG = SDL_LoadBMP("data/img/bg/bg1.bmp");  // Fmod stuff  FSOUND_Init(32000, 64, 0);  Player.LoadSong("data/music/cor.mp3", "Champion of RON", "vuxnut");  // Initialize the TTF library  TTF_Init(); // ok  // Init font  ftForgot = TTF_OpenFont("data/fonts/forgot.ttf", 14); // ah! teh font!  // Initialize the stack with the exit state  StateStruct state;  state.StatePointer = gsExit;  gStateStack.push(state);  // Add a pointer to the menu state  state.StatePointer = gsMenu;  gStateStack.push(state);	}


Your skill in debugging has increased to 2.
- A momentary maniac with casual delusions.
Awesome! It's always those calls to X_Init that seem to ruin the day. Glad you got it fixed! However, I wonder why the solid text was working in this same case, but this one was not. Just plain weird.
The solid wasn't. That was a mistake in my OP, because I forgot that I made both the changes at the same time.
- A momentary maniac with casual delusions.

This topic is closed to new replies.

Advertisement