SDL_ttf question

Hello all,

I’m trying to add font support to my project.
I’ve downloaded SDL_ttf and everything works fine.
However, I’ve had a look at the glfont.c sample,
and it only shows how to do the blended mode
(which is the slowest/nicest one).

So I need to clarify something…In the SDL_GL_Enter2DMode
for this example, glEnable(GL_BLEND) and the glBlendFunc(…)
only need to be called for the blended more, right?

I.e. if I’m rendering in Solid or Shaded modes, I don’t
actually need to enable blending in openGL.
Is this correct?

cheers,
k.

I’m trying to add font support to my project.
I’ve downloaded SDL_ttf and everything works fine.
However, I’ve had a look at the glfont.c sample,
and it only shows how to do the blended mode
(which is the slowest/nicest one).

Are you using OpenGL or just plain SDL?

So I need to clarify something…In the SDL_GL_Enter2DMode
for this example, glEnable(GL_BLEND) and the glBlendFunc(…)
only need to be called for the blended more, right?

Don’t know, in my game engine GL_BLEND is all time enabled and they are rendered ok… probably if you disable GL_BLEND, your texts will also have background drawn (in shaded mode, solid should give the same results).

I.e. if I’m rendering in Solid or Shaded modes, I don’t
actually need to enable blending in openGL.
Is this correct?

See above… probably not, but output will vary.

Also, you could take a look at this little snippet I’ve found on my hard drive, it’s not in OGL (plain SDL) but if you want I can send you my SDL_TTF/OGL (very efficient*) font engine:

include <stdio.h>
#include <stdlib.h>
#include
#include
#include <time.h>

#include <SDL.h>
#include <SDL_TTF.h>

