C/C++ & OpenGL - Lightweight TTF Text Rendering (Ver 0.2)
Posted: Sat Sep 05, 2009 2:11 pm
This is for all you people who want to render normal .ttf font files into text on the screen, without having to use SDL_ttf and convert it to gl textures, or use some other bloated library.
First, you'll need this small library to include and link
http://freetype.sourceforge.net/index2.html
To use my code, simply make a new font structure like this, and use loadFont(), supplying a filepath and font size
The above code would load the font file "arial.ttf" in size 20
Then to render, put this in your rendering code
The above code would write "Hello, world!" on the screen
To finish using a font, call deleteFont on it
Here is the code
font.h
font.c
First, you'll need this small library to include and link
http://freetype.sourceforge.net/index2.html
To use my code, simply make a new font structure like this, and use loadFont(), supplying a filepath and font size
Code: Select all
struct Font* newfont;
newfont = loadFont("arial.ttf", 20);
Then to render, put this in your rendering code
Code: Select all
glOrtho(0, 640, 0, 480, 0, 10);
printFont(newfont, "Hello, world!");
To finish using a font, call deleteFont on it
Code: Select all
deleteFont(newfont);
font.h
Code: Select all
/*All code copyright to Ryan Pridgeon, 2009
If you wish to use this code, you must include these credits
in your code, and give credit in your application/documentation
Thankyou
*/
#ifndef RYAN_FONT
#define RYAN_FONT
#include <GL/gl.h>
struct Font{
GLuint textures[128];
GLuint displaylist;
float h;
};
struct Font* loadFont(char*, int);
int printFont(struct Font*, char*);
int deleteFont(struct Font*);
#endif // TANK_FONT
Code: Select all
/*All code copyright to Ryan Pridgeon, 2009
If you wish to use this code, you must include these credits
in your code, and give credit in your application/documentation
Thankyou
*/
#include "font.h"
#include <ft2build.h>
#include <freetype/freetype.h>
#include <freetype/ftglyph.h>
#include <freetype/ftoutln.h>
#include <freetype/fttrigon.h>
#include <GL/gl.h>
#include <string.h>
int nextPower(int val){
int x = 1;
while(x<val){
x <<= 1;
}
return x;
}
struct Font* loadFont(char* filepath, int height){
struct Font* temp;
FT_Library lib;
FT_Face face;
FT_Glyph glyph;
FT_Bitmap* bitmap;
FT_BitmapGlyph* bitglyph;
int w, h, xpos, ypos;
unsigned char i;
GLubyte* buffer;
float texpropx, texpropy;
temp = (struct Font*)malloc(sizeof(struct Font));
glGenTextures(128, temp->textures);
temp->displaylist = glGenLists(128);
FT_Init_FreeType(&lib);
FT_New_Face(lib, filepath, 0, &face);
FT_Set_Char_Size(face, height << 6, height << 6, 96, 96);
for (i=0;i<128;i++){
// get bitmap
FT_Load_Glyph(face, FT_Get_Char_Index(face, i), FT_LOAD_DEFAULT);
FT_Get_Glyph(face->glyph, &glyph);
FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, 0, 1);
bitglyph = (FT_BitmapGlyph*)&glyph;
bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
w= 1;
while(w<bitmap->width)
w *= 2;
h= 1;
while(h<bitmap->rows)
h *= 2;
// make bitmap
buffer = (GLubyte*)calloc(sizeof(GLubyte)*2*w*h, 1);
for (ypos=0;ypos<bitmap->rows;ypos++){
for (xpos=0;xpos<bitmap->width;xpos++){
buffer[2*(xpos+ypos*w)] = bitmap->buffer[xpos+ypos*bitmap->width];
buffer[2*(xpos+ypos*w)+1] = bitmap->buffer[xpos+ypos*bitmap->width];
}
}
glBindTexture(GL_TEXTURE_2D, temp->textures[i]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, buffer);
// make display list (for nicely formatted text)
glPushMatrix();
glNewList(temp->displaylist+i, GL_COMPILE);
glBindTexture(GL_TEXTURE_2D, temp->textures[i]);
glPushMatrix();
glTranslatef((*bitglyph)->left, (*bitglyph)->top-bitmap->rows, 0);
// proportions of the texture that are the font (not padding)
texpropx = (float)bitmap->width / (float)w;
texpropy = (float)bitmap->rows / (float)h;
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(0, bitmap->rows, 0);
glTexCoord2f(0, texpropy); glVertex3f(0, 0, 0);
glTexCoord2f(texpropx, texpropy); glVertex3f(bitmap->width, 0, 0);
glTexCoord2f(texpropx, 0); glVertex3f(bitmap->width, bitmap->rows, 0);
glEnd();
glPopMatrix();
glTranslatef(face->glyph->advance.x >> 6, 0, 0);
glEndList();
glPopMatrix();
free(buffer);
}
FT_Done_Face(face);
FT_Done_FreeType(lib);
return temp;
}
int printFont(struct Font* temp, char* text){
glListBase(temp->displaylist);
glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
return 0;
}
int deleteFont(struct Font* temp){
glDeleteTextures(128, temp->textures);
glDeleteLists(temp->displaylist, 128);
free(temp);
return 0;
}