Jump to content
  • Advertisement
Sign in to follow this  
Alpha Nox

SDL_ttf speed

This topic is 4859 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, When I added the following message system to my game which uses SDL_ttf to display the text, the game become slow. Am i doing something wrong? How can I fix that? Is there another library for SDL which is faster? I tried to load the TTF_font just once instead of load it every time, but it keeps giving me an error in this part: "SDL_Surface* textSurface2 = TTF_RenderText_Shaded(fontSYS, text, foregroundColor,backgroundColor);" Thanks very much, Victor Freire

// SYSTEM MESSAGES SYSTEM

class sys_class {
	int lineY[6];
public:
	
	sys_class();

	char* msgs[6];
	void DisplayMsgs();
	void say(char* msg);
}SYS;



sys_class::sys_class() {
	
	lineY[0] = 465;
	lineY[1] = 485;
	lineY[2] = 505;
	lineY[3] = 525;
	lineY[4] = 545;
	lineY[5] = 565;
	
	msgs[0] = "Welcome to Phoenix Online, created by Alpha NOX";
	msgs[1] = "PO is still being tested. So you will probably find some bugs.";
	msgs[2] = "If you find a bug, please report it in the forum or send an email to: phoenixmmorpg@hotmail.com ";
	msgs[3] = "Have fun and enjoy your stay here.";
	msgs[4] = "PRESS 'F1' if you need help.";
	msgs[5] = "";
}

void sys_class::say(char* msg){
	
	// Reorganize lines

	msgs[0] = msgs[1];
	msgs[1] = msgs[2];
	msgs[2] = msgs[3];
	msgs[3] = msgs[4];
	
	msgs[4] = msg;
	
	
}

void sys_class::DisplayMsgs() 
{
	for(int l = 0;l < 5;l++)
	{
		drawtextSYS(msgs[l],15,lineY[l],255,255,255,0,0,0);
	

	}
	
}







void drawtextSYS(char* text,int x,int y,int fR,int fG, int fB, int bR,int bG,int bB){
	
	TTF_Font* fontSYS = TTF_OpenFont("ARIAL.TTF", 14); // font name,font size
	
	SDL_Color foregroundColor = { fR, fG, fB };
	SDL_Color backgroundColor = { bR, bG, bB };
   	
	SDL_Surface* textSurface2 = TTF_RenderText_Shaded(fontSYS, text, 
      foregroundColor,backgroundColor);

	SDL_SetColorKey(textSurface2, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(textSurface2->format, 0, 0, 0) );
	
	SDL_Surface* textSurface = SDL_DisplayFormat(textSurface2);
	
	int textwidth,textheight;
	
	textwidth = 40;textheight = 40;
		
	SDL_Rect textLocation = { x, y, textwidth, textheight  }; // 0, 0 - draw whole surface

	SDL_BlitSurface(textSurface, NULL, screen, &textLocation);

    SDL_FreeSurface(textSurface);
	SDL_FreeSurface(textSurface2);

    TTF_CloseFont(fontSYS);


}

Share this post


Link to post
Share on other sites
Advertisement
When you try loading it just once, where do you put it? and what's the exact error you get?
If you put it in an init function, or even the ctor (and then close the font in the dtor) you should be able to render text with that font as many times as you want...

[edit] sorry, didn't see that drawtextSYS wasn't part of the sys_class, so forget that part about the ctor & dtor.

But, so long as you open the font somewhere before your main game loop (where you will be calling drawtextSYS), you could pass a reference to the opened font, and then when your game loop is done & you're quitting close the font there...
[/edit]

[edit2] you could also put the drawtextSYS function into the sys_class if that's the only place you're going to be using it from. in that case:


// SYSTEM MESSAGES SYSTEM

class sys_class {
int lineY[6];
TTF_Font* m_fontSYS;
void m_drawText(char* text,int x,int y, SDL_Color fg, SDL_Color bg);
public:
void init();
void cleanUp();
sys_class();

char* msgs[6];
void DisplayMsgs();
void say(char* msg);
}SYS;

void sys_class::init()
{
m_fontSYS = TTF_OpenFont("ARIAL.TTF", 14); // font name,font size
}

void sys_class::cleanUp()
{
TTF_CloseFont(m_fontSYS);
m_fontSYS = NULL;
}

void sys_class::DisplayMsgs()
{
SDL_Color fg = {255, 255, 255};
SDL_Color bg = {0, 0, 0};
for(int i = 0; i < 5; ++i)
m_drawText(msgs,15,lineY, fg, bg);
}