int main( int argc, char* argv[] ) {

if( SDL_Init(SDL_INIT_VIDEO)==(-1) ) {
printf(“Could not initialize SDL: %s.\n”, SDL_GetError());
exit(-1);
}

SDL_Surface *screen;
int WINWIDTH = 800, WINHEIGHT = 600, BPP = 32;
screen = SDL_SetVideoMode( WINWIDTH,WINHEIGHT, BPP, SDL_SWSURFACE | SDL_FULLSCREEN );
if( screen == NULL ) {
fprintf(stderr, “Couldn’t set %ix%ix%i video mode: %s\n”, WINWIDTH,WINHEIGHT,BPP, SDL_GetError());
exit(1);
}

TTF_Init();

TTF_Font *fntCourier = TTF_OpenFont( “cour.ttf”, 25 );
SDL_Color clrFg = {220,50,50,0}; // Blue (“Fg” is foreground)
SDL_Color clrBg = {0,0,0,0};
SDL_Rect rcDest = {20,20,0,0};

SDL_Surface * sText = TTF_RenderText_Solid( fntCourier, “Courier 12”, clrFg);
SDL_BlitSurface( sText,NULL, screen,&rcDest );

rcDest.y = 60;

sText = TTF_RenderText_Shaded( fntCourier, “Courier 12!@#$%^&*()_+[]”, clrFg, clrBg );
SDL_BlitSurface( sText,NULL, screen,&rcDest );

rcDest.y = 100;

sText = TTF_RenderText_Blended( fntCourier, “So we met there, and started to bangle \n each other and drink green tea (YEEEAH!).”, clrFg);
SDL_BlitSurface( sText,NULL, screen,&rcDest );

fprintf(stderr, " Width: %i Height: %i", sText->w, sText->h);

SDL_Flip(screen);

SDL_Event event ;

for ( ; ; )
{
if ( SDL_PollEvent ( &event ) )
{
if ( event.type == SDL_KEYDOWN ) break ;
}
}

SDL_FreeSurface( sText );

TTF_CloseFont( fntCourier );

TTF_Quit();
SDL_Quit();
return 0;
}

Koshmaar

    • it uses Bob Pendelton’s solution for prerendering individual glyphs, therefore -> no need for dynamic memory allocation and sending textures to video card every frame

I’m using both SDL and OpenGL.
Basicaly, I’m doing all the init stuff and handling input, events, timers,
etc. via
SDL, and I’m using openGL for rendering…

I’ve based my font code to the glfont.c example that comes with
the SDL_ttf sources. Is there a more efficient way than the one described
there?

If so, I’d be interested in a link or reference to it pls.

cheers,
K.> ----- Original Message -----

From: sdl-bounces+kos=climaxgroup.com@libsdl.org
[mailto:sdl-bounces+kos=climaxgroup.com at libsdl.org]On Behalf Of Koshmaar
Sent: 14 January 2005 21:56
To: A list for developers using the SDL library. (includes SDL-announce)
Subject: Re: [SDL] SDL_ttf question

I’m trying to add font support to my project.
I’ve downloaded SDL_ttf and everything works fine.
However, I’ve had a look at the glfont.c sample,
and it only shows how to do the blended mode
(which is the slowest/nicest one).

Are you using OpenGL or just plain SDL?

So I need to clarify something…In the SDL_GL_Enter2DMode
for this example, glEnable(GL_BLEND) and the glBlendFunc(…)
only need to be called for the blended more, right?

Don’t know, in my game engine GL_BLEND is all time enabled and they are
rendered ok… probably if you disable GL_BLEND, your texts will also have
background drawn (in shaded mode, solid should give the same results).

I.e. if I’m rendering in Solid or Shaded modes, I don’t
actually need to enable blending in openGL.
Is this correct?

See above… probably not, but output will vary.

Also, you could take a look at this little snippet I’ve found on my hard
drive, it’s not in OGL (plain SDL) but if you want I can send you my
SDL_TTF/OGL (very efficient*) font engine:

include <stdio.h>
#include <stdlib.h>
#include
#include
#include <time.h>

#include <SDL.h>
#include <SDL_TTF.h>

int main( int argc, char* argv[] ) {

if( SDL_Init(SDL_INIT_VIDEO)==(-1) ) {
printf(“Could not initialize SDL: %s.\n”, SDL_GetError());
exit(-1);
}

SDL_Surface *screen;
int WINWIDTH = 800, WINHEIGHT = 600, BPP = 32;
screen = SDL_SetVideoMode( WINWIDTH,WINHEIGHT, BPP, SDL_SWSURFACE |
SDL_FULLSCREEN );
if( screen == NULL ) {
fprintf(stderr, “Couldn’t set %ix%ix%i video mode: %s\n”,
WINWIDTH,WINHEIGHT,BPP, SDL_GetError());
exit(1);
}

TTF_Init();

TTF_Font *fntCourier = TTF_OpenFont( “cour.ttf”, 25 );
SDL_Color clrFg = {220,50,50,0}; // Blue (“Fg” is foreground)
SDL_Color clrBg = {0,0,0,0};
SDL_Rect rcDest = {20,20,0,0};

SDL_Surface * sText = TTF_RenderText_Solid( fntCourier, “Courier 12”,
clrFg);
SDL_BlitSurface( sText,NULL, screen,&rcDest );

rcDest.y = 60;

sText = TTF_RenderText_Shaded( fntCourier, “Courier 12!@#$%^&*()_+[]”,
clrFg, clrBg );
SDL_BlitSurface( sText,NULL, screen,&rcDest );

rcDest.y = 100;

sText = TTF_RenderText_Blended( fntCourier, “So we met there, and started
to bangle \n each other and drink green tea (YEEEAH!).”, clrFg);
SDL_BlitSurface( sText,NULL, screen,&rcDest );

fprintf(stderr, " Width: %i Height: %i", sText->w, sText->h);

SDL_Flip(screen);

SDL_Event event ;

for ( ; ; )
{
if ( SDL_PollEvent ( &event ) )
{
if ( event.type == SDL_KEYDOWN ) break ;
}
}

SDL_FreeSurface( sText );

TTF_CloseFont( fntCourier );

TTF_Quit();
SDL_Quit();
return 0;
}

Koshmaar

    • it uses Bob Pendelton’s solution for prerendering individual glyphs,
      therefore -> no need for dynamic memory allocation and sending textures to
      video card every frame

SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

More efficient in what way?

If you need lots of text at the same time as other stuff is going on,
you probably need to render into temporary textures.

For a static overlay, just render it all into an RGBA texture of
sufficient size. (Remember that some cards may not support 2048x2048
or even 1024x1024 textures! You may have to do some tiling, or just
hardwire your code for 256x256 tiles if that’s easier.)

For scrolling, handle lines as separate textures and/or quads, or
whatever suits your needs. The smaller the “tiles”, the less texture
memory you need for off-screen “scroll margin” - but of course,
there’s slightly more overhead.

If you need animated glyphs and stuff (assuming you don’t have to
animate all of them), you can just leave the animated glyphs out
when rendering the static overlay textures, and render them "live"
instead.

Of course, if to animate all glyphs in unison, you can just render one
overlay texture for each frame, and “page flip” by switching texture
every N ms or something. Or use color OpenGL modulation and/or
transformations instead; they’re pretty much free once you’re in
there rendering anyway…

I’ve been meaning to evolve the smoothscroll example into something
more flexible and usable; a generic OpenGL sub-pixel smoothscrolling
engine… (You supply a callback that renders the requested area of
your map into an SDL surface, and the “engine” does the rest, pretty
much.) That would be usable for scrolling text and overlaying 2D
graphics on top of 3D or other “native” OpenGL stuff as well, I
guess. However, that doesn’t help much unless I actually get around
to hack it. :-/

//David Olofson - Programmer, Composer, Open Source Advocate

.- Audiality -----------------------------------------------.
| Free/Open Source audio engine for games and multimedia. |
| MIDI, modular synthesis, real time effects, scripting,… |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se —On Monday 17 January 2005 09.52, Kostas Kostiadis wrote:

I’m using both SDL and OpenGL.
Basicaly, I’m doing all the init stuff and handling input, events,
timers, etc. via
SDL, and I’m using openGL for rendering…

I’ve based my font code to the glfont.c example that comes with
the SDL_ttf sources. Is there a more efficient way than the one
described there?

more efficient in terms of cpu/gpu usage…
At the moment what I’m doing everytime I want to render text is:

create an SDL_Surface (via TTF_Render*_*)
create a texture from the surface (using SDL_CreateRGBSurface,
SDL_BlitSurface, etc.)
enter 2D mode (glOrtho, push attribs, etc.)
render the texture
exit 2D mode
Free the SDL_Surface

which is all based on glfont.c in the example code that comes with SDL_ttf.
This seems like a lot of stuff (but it may all be necessary)…

The only thing I can think of to improve performance is batch all my
render text calls and do them once a tick (so that all the enter/exit 2D
mode, etc.
happen only once).

Also, am not sure how expensive SDL_BlitSurface is (from what I saw in the
code
it calls SDL_UpperBlit).

cheers,
K.> ----- Original Message -----

From: sdl-bounces+kos=climaxgroup.com@libsdl.org
[mailto:sdl-bounces+kos=climaxgroup.com at libsdl.org]On Behalf Of David
Olofson
Sent: 17 January 2005 09:52
To: A list for developers using the SDL library. (includes SDL-announce)
Subject: Re: [SDL] SDL_ttf question

On Monday 17 January 2005 09.52, Kostas Kostiadis wrote:

I’m using both SDL and OpenGL.
Basicaly, I’m doing all the init stuff and handling input, events,
timers, etc. via
SDL, and I’m using openGL for rendering…

I’ve based my font code to the glfont.c example that comes with
the SDL_ttf sources. Is there a more efficient way than the one
described there?

More efficient in what way?

If you need lots of text at the same time as other stuff is going on,
you probably need to render into temporary textures.

For a static overlay, just render it all into an RGBA texture of
sufficient size. (Remember that some cards may not support 2048x2048
or even 1024x1024 textures! You may have to do some tiling, or just
hardwire your code for 256x256 tiles if that’s easier.)

For scrolling, handle lines as separate textures and/or quads, or
whatever suits your needs. The smaller the “tiles”, the less texture
memory you need for off-screen “scroll margin” - but of course,
there’s slightly more overhead.

If you need animated glyphs and stuff (assuming you don’t have to
animate all of them), you can just leave the animated glyphs out
when rendering the static overlay textures, and render them "live"
instead.

Of course, if to animate all glyphs in unison, you can just render one
overlay texture for each frame, and “page flip” by switching texture
every N ms or something. Or use color OpenGL modulation and/or
transformations instead; they’re pretty much free once you’re in
there rendering anyway…

I’ve been meaning to evolve the smoothscroll example into something
more flexible and usable; a generic OpenGL sub-pixel smoothscrolling
engine… (You supply a callback that renders the requested area of
your map into an SDL surface, and the “engine” does the rest, pretty
much.) That would be usable for scrolling text and overlaying 2D
graphics on top of 3D or other “native” OpenGL stuff as well, I
guess. However, that doesn’t help much unless I actually get around
to hack it. :-/

//David Olofson - Programmer, Composer, Open Source Advocate

.- Audiality -----------------------------------------------.
| Free/Open Source audio engine for games and multimedia. |
| MIDI, modular synthesis, real time effects, scripting,… |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

more efficient in terms of cpu/gpu usage…
At the moment what I’m doing everytime I want to render text is:

create an SDL_Surface (via TTF_Render*_*)
create a texture from the surface (using SDL_CreateRGBSurface,
SDL_BlitSurface, etc.)
enter 2D mode (glOrtho, push attribs, etc.)
render the texture
exit 2D mode
Free the SDL_Surface

Surface creation/destruction should be outside the loop, so you only
deal with textures and OpenGL, except when the text actually changes.

That is:

render new text:

  • Free old SDL_Surface, if any
  • create an SDL_Surface (via TTF_Render*_*)
  • create a texture from the surface (using
    SDL_CreateRGBSurface,> SDL_BlitSurface, etc.)

every frame:

  • enter 2D mode (glOrtho, push attribs, etc.)
  • render the texture
  • exit 2D mode

cleanup:

  • Free the SDL_Surface

The only thing I can think of to improve performance is batch all
my render text calls and do them once a tick (so that all the
enter/exit 2D mode, etc.
happen only once).

The big hit is from rendering and convertion. The OpenGL stuff isn’t
nearly as expensive, in the normal case, I think.

Also, am not sure how expensive SDL_BlitSurface is (from what I saw
in the code
it calls SDL_UpperBlit).

Depends on your CPU/GPU performance ratio (SDL blitting is 100%
software when using SDL with OpenGL), but my guess is that your
average video card blits many times faster than the CPU it’s paired
with - which would make SDL_BlitSurface() relatively expensive. And
alpha blending (for antialiazing) slows down the CPU a lot, but
doesn’t bother a CPU much at all…

//David Olofson - Programmer, Composer, Open Source Advocate

.- Audiality -----------------------------------------------.
| Free/Open Source audio engine for games and multimedia. |
| MIDI, modular synthesis, real time effects, scripting,… |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se —On Monday 17 January 2005 11.14, Kostas Kostiadis wrote:

Depends on your CPU/GPU performance ratio (SDL blitting is 100%
software when using SDL with OpenGL), but my guess is that your

Ouch!..Is there an alternative?
I’m guessing it’s not just a case of changing the SDL_CreateRGBSurface
call to use SDL_HWSURFACE :wink:

cheers,
k.

Nope, at least not yet. Maybe the glSDL backend will be able to
accelerate surface->surface blits eventually, if the right OpenGL
extensions are in place.

Anyway, do you really have to render new textures all the time? Even
"dynamic" text can’t be all that dynamic, provided anyone’s
actually supposed to be able to read it. :slight_smile:

Scrolling, rotation, fading, zooming, shearing etc can be done with
OpenGL when rendering the pre-rendered textures to screen, so you
should only have to render a new texture every now and then,
normally. If that takes too long (hickups in the frame rate whenever
you render a new texture), you can probably do it piece by piece “in
the background”, or actually in the background by means of a worker
thread.

//David Olofson - Programmer, Composer, Open Source Advocate

.- Audiality -----------------------------------------------.
| Free/Open Source audio engine for games and multimedia. |
| MIDI, modular synthesis, real time effects, scripting,… |
`-----------------------------------> http://audiality.org -’
http://olofson.nethttp://www.reologica.se —On Monday 17 January 2005 12.53, Kostas Kostiadis wrote:

Depends on your CPU/GPU performance ratio (SDL blitting is 100%
software when using SDL with OpenGL), but my guess is that your

Ouch!..Is there an alternative?
I’m guessing it’s not just a case of changing the
SDL_CreateRGBSurface call to use SDL_HWSURFACE :wink: