Another SDL_ttf question

Now that I have SDL_ttf working, I’d like to use it to display fonts in an
SDL/Open GL program. I don’t understand the relationship between OpenGL and SDL,
so I’m not quite sure what should work. I’ve tried modifying the showfont
program to open an Open GL window, but it fails with a seg fault.

I’ve also tried copying the essential parts of showfont into my GL program, and
while it runs perfectly, I don’t get any text.

So … can someone tell me what I should do to display text in an Open GL SDL
window?

thanks in advance,

Loren–
Loren Frank

Postdoctoral Fellow
Neuroscience Statistics Research Laboratory
Harvard / M.I.T. Division of Health Sciences and Technology and
Department of Anesthesia and Critical Care, Massachusetts General Hospital

Loren Frank wrote:

Now that I have SDL_ttf working, I’d like to use it to display fonts in an
SDL/Open GL program. I don’t understand the relationship between OpenGL and SDL,
so I’m not quite sure what should work. I’ve tried modifying the showfont
program to open an Open GL window, but it fails with a seg fault.

I’ve also tried copying the essential parts of showfont into my GL program, and
while it runs perfectly, I don’t get any text.

So … can someone tell me what I should do to display text in an Open GL SDL
window?

Add SDL_OPENGLBLIT to the flags in SDL_SetVideoMode. This will allow
you to perform normal draw operations, converting the output surface
into an OpenGL texture and drawing it when you update the screen. But
this is slow and wasteful if you just want to draw fonts. Something
like TexFont would be better for OpenGL.

See:
http://reality.sgi.com/opengl/tips/TexFont/TexFont.html

-- David Snopek

/-- libksd –
| The C++ Cross-Platform Game Framework
| Only want to write it once??
| http://libksd.sourceforge.net
------------

I think I can answer this problem :slight_smile: , I’ve done the same thing.

First of all, there is a very important thing I had to do (with SDL_TTF2
(freetype2)) before blitting. I had to set the src_alpha off, otherwise I
would
get nothing.

text = TTF_RenderText_Blended(font, string, white );

SDL_SetAlpha(text,0,0);

text is a 32bpp SDL surface or if you aren’t using the blended version, it’s
a 8bit colorkeyed surface in which you would use:
text = TTF_RenderText_Shaded(font, string, white, black );
SDL_SetColorKey(text,SDL_SRCCOLORKEY,0x00000000);

or

text = TTF_RenderText_Solid(font, string, white );
SDL_SetColorKey(text,SDL_SRCCOLORKEY,0x00000000);

Now I have a very complex SDL Surface to OpenGL setup which breaks up
oversized images into whatever the video cards maximum texturesize is.
OpenGL requires textures to be in powers of 2
(2,4,8,16,32,64,128,256,512,1024,2048, Voodoo 1,2,3 cards max out at 256,
most others max out at 1024)

So the simple way is to simply blit the surface to a 32bpp surface that is a
correct texture size. (The problem here is that if you want to align text
against the original size, you have to save the original width/height.)

So create the texture:

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, text->w, text->h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, text->pixels);

Then draw a quad with the this texture.

glBegin(GL_QUADS);
glTexCoord2i(0, 0);
glVertex2i(x,y);
glTexCoord2i(0, 1);
glVertex2i(x,y+h));
glTexCoord2i(1, 1);
glVertex2i(x+w,y+h);
glTexCoord2i(1, 0);
glVertex2i(x, y);
glEnd();

(This drawing order may be incorrect, My GL viewport is setup so 0,0 is the
UpperLeft corner of the screen, with the viewport being the size of the
screen.)

BTW, this is essentially what OpenGLBlit does anyways.> ----- Original Message -----

From: owner-sdl@lokigames.com [mailto:owner-sdl at lokigames.com]On Behalf
Of Loren Frank
Sent: May 28, 2001 7:49 AM
To: sdl at lokigames.com
Subject: [SDL] another SDL_ttf question

Now that I have SDL_ttf working, I’d like to use it to display fonts in an
SDL/Open GL program. I don’t understand the relationship between OpenGL and
SDL,
so I’m not quite sure what should work. I’ve tried modifying the showfont
program to open an Open GL window, but it fails with a seg fault.

I’ve also tried copying the essential parts of showfont into my GL program,
and
while it runs perfectly, I don’t get any text.

So … can someone tell me what I should do to display text in an Open GL
SDL
window?

thanks in advance,

Loren

Loren Frank

Postdoctoral Fellow
Neuroscience Statistics Research Laboratory
Harvard / M.I.T. Division of Health Sciences and Technology and
Department of Anesthesia and Critical Care, Massachusetts General Hospital


Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com

I think I can answer this problem :slight_smile: , I’ve done the same thing.

First of all, there is a very important thing I had to do (with SDL_TTF2
(freetype2)) before blitting. I had to set the src_alpha off, otherwise I
would
get nothing.

