Using SDL_image and SDL_ttf with OpenGL

Hope this helps somebody out there. It's pretty straightforward but if you have any questions leave a comment.

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>

#define MAX_TEXTURES 256

GLuint textures[MAX_TEXTURES];

/**
  * Round to the next power of 2.
  */
GLsizei pow2(GLuint v) {
  v--;
  v |= v >> 1;
  v |= v >> 2;
  v |= v >> 4;
  v |= v >> 8;
  v |= v >> 16;
  v++;
  return v;
}

bool SDL_Image_to_glTexture(const char fn[], const GLuint tid) {
  SDL_Surface *surface;

  if ((surface = IMG_Load(fn)) != NULL) {
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glGenTextures(1, &textures[tid]);
    glBindTexture(GL_TEXTURE_2D, textures[tid]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR);

    SDL_PixelFormat *format = surface->format;

    int width, height;
    width = pow2(surface->w);
    height = pow2(surface->h);

    SDL_LockSurface(surface);

    /* Check for alpha channel */
    if (format->Amask)
      glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
    else
      glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, surface->pixels);

    SDL_UnlockSurface(surface);
  }
  else {
    fprintf(stderr, "%s(): SDL_image could not load %s: %s\n", __FUNCTION__, fn, SDL_GetError());
    return false;
  }

  if (surface != NULL)
    SDL_FreeSurface(surface);
  else {
    fprintf(stderr, "%s(%s): SDL_Surface not freed! ... %s\n", __FUNCTION__, fn, SDL_GetError());
    return false;
  }

  return true;
}

bool SDL_ttf_to_glTexture(const TTF_Font *font, const char text[], const SDL_Color color) {
  SDL_Surface *surface;

  if ((surface = TTF_RenderUTF8_Blended(font, text, color)) != NULL) {
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glGenTextures(1, &textures[i]);
    glBindTexture(GL_TEXTURE_2D, textures[i]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    int width, height;
    width = pow2(surface->w);
    height = pow2(surface->h);

    SDL_LockSurface(surface);
    /* TTF surfaces always have an alpha channel */
    glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
    SDL_UnlockSurface(surface);
  }
  else {
    fprintf(stderr, "%s(): SDL_ttf could render '%s'! ... %s\n", __FUNCTION__, input, TTF_GetError());
    return false;
  }

  if (surface != NULL)
    SDL_FreeSurface(surface);
  else {
    fprintf(stderr, "%s(%s): SDL_Surface not freed! ... %s\n", __FUNCTION__, fn, SDL_GetError());
    return false;
  }

  return false;
}

Comments

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Syntax highlight code surrounded by the {syntaxhighlighter OPTIONS}...{/syntaxhighlighter} tags.
  • HTML tags will be transformed to conform to HTML standards.

More information about formatting options

By submitting this form, you accept the Mollom privacy policy.