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;
}