[1.2.x+OpenGL]-Best Method To Draw Text???
Hi,
I’m learning how to use SDL 1.2.x and OpenGL together.
What is best (fastest) method to draw TTF text on the screen with
SDL+OpenGL?
Did some Googling and found something that uses SDL_ttf with SDL+OpenGL,
but it is ridiculously slow and ! need something that is faster.
Thanks…
HERE IS A URL TO A SCREENSHOT:
http://silentheroproductions.com/images/SDL-l-OGL_Alpha-0003.png
HERE IS THE SOURCE CODE ON PASTEBIN:
http://pastebin.com/m641b7bd3
JeZ-l-Lee
SLNTHERO at aol.com
www.SilentHeroProductions.com
// HERE IS THE SDL_TTF+OPENGL FUNCTION I CURRENTLY USE (SLOW!!!)
// One line of text with an outline takes 20% CPU usage on a 4 core CPU
running @ 1.6GHz???
//
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
void SDL_GL_RenderText(const char *text, TTF_Font *font, SDL_Color
color, SDL_Rect *location)
{
SDL_Surface *initial;
SDL_Surface *initialOutline;
SDL_Surface *intermediary;
SDL_Rect rect;
int w,h;
GLuint textureTwo;
SDL_Color outline;
outline.r = 255;
outline.g = 0;
outline.b = 0;
// Use SDL_TTF to render our text
initial = TTF_RenderText_Solid(font, text, color);
initialOutline = TTF_RenderText_Solid(font, text, outline);
// Convert the rendered text to a known format
w = nextpoweroftwo(5+initial->w);
h = nextpoweroftwo(5+initial->h);
/* SDL interprets each pixel as a 32-bit number, so our masks must
depend
on the endianness (byte order) of the machine */
Uint32 rmask, gmask, bmask, amask;
bool colorIsRGBA = true;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
rmask = 0xff000000;
gmask = 0x00ff0000;
bmask = 0x0000ff00;
amask = 0x000000ff;
colorIsRGBA = false;
#else
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = 0xff000000;
colorIsRGBA = true;
#endif
intermediary = SDL_CreateRGBSurface(0, w, h, 32, rmask, gmask,
bmask, amask);
for (int outlineY = 0; outlineY < 5; outlineY++)
for (int outlineX = 0; outlineX < 5; outlineX++)
{
rect.x = outlineX;
rect.y = outlineY;
SDL_BlitSurface(initialOutline, 0, intermediary, &rect);
}
rect.x = 2;
rect.y = 2;
SDL_BlitSurface(initial, 0, intermediary, &rect);
// Tell GL about our new texture
glGenTextures(1, &textureTwo);
glBindTexture(GL_TEXTURE_2D, textureTwo);
if (colorIsRGBA == true)
glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, intermediary->pixels );
else
glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_BGRA,
GL_UNSIGNED_BYTE, intermediary->pixels );
// GL_NEAREST looks horrible, if scaled...
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// prepare to render our texture
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureTwo);
glColor3f(1.0f, 1.0f, 1.0f);
// Draw a quad at location
glBegin(GL_QUADS);
// Recall that the origin is in the lower-left corner
// That is why the TexCoords specify different corners
// than the Vertex coors seem to.
glTexCoord2f(0.0f, 1.0f);
glVertex2f(location->x , location->y + h);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(location->x + w, location->y + h);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(location->x + w, location->y );
glTexCoord2f(0.0f, 0.0f);
glVertex2f(location->x , location->y );
glEnd();
// Bad things happen if we delete the texture before it finishes
glFinish();
// return the deltas in the unused w,h part of the rect
location->w = initial->w;
location->h = initial->h;
// Clean up
SDL_FreeSurface(initial);
SDL_FreeSurface(intermediary);
glDeleteTextures(1, &textureTwo);
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------