I'm following this example.
freetype.h:
namespace myfreetype {
struct FontData {
float h;
GLuint *textures;
GLuint list_base;
int init(const char *fname, unsigned int h);
void clean();
};
void print(const FontData &ft_font, float x, float y, const char *fmt, ...);}
freetype.cpp:
namespace myfreetype {
static inline int _next_p2(int a) {
int v = 1;
while (v < a) {
v <<= 1;
}
return v;
}
static int make_dlist(FT_Face face, char ch, GLuint list_base, GLuint *tex_base) {
int r;
if ((r = FT_Load_Glyph(face, FT_Get_Char_Index(face, ch), FT_LOAD_DEFAULT)))
return r;
FT_Glyph glyph;
if ((r = FT_Get_Glyph(face->glyph, &glyph)))
return r;
FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, 0, 1);
FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
FT_Bitmap& bitmap=bitmap_glyph->bitmap;
int width = _next_p2(bitmap.width);
int height = _next_p2(bitmap.rows);
GLubyte* expanded_data = new GLubyte[ 2 * width * height];
for(int i=0; i < height; i++) {
for(int j=0; j < width; j++) {
expanded_data[2 * (j + i * width)]= expanded_data[2 * (j + i * width) + 1] =
(j >= bitmap.width || i >= bitmap.rows) ?
0 : bitmap.buffer[j + bitmap.width * i];
}
}
glBindTexture( GL_TEXTURE_2D, tex_base[ch]);
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, width, height, 0,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data );
delete [] expanded_data;
glNewList(list_base + ch, GL_COMPILE);
glBindTexture(GL_TEXTURE_2D, tex_base[ch]);
glPushMatrix();
glTranslatef(bitmap_glyph->left,0,0);
glTranslatef(0,bitmap_glyph->top-bitmap.rows,0);
float x = (float)bitmap.width / (float)width,
y = (float)bitmap.rows / (float)height;
glBegin(GL_QUADS);
glTexCoord2d(0, 0); glVertex2f(0, bitmap.rows);
glTexCoord2d(0, y); glVertex2f(0, 0);
glTexCoord2d(x, y); glVertex2f(bitmap.width, 0);
glTexCoord2d(x, 0); glVertex2f(bitmap.width, bitmap.rows);
glEnd();
glPopMatrix();
glTranslatef(face->glyph->advance.x >> 6, 0, 0);
glEndList();
return 0;
}
int FontData::init(const char* fname, unsigned int h) {
textures = new GLuint[128];
this->h = h;
int r;
FT_Library library;
if ((r = FT_Init_FreeType(&library)))_
return r;
FT_Face face;
if ((r = FT_New_Face(library, fname, 0, &face)))_
return r;
FT_Set_Char_Size(face, h << 6, h << 6, 96, 96);
list_base = glGenLists(128);
glGenTextures(128, textures);
for (unsigned char i = 0; i < 128; i++)
make_dlist(face, i, list_base, textures);
FT_Done_Face(face);
FT_Done_FreeType(library);
return 0;
}
void FontData::clean() {
glDeleteLists(list_base, 128);
glDeleteTextures(128, textures);
delete [] textures;
}
static inline void pushScreenCoordinateMatrix() {
glPushAttrib(GL_TRANSFORM_BIT);
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(viewport[0],viewport[2],viewport[1],viewport[3]);
glPopAttrib();
}
static inline void pop_projection_matrix() {
glPushAttrib(GL_TRANSFORM_BIT);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
}
void print(const FontData &ft_font, float x, float y, const char *fmt, ...) {
using std::string;
using std::vector;
pushScreenCoordinateMatrix();
GLuint font = ft_font.list_base;
float h = ft_font.h / .63;
char text[256];
va_list ap;
if (fmt == NULL)
*text = 0;
else {
va_start(ap, fmt);
vsprintf(text, fmt, ap);
va_end(ap);
}
const char *start_line=text;
vector<string> lines;
const char *c;
for(c = text; *c; c ++) {
if(*c == '\n') {
string line;
for(const char *n = start_line; n < c; n ++) line.append(1,*n);
lines.push_back(line);
start_line=c+1;
}
}
if (start_line) {
string line;
for(const char *n = start_line; n < c; n ++) line.append(1,*n);
lines.push_back(line);
}
glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glListBase(font);
float modelview_matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, modelview_matrix);
for(unsigned int i = 0; i < lines.size(); i ++) {
glPushMatrix();
glLoadIdentity();
glTranslatef(x, y - h * i,0);
glMultMatrixf(modelview_matrix);
glCallLists(lines[i].length(), GL_UNSIGNED_BYTE, lines[i].c_str());
glPopMatrix();
}
glPopAttrib();
pop_projection_matrix();
}
}
main.cpp:
void reshape(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2, 2, -2, 2, -2, 2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
myfreetype::FontData our_font;
void init() {
glClearColor(0, 0, 0, 0);//RGBA
if (our_font.init("Test.ttf", 16)) {
exit(EXIT_FAILURE);
}
}
void display() {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
static int cnt = 0;
cnt ++;
glColor3ub(0, 0xff, 0);
glLoadIdentity();
myfreetype::print(our_font, 120, 200, "Active FreeType Text - %7.2f", cnt);
}
int main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH|GLUT_RGBA);
glutInitWindowSize(512, 512);
glutInitWindowPosition(100, 100);
glutCreateWindow("hello world texture window");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutIdleFunc(display);
init();
glutMainLoop();
return 0;
}
However when running,nothing is shown.
What's wrong in my code?