void sys_class::m_drawText(char* text,int x,int y, SDL_Color& fg, SDL_Color& bg)
{
SDL_Surface* textSurface2 = TTF_RenderText_Shaded(m_fontSYS, text, fg, bg);

SDL_SetColorKey(textSurface2, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(textSurface2->format, 0, 0, 0) );

SDL_Surface* textSurface = SDL_DisplayFormat(textSurface2);

int textwidth = 40,textheight = 40;

SDL_Rect textLocation = { x, y, textwidth, textheight }; // 0, 0 - draw whole surface

SDL_BlitSurface(textSurface, NULL, screen, &textLocation);

SDL_FreeSurface(textSurface);
SDL_FreeSurface(textSurface2);
}





new class members:
private ttf_font
private m_drawText (was your drawtextSYS)
public init
public cleanup

in addition to only opening & closing the font once, I have also moved the foreground and bg color's to the displaytext function, so they're only created once per call (before they were being created 5 times per call)... if you always plan on having them be the same color you could make them private members of the class and setting them in the init function that way they're only created/destroyed once your entire program (or for each instance of the class).
[/edit2]

[Edited by - c0uchm0nster on December 2, 2005 8:47:19 PM]

Share this post


Link to post
Share on other sites
If you tried opening the font before calling TTF_Init, I believe it would give you an error. If you load the font into a global variable, this will be a problem. But the slowdowns are almost certainly caused by loading the font each time you want to render, and, unless you delete the font, you are probably creating a huge memory leak.

Edit:

In fact, here is a font manager I made a while ago that I use specifically for use with SDL_TTF. Use it if you want - I don't care.

font manager.h

#ifndef FONT_MANAGER_HPP
#define FONT_MANAGER_HPP

#include <SDL/sdl_ttf.h>
#include <string>
#include <map>

class FontManager
{
public:
FontManager();
~FontManager();

void AddFont(std::string id, std::string filename, int size);
void AddFont(std::string id, TTF_Font * font);
void FreeFont(std::string id);
TTF_Font * GetFont(std::string id);



private:
FontManager(const SparrowFontManager & rhs);
FontManager & operator = (const SparrowFontManager & rhs);

std::map<std::string, TTF_Font *> font_map;
};


#endif



font manager.cpp

#include "font_manager.h"

FontManager::FontManager()
{}

FontManager::~FontManager()
{
for (std::map<std::string, TTF_Font *>::iterator iter = font_map.begin();
iter != font_map.end();
++iter)
{
if (iter->second != NULL)
TTF_CloseFont(iter->second);
}
font_map.clear();
}

void FontManager::AddFont(std::string id, std::string filename, int size)
{
std::map<std::string, TTF_Font *>::iterator iter = font_map.find(id);

//Don't use this Font if the ID is already in use. If it is a free ID,
//load up the Font from a file
if (iter == font_map.end() && size > 0)
{
font_map[id] = TTF_OpenFont(filename.c_str(), size);
}
}

void FontManager::AddFont(std::string id, TTF_Font * font)
{
if (font != NULL && font_map.find(id) == font_map.end())
font_map[id] = font;
}

void FontManager::FreeFont(std::string id)
{
std::map<std::string, TTF_Font *>::iterator iter = font_map.find(id);

if (iter != font_map.end())
{
TTF_CloseFont(iter->second);
iter->second = NULL;
font_map.erase(iter);
}
}

TTF_Font * FontManager::GetFont(std::string id)
{
std::map<std::string, TTF_Font *>::iterator iter = font_map.find(id);

//If we couldn't find a Font with a matching ID, return NULL
if (iter == font_map.end())
return NULL;

return iter->second;
}



To use it:

Include font_manager.h in your project. It is a singleton, and to access its methods you get a pointer to the static FontManager by calling GetInstance(). It stores the fonts in a map, indexed by a string, and you add a font by calling AddFont with the identification string of the font and the file path of the font. It will load and store the font automatically for you. You can also add an already loaded font by substituting the file path with a pointer to the loaded font. You can access a pointer to the TTF_Font by calling GetFont() with the identification string of the font (it returns NULL if it can't find the font). FreeFont will free the memory used by a loaded font.

All loaded fonts will be freed when the destructor of the font manager is called.

Example:


#include "font_manager.h"

void DoStuff()
{
FontManager::GetInstance->AddFont("title text", "media/fonts/font1.ttf");
TTF_Font * font = FontManager::GetInstance->GetFont("title text");
//Do stuff with "font"
FontManager::GetInstance->FreeFont("title text");
}




Hope it helps you.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!