0

I'm using SDL, I have OpenGL rendering setup, I want to draw some text to the screen.

I found this question: Using SDL_ttf with OpenGL which seems to address the same concern, but I think my GL-fu isn't good enough to understand what to do next.

Ie, I have the texture from that other post, which, if I understand everything correctly, is an integer ID representing a GL texture that contains the rendered text. How do I actually render this texture onto my screen (everything's 2D here so I just want to render it as flat text on the screen, not onto some fancy surface in a 3D scene or anything).

Alternatively, is there any easier way of getting this working? (ie, rendering some text via SDL while also being able to render GL shapes)

edit: Or, even more generally, is there an easier way of being able to render both text and shapes onto the screen via SDL?

Community
  • 1
  • 1
alecbz
  • 6,292
  • 4
  • 30
  • 50

2 Answers2

3
  1. Use SDL_ttf to turn your string into a bitmap; this is just a single function call.

  2. Use the code in the link you posted to turn it into a texture.

  3. Draw a rectangle using said texture. That is, glBindTexture, glBegin, (glTexCoord, glVertex) x4, glEnd. If you have doubts about this step, you better go through some basic OpenGL tutorials (covering texture mapping, of course) first.

DanielKO
  • 4,422
  • 19
  • 29
  • I've been trying for a while and I've yet to get #3 working. I've found a couple of sites that give some code using glTexCoord like you mention (eg, http://www.gaanza.com/blog/display-2d-sprite/), but all that's rendering for me is a white rectangle: https://gist.github.com/alecbenzer/5296913 – alecbz Apr 02 '13 at 22:53
  • Alternatively, is this _definitely_ the only way to do font rendering and shape drawing via SDL? Isn't there some way to use OpenGL for the shapes and have some other SDL surface rendered on top of this that you can just blit a surface to? – alecbz Apr 02 '13 at 22:54
  • SDL once supported a kind of window that supported both OpenGL rendering and surface blitting. It got deprecated because it didn't work well in some platforms/drivers. If you are satisfied with the program working only in your computer (if at all), you can try passing "SDL_OPENGLBLIT" to SDL_SetVideoMode. – DanielKO Apr 03 '13 at 19:48
  • Also, don't forget to glEnable(GL_TEXTURE_2D), otherwise the rectangle won't be textured. And yes, this is the way to display bitmaps when using OpenGL. If it's too low-level for you, you should be using a rendering engine instead, where things like text rendering and sprites are already conveniently provided. – DanielKO Apr 03 '13 at 19:53
  • And for completeness sake, there IS glDrawPixels(), where you could just provide the SDL_Surface pixels and the pixel coordinates through glRasterPos(). It's slow. Don't use it, unless you want to measure how slow it is. – DanielKO Apr 03 '13 at 19:58
0

Try this snippet, it renders a SDL true type font extension library font starting from the bottom left side of the screen.

Note the arrangment of the texcords to the shape on the screen. The pixels from the text texture start 0,0 at the top left of the image. So I need to flip that around to make it show properly on a screen with x,y at the bottom left.

void RenderText(std::string message, SDL_Color color, int x, int y, 
                TTF_Font* font) 
{

  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();

  gluOrtho2D(0, gWindow->getWidth(),0,gWindow->getHeight()); 
  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();

  glDisable(GL_DEPTH_TEST);
  glEnable(GL_TEXTURE_2D);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  GLuint texture;
  glGenTextures(1, &texture);
  glBindTexture(GL_TEXTURE_2D, texture);

  SDL_Surface * sFont = TTF_RenderText_Blended(font, message.c_str(), color);

  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sFont->w, sFont->h, 0, GL_BGRA, 
                GL_UNSIGNED_BYTE, sFont->pixels);

  glBegin(GL_QUADS);
  {
    glTexCoord2f(0,1); glVertex2f(x, y);
    glTexCoord2f(1,1); glVertex2f(x + sFont->w, y);
    glTexCoord2f(1,0); glVertex2f(x + sFont->w, y + sFont->h);
    glTexCoord2f(0,0); glVertex2f(x, y + sFont->h);
  }
  glEnd();

  glDisable(GL_BLEND);
  glDisable(GL_TEXTURE_2D);
  glEnable(GL_DEPTH_TEST);

  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(GL_PROJECTION);
  glPopMatrix();

  glDeleteTextures(1, &texture);
  SDL_FreeSurface(sFont);
}