• Advertisement
Sign in to follow this  

SDL, Opengl and SDL_ttf

This topic is 4814 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
Advertisement
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
Sign in to follow this  

  • Advertisement