http://GameProgrammer.Com

Programming

GP Mailing List
     Thread Index
     Date Index

ATXGPSIG List
     Thread Index
     Date Index

Google
>

Home

Wise2Food



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gameprogrammer] Re: SDL_ttf and OpenGL



On Thu, 2004-04-29 at 07:22, Kevin Fields wrote:
> Hey people,
> 
> I'm having an issue with trying to get SDL_ttf to work with OpenGL.
> I've posted on the SDL mailing list, but I'm still not sure how I can go 
> about getting SDL_ttf to render to the screen.
> 
> One method I was told to use was to take the surface generated by 
> TTF_RenderText_*() and make a texture out of it, then applying that texture 
> to a quad (or triangle strip) and rendering to the screen. When I tried 
> that, nothing appeared.
> 
> Has anyone been able to get fonts working with SDL and OpenGL?

I've been so involved in this list (my list) for the last few days that
I have not been looking at the SDL list and missed you question. I have
indeed gotten SDL_ttf to work with OpenGL. It isn't difficult. Here is
some code that I use for the job:

//-------------------------------------------------

class Font
{
private:
  static const int minGlyph = ' ';
  static const int maxGlyph = 126;

  static int initCounter;

  typedef struct
  {
    int minx, maxx;
    int miny, maxy;
    int advance;
    SDL_Surface *pic;
    GLuint tex;
    GLfloat texMinX, texMinY;
    GLfloat texMaxX, texMaxY;
  } glyph;

  int height;
  int ascent;
  int descent;
  int lineSkip;
  glyph glyphs[maxGlyph + 1];

  unsigned char *address;
  int length;
  int pointSize;
  int style;
  float fgRed, fgGreen, fgBlue;
  float bgRed, bgGreen, bgBlue;

  TTF_Font *ttfFont;

  SDL_Color foreground;
  SDL_Color background;

  void loadChar(char c)
  {
    GLfloat texcoord[4];
    char letter[2] = {0, 0};

    if ((minGlyph <= c) && 
        (c <= maxGlyph) &&
        (NULL == glyphs[c].pic))
    {
      SDL_Surface *g0 = NULL;
      SDL_Surface *g1 = NULL;

      letter[0] = c;

      TTF_GlyphMetrics(ttfFont, 
                       (Uint16)c, 
                       &glyphs[c].minx, 
                       &glyphs[c].maxx, 
                       &glyphs[c].miny, 
                       &glyphs[c].maxy, 
                       &glyphs[c].advance);

      g0 = TTF_RenderText_Shaded(ttfFont, 
                                 letter, 
                                 foreground, 
                                 background);

      if (NULL != g0)
      {
        g1 = SDL_DisplayFormat(g0);
        SDL_FreeSurface(g0);
      }

      if (NULL != g1)
      {
        glyphs[c].pic = g1;
        glyphs[c].tex = loadTextureColorKey(g1, texcoord, 0, 0, 0);
        glyphs[c].texMinX = texcoord[0];
        glyphs[c].texMinY = texcoord[1];
        glyphs[c].texMaxX = texcoord[2];
        glyphs[c].texMaxY = texcoord[3];
      }
    }
  }

public:

  Font(unsigned char *address,
       int length,
       int pointSize, 
       int style,
       float fgRed, float fgGreen, float fgBlue,
       float bgRed, float bgGreen, float bgBlue):
    address(address), length(length),
    pointSize(pointSize),
    style(style),
    fgRed(fgRed), fgGreen(fgGreen), fgBlue(fgBlue),
    bgRed(bgRed), bgGreen(bgGreen), bgBlue(bgBlue),
    ttfFont(NULL)
  {
    if (0 == initCounter)
    {
      if (TTF_Init() < 0)
      {
        errorExit("Can't init SDL_ttf");
      }
    }
    initCounter++;
    initFont();
  }

