Sign in to follow this  

SDL, Opengl and SDL_ttf

This topic is 4746 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

I'm having problems getting SDL_ttf to work properly in opengl. Basically what I'm doing is rendering each character to a texture and then drawing gl_quads with that texture, but it doesn't seem to load or draw the texture. I've been looking at this code for a while but I can't figure out. Here is the relevant section.
class Text
{
 public:
  Text();
  ~Text();
  bool load_font(const char* filename);
  void write(GLfloat x, GLfloat y, char c);
 private:
  TTF_Font* font;
  GLuint textures[256];
};



bool Text::load_font(const char* filename)
{
  font = TTF_OpenFont(filename, 32);
  if(font == NULL)
  {
    printf("Could not load font %s.\n", filename);
    return false;
  }


  SDL_Color colour;
  colour.r = 255;
  colour.g = 255;
  colour.b = 255;

  glGenTextures(256, textures);
  SDL_Surface* glyph;
  SDL_Surface* temp = SDL_CreateRGBSurface(SDL_SRCALPHA | SDL_HWSURFACE, 128, 128, 32, screen->format->Rmask, screen->format->Gmask,
                                           screen->format->Bmask, screen->format->Amask);
  SDL_Rect erase;
  erase.h = 128;
  erase.w = 128;
  string letter;

  for(char c = ' '; c <= '~'; c++)
  {
    letter = c;
    glyph = TTF_RenderText_Blended(font, letter.c_str(), colour);
    SDL_BlitSurface(glyph, NULL, temp, NULL);
    glBindTexture(GL_TEXTURE_2D, textures[c]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, temp->w, temp->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, temp->pixels);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    SDL_FreeSurface(glyph);
    SDL_FillRect(temp, &erase, 0x00000000);
  }


}

void Text::write(GLfloat x, GLfloat y, char c)
{
  glBindTexture(GL_TEXTURE_2D, textures[c]);
  glBegin(GL_QUADS);
    glTexCoord2f(0, 0);
    glVertex2f(x, y);
    glTexCoord2f(1, 0);
    glVertex2f(x + 64, y);
    glTexCoord2f(1, 1);
    glVertex2f(x + 64, y + 64);
    glTexCoord2f(0, 1);
    glVertex2f(x, y + 64);
  glEnd();


}

Share this post


Link to post
Share on other sites
I saw a thread about this a few weeks ago. It was actually a refrence thread, meaning that someone wanted to post the code that would act as a stand-alone app using SDL, OpenGL, and SDL_ttf.

Here's the code C-Junkie posted, let me know if this works for you.

/* adjust these accordingly */
char fontpath[] = "data/font/font.ttf";
/*****************************************************************/
int round(double x)
{
return (int)(x + 0.5);
}
/*****************************************************************/
int nextpoweroftwo(int x)
{
double logbase2 = log(x) / log(2);
return round(pow(2,ceil(logbase2)));
}
/*****************************************************************/
char *init_sdl(SDL_Surface** screen)
{
if(SDL_Init(SDL_INIT_VIDEO))
return SDL_GetError();
atexit(SDL_Quit);

*screen = SDL_SetVideoMode(screenwidth, screenheight, 0, SDL_OPENGL);

SDL_WM_SetCaption("C-Junkie's SDLGL text example", 0);

if(TTF_Init()==-1)
return TTF_GetError();
atexit(TTF_Quit);

return 0;
}
/*****************************************************************/
void OGL_RenderText(char *text,
TTF_Font *font,
SDL_Color color,
SDL_Rect *location)
{
SDL_Surface *initial;
SDL_Surface *intermediary;
SDL_Rect rect;
int w,h;
int texture;

// Use SDL_TTF to render our text
initial = TTF_RenderText_Blended(font, text, color);

// Convert the rendered text to a known format
w = nextpoweroftwo(initial->w);
h = nextpoweroftwo(initial->h);

intermediary = SDL_CreateRGBSurface(0, w, h, 32,
0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);

SDL_BlitSurface(initial, 0, intermediary, 0);

// Tell GL about our new texture
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
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, texture);
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);
glTexCoord2f(1.0f, 1.0f); glVertex2f(location->x + w, location->y);
glTexCoord2f(1.0f, 0.0f); glVertex2f(location->x + w, location->y + h);
glTexCoord2f(0.0f, 0.0f); glVertex2f(location->x , location->y + h);
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, &texture);
}
/*****************************************************************/
void glEnable2D()
{
int vPort[4];

glGetIntegerv(GL_VIEWPORT, vPort);

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

glOrtho(0, vPort[2], 0, vPort[3], -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
}
/*****************************************************************/
void glDisable2D()
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
/*****************************************************************/
void init_gl()
{
// Irrelevant stuff for this demo
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

// Required if you want alpha-blended textures (for our fonts)
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_BLEND);

// Required setup stuff
glViewport(0, 0, 800, 600);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, screenwidth / (float)screenheight, 0.1f, 50.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
/*****************************************************************/
int main()
{
SDL_Surface *screen;
TTF_Font* font;
char *err;
SDL_Color color;
SDL_Rect position;
SDL_Event event;
int done;

// Do boring initialization
if((err = init_sdl(&screen))) {
printf("Error while initializing: %s", err);
return 1;
}

if(!(font = TTF_OpenFont(fontpath, 20))) {
printf("Error loading font: %s", TTF_GetError());
return 1;
}

init_gl();

done = 0;
while(!done)
{
// render a fun litte quad
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -5.0f);
glDisable(GL_TEXTURE_2D);

glBegin(GL_QUADS);
glNormal3f(0.0f, 0.0f, 1.0f);
glColor3f(0.5f, 0.0f, 0.0f); glVertex3f(-1.5f, -1.0f, 1.0f);
glColor3f(0.0f, 0.5f, 0.0f); glVertex3f( 1.0f, -2.0f, 1.0f);
glColor3f(0.0f, 0.0f, 0.5f); glVertex3f( 1.5f, 1.0f, 1.0f);
glColor3f(0.5f, 0.0f, 0.0f); glVertex3f(-2.0f, 1.0f, -1.0f);
glEnd();

// Go in HUD-drawing mode
glEnable2D();
glDisable(GL_DEPTH_TEST);

// Draw some text
color.r = 255;
color.g = 255;
color.b = 255;
/** A quick note about position.
* Enable2D puts the origin in the lower-left corner of the
* screen, which is different from the normal coordinate
* space of most 2D api's. position, therefore,
* gives the X,Y coordinates of the lower-left corner of the
* rectangle **/

position.x = screenwidth / 3;
position.y = screenheight / 2;
SDL_GL_RenderText("Hello, World!", font, color, &position);
position.y -= position.h;
SDL_GL_RenderText("A line right underneath", font, color, &position);
position.y -= position.h;
SDL_GL_RenderText("Yay text rendering.", font, color, &position);

// Come out of HUD mode
glEnable(GL_DEPTH_TEST);
glDisable2D();

// Show the screen
SDL_GL_SwapBuffers( );

// Wait until you click the X

SDL_WaitEvent(&event);
switch(event.type) {
case SDL_QUIT:
done = 1;
break;
}
}

// Clean up (the atexit's take care of the rest)
TTF_CloseFont(font);

return 0;
}

Share this post


Link to post
Share on other sites

This topic is 4746 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this