text = TTF_RenderText_Blended(font, string, white );

SDL_SetAlpha(text,0,0);

text is a 32bpp SDL surface or if you aren’t using the blended version, it’s
a 8bit colorkeyed surface in which you would use:
text = TTF_RenderText_Shaded(font, string, white, black );
SDL_SetColorKey(text,SDL_SRCCOLORKEY,0x00000000);

or

text = TTF_RenderText_Solid(font, string, white );
SDL_SetColorKey(text,SDL_SRCCOLORKEY,0x00000000);

snip…

First off, thanks for the reply. Unfortunately, I must still be doing something
wrong, as, when I follow your prescription, I get only a blank rectangle where
the text is supposed to be. If you have any idea what I might be doing wrong,
please let me know. In the meantime, I’ll investiate the texfont suggestion
someone else made…

Thanks,

Loren

Here’s the section of the code:

TTF_Font 		*font;

enum {
            RENDER_LATIN1,
            RENDER_UTF8,
            RENDER_UNICODE
 } rendertype;
 int rendersolid;
 int renderstyle;
 SDL_Color white = { 0xFF, 0xFF, 0xFF, 0 };
 SDL_Color black = { 0, 0, 0, 0 };
 SDL_Surface *text, *temp;
 SDL_Rect dstrect; 
 GLuint texture;

 /* set up the font info (this should eventually go to another function */
 rendersolid = 0;
 renderstyle = TTF_STYLE_NORMAL;
 rendertype = RENDER_LATIN1; 

/* Initialize the TTF library  */
if ( TTF_Init() < 0 ) {
    fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError());
    exit(2);
}


font = TTF_OpenFont("TIMES.TTF", 20);

TTF_SetFontStyle(font, renderstyle);


//sprintf(tmpstring, "Spike version %s by Loren Frank\n", VERSION);
//sprintf(tmpstring, "Spike version by Loren Frank\n");
sprintf(tmpstring, "A");



text = TTF_RenderText_Solid(font, tmpstring, white);
SDL_SetAlpha(text, 0, 0);
SDL_SetColorKey(text,SDL_SRCCOLORKEY,0x00000000);
if ( text != NULL ) {
    text = TTF_RenderText_Solid(font, tmpstring, white);
    SDL_SetAlpha(text, 0, 0);
    SDL_SetColorKey(text,SDL_SRCCOLORKEY,0x00000000);
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, text->w, text->h, 0,

GL_RGB,
GL_UNSIGNED_BYTE, text->pixels);

    glBegin(GL_QUADS);
    glTexCoord2i(0, 0);
    glVertex2i(i,i+4);
    glTexCoord2i(0, 1);
    glVertex2i(i,i);
    glTexCoord2i(1, 1);
    glVertex2i(i+50,i);
    glTexCoord2i(1, 0);
    glVertex2i(i+50, i+4);
    glEnd(); 

}
    glFlush();
}On Mon, 28 May 2001, Kisai wrote:

Well, like I said in the prior message, OpenGL requires textures that are
mulitples of 2 (2,4,8,16,32,64,128,256,512,1024,2048) in both dimensions,
The text rendered by SDL_TTF/SDL_TTF2 will rarely ever fit both of those
dimensions exactly. So what I do is blit it to a surface that IS the correct
size first.

What I do is:
Create a surface
generate text on this surface
create a new surface that’s a proper gl size (say, 32x64)
blit the prior surface to this surface
use the new surface to create the texture.

Let’s see if I can summarize this down to what I exactly used:
/* Surface Name is the text image */

int n_w;
int n_h;
double l2_w = log10(surfacename->w) / log10(2);
double l2_h = log10(surfacename->h) / log10(2);

n_w = surfacename->w;
n_h = surfacename->h;

if (l2_w != floor(l2_w)) {n_w = 1 << (int)ceil(l2_w);}
if (l2_h != floor(l2_h)) {n_h = 1 << (int)ceil(l2_h);}

/* iwidth/iheight save the original size */
iwidth=surfacename->w;
iheight=surfacename->h;

SDL_Surface* newimage;
newimage =
SDL_AllocSurface(SDL_SWSURFACE,n_w,n_h,32,Rmask,Gmask,Bmask,Amask);

SDL_SetAlpha(surfacename,0,0);

SDL_BlitSurface(surfacename, NULL , newimage, NULL);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, newimage->w, newimage->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, newimage->pixels);

SDL_FreeSurface(newimage);

If you want to see the big gory mess that this is from, see:
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/renai/src/video/ra_videolayer
.cpp
version 1.2, after version 1.2 I added the texture splitting (for Voodoo
cards) and
it gets more complicated.

Basically what my source code did at that stage was look to see if the image
fits the gl dimensions, if it doesn’t, blit it to a new surface that does
fit. If it already fits, make the texture from the image itself._________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com