  ~Font()
  {
    initCounter--;
    if (0 == initCounter)
    {
      TTF_Quit();
    }
  }

  void initFont()
  {
    SDL_RWops *src = NULL;
    int i;

    src = SDL_RWFromMem(address, length);

    ttfFont = TTF_OpenFontRW(src, 1, pointSize);
    if (NULL == ttfFont)
    {
      errorExit("Can't open font file");
    }

    TTF_SetFontStyle(ttfFont, style);

    foreground.r = (Uint8)(255 * fgRed);
    foreground.g  = (Uint8)(255 * fgGreen);
    foreground.b = (Uint8)(255 * fgBlue);

    background.r = (Uint8)(255 * bgRed);
    background.g = (Uint8)(255 * bgGreen);
    background.b = (Uint8)(255 * bgBlue);

    height = TTF_FontHeight(ttfFont);
    ascent = TTF_FontAscent(ttfFont);
    descent = TTF_FontDescent(ttfFont);
    lineSkip = TTF_FontLineSkip(ttfFont);

    for (i = minGlyph; i <= maxGlyph; i++)
    {
      glyphs[i].pic = NULL;
      glyphs[i].tex = 0;
    }
  }

  int getLineSkip()
  {
    return lineSkip;
  }

  int getHeight()
  {
    return height;
  }

  void textSize(char *text, 
                SDL_Rect *r)
  {
    int maxx = 0;
    int advance = 0;

    r->x = 0;
    r->y = 0;
    r->w = 0;
    r->h = height;

    while (0 != *text)
    {
      if ((minGlyph <= *text) && (*text <= maxGlyph))
      {
        loadChar(*text);

        maxx = glyphs[*text].maxx;
        advance = glyphs[*text].advance;
        r->w += advance;
      }

      text++;
    }

    r->w = r->w - advance + maxx;
  }

  void drawText(char *text, int x, int y)
  {
    GLfloat left, right;
    GLfloat top, bottom;
    GLfloat texMinX, texMinY;
    GLfloat texMaxX, texMaxY;

    glPushAttrib(GL_ALL_ATTRIB_BITS);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glEnable(GL_TEXTURE_2D);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

    while (0 != *text)
    {
      if ((minGlyph <= *text) && (*text <= maxGlyph))
      {
        loadChar(*text);

        texMinX = glyphs[*text].texMinX;
        texMinY = glyphs[*text].texMinY;
        texMaxX = glyphs[*text].texMaxX;
        texMaxY = glyphs[*text].texMaxY;

        left   = x;
        right  = x + glyphs[*text].pic->w;
        top    = y;
        bottom = y + glyphs[*text].pic->h;

        glBindTexture(GL_TEXTURE_2D, glyphs[*text].tex);

        glBegin(GL_TRIANGLE_STRIP);

        glTexCoord2f(texMinX, texMinY); glVertex2f( left,    top);
        glTexCoord2f(texMaxX, texMinY); glVertex2f(right,    top);
        glTexCoord2f(texMinX, texMaxY); glVertex2f( left, bottom);
        glTexCoord2f(texMaxX, texMaxY); glVertex2f(right, bottom);

        glEnd();

        x += glyphs[*text].advance;
      }

      text++;
    }

    glPopAttrib();
  }
};

//-------------------------------------------------

int Font::initCounter = 0;

		Bob Pendleton

> 
> _________________________________________________________________
> MSN Premium: Up to 11 personalized e-mail addresses and 2 months FREE*   
> http://join.msn.com/?pgmarket=en-ca&page=byoa/prem&xAPID=1994&DI=1034&SU=http://hotmail.com/enca&HL=Market_MSNIS_Taglines
> 
-- 
+--------------------------------------+
+ Bob Pendleton: writer and programmer +
+ email: Bob@Pendleton.com             +
+ blog:  www.Stonewolf.net             +
+ web:   www.GameProgrammer.com        +
+--------------------------------------+