Simple Text in OpenGL (without GLUT)
I am making a simple 2D platformer with C++, SDL and OpenGL and now I would like to display text on the screen, e.g. points, timer, simple messages.
On various site's I've read that Bitmap Fonts would probably be the way to go for this, but could someone please give me a straightforward, easy to understand example of how to use them in OpenGL to output a test-message to the screen?
EDIT: I found something interesting, FTGL. The example-code in the tutorial (2nd link) looks very straightforward. Couldn't get it to work atm but will go back to it later.
FTGL is a free cross-platform Open Source C++ library that uses Freetype2 to simplify rendering fonts in OpenGL applications. FTGL supports bitmaps, pixmaps, texture maps, outlines, polygon mesh, and extruded polygon rendering modes.
- http://sourceforge.net/projects/ftgl/
- http://ftgl.sourceforge.net/docs/html/ftgl-tutoria开发者_如何学Cl.html
- http://nehe.gamedev.net/tutorial/freetype_fonts_in_opengl/24001/
You can use SDL_gfx, it can output text using bitmap fonts like this:
#include <SDL/SDL_gfxPrimitives.h>
#include <SDL/SDL_gfxPrimitives_font.h>
const char *text = "text to render";
stringColor(sdlSurface, x, y, text, 0xff0000ff);
You have to create a bitmap image, containing all the characters you want to use. The easiest way is with a fixed-width font. Then for each letter you bind that part of the texture. I've written such code in Pascal/OpenGL years ago, will search for it and post
Edit here is the code
procedure DisplayString(str: string; l: integer; active: integer; align: integer);
var i,n: integer;
s: string;
begin
glPushMatrix;
glTranslatef(0,-l,0);
if align=1 then glTranslatef(-15,0,0); //left alignment
if align=3 then glTranslatef(15,0,0);//right aligment
s:=uppercase(str); // the font is uppercase only
for i:=1 to length(str)-4 do begin
n:=ord(s[i]); // get the ASCII code of letter
glTranslatef(1,0,0);
if n=32 then continue; //space
if (n>=48) and (n<=58) then n:=n-47; // translate ascii code to the
if (n>=65) and (n<=90) then n:=n-53; // corresponding position in the bitmap
if active=0 then glBindTexture(GL_TEXTURE_2D, font2) // two different font files used
else glBindTexture(GL_TEXTURE_2D, font);
glBegin(GL_QUADS); // 1850 is the total width of the bitmap image, 50 is one character
glTexCoord2f(((n-1)*50/1850)-1, 0.0); glVertex3f(0.0, 0.0, 1.0);
glTexCoord2f((n*50/1850)-1, 0.0); glVertex3f(1.0, 0.0, 1.0);
glTexCoord2f((n*50/1850)-1, 1.0); glVertex3f(1.0, 1.0, 1.0);
glTexCoord2f(((n-1)*50/1850)-1, 1.0); glVertex3f(0.0, 1.0, 1.0);
glEnd();
end;
glPopMatrix;
end;
When you use SDL already why not add SDL_ttf?
SDL_ttf is a TrueType font rendering library that is used with the SDL library, and almost as portable. It depends on freetype2 to handle the TrueType font data. It allows a programmer to use multiple TrueType fonts without having to code a font rendering routine themselves. With the power of outline fonts and antialiasing, high quality text output can be obtained without much effort.
I used bitmap fonts that are available in GLUT. The respective calls in JOGL (Java + OpenGL) are:
GLU glu = new GLU();
GLUT glut = new GLUT();
GL gl = drawable.getGL();
gl.glRasterPos3f(x, y, z); // move to (x, y, z) for the next text output
glut.glutBitmapString(GLUT.BITMAP_HELVETICA_12, "Message");
gl.glRasterPos3f (x2, y2, z2);
glut.glutBitmapCharacter (GLUT.BITMAP_HELVETICA_18, 'X');
This can surely be adapted to OpenGL + C++ easily.
精彩评论