• Advertisement

Katz

Member
  • Content count

    2
  • Joined

  • Last visited

Community Reputation

100 Neutral

About Katz

  • Rank
    Newbie
  1. Problem with lesson 43

    OK, I solved my own problem, after much looking around. I had two main problems: One was that my texture coordinates were entered into integers, although they are supposed to by smaller than 1. (Two days for this problem... *facepalm*) The other was that I am using a different coordinate system: My ordinate axis runs from top to bottom and not bottom to top. Anyway, working code, if it may help anybody: [code] #include <SDL.h> #include <GL/gl.h> #include <GL/glu.h> #include <ft2build.h> #include FT_FREETYPE_H #include <vector> #include <string> #include <iostream> using namespace std; struct font_data { int h; GLuint *textures; GLuint listBase; void init(string fontName, unsigned int h); //create font of required height void clean(); //clean font data }; void write(const font_data &ft_font, int x, int y, string text); //get power of two right above given number inline int nextP2(int nb) { int ret=1; while(ret < nb) ret *= 2; return ret; } //create a display lit corresponding to the given character void makeDList(FT_Face font, unsigned char ch, GLuint listBase, GLuint *texBase) { if(FT_Load_Char(font, ch, FT_LOAD_RENDER)) cout << "FT_Load_Char failed in makeDList." << endl; FT_GlyphSlot glyph = font->glyph; FT_Bitmap &bitmap = glyph->bitmap; //get required width and height to get correct texture size int width = nextP2(bitmap.width); int height = nextP2(bitmap.rows); GLubyte *expandedData = new GLubyte [2*width*height]; for(int j=0;j<height;j++) { for(int i=0;i<width;i++) { expandedData[2*(i+j*width)] = 255; expandedData[2*(i+j*width)+1] = (i>=bitmap.width || j>=bitmap.rows) ? 0 : bitmap.buffer[i+bitmap.width*j]; } } glBindTexture(GL_TEXTURE_2D, texBase[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, expandedData); delete [] expandedData; glNewList(listBase + ch, GL_COMPILE); glBindTexture(GL_TEXTURE_2D, texBase[ch]); glPushMatrix(); glTranslatef(glyph->bitmap_left,0,0); //shift character to have right amount of space before glTranslatef(0, (font->bbox.yMax - glyph->metrics.horiBearingY)/64,0); //move down a little if previous line has lower character double x = (double)bitmap.width /(double)width; //take empty space around char into account double y = (double)bitmap.rows / (double)height; glBegin(GL_QUADS); glTexCoord2d(0,y); glVertex2f(0,bitmap.rows); glTexCoord2d(0,0); glVertex2f(0,0); glTexCoord2d(x,0); glVertex2f(bitmap.width,0); glTexCoord2d(x,y); glVertex2f(bitmap.width,bitmap.rows); glEnd(); glPopMatrix(); glTranslatef(glyph->metrics.horiAdvance/64,0,0); glEndList(); } void font_data::init(string fontName, unsigned int h) { textures = new GLuint[128]; this->h=h; FT_Library library; if(FT_Init_FreeType(&library)) cout << "Could not initialize Freetype library" << endl; FT_Face font; if(FT_New_Face(library, fontName.c_str(), 0, &font)) cout << "Could not open font \"" <<fontName<<"\"."<<endl; FT_Set_Char_Size(font, h*64,h*64,96,96); //set font size //allocate resources for textures and display lists listBase=glGenLists(128); glGenTextures(128,textures); //create each of the fonts display lists for(unsigned char i=0;i<128;i++) makeDList(font,i,listBase,textures); FT_Done_Face(font); FT_Done_FreeType(library); } void font_data::clean() { glDeleteLists(listBase,128); glDeleteTextures(128,textures); delete [] textures; } void write(const font_data &ft_font, int x, int y, string text) { GLuint font = ft_font.listBase; glListBase(font); glPushMatrix(); glTranslatef(x,y,0); //move to text glCallLists(text.length(), GL_UNSIGNED_BYTE,text.c_str()); glPopMatrix(); } int main ( int argc, char** argv ) { SDL_Init( SDL_INIT_VIDEO ); SDL_SetVideoMode(800, 600, 32, SDL_OPENGL); //set openGL parameters glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0,800,600,0); glDisable(GL_DEPTH_TEST); //depth buffering glEnable(GL_TEXTURE_2D); //texture using glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); font_data myFont; myFont.init("../TD/fonts/jester.ttf", 20); SDL_Event event; bool quit = false; while(!quit) { glClear(GL_COLOR_BUFFER_BIT); glColor3ub(255,255,255); glDisable(GL_TEXTURE_2D); glBegin(GL_QUADS); glVertex2d(0,0); glVertex2d(800,0); glVertex2d(800,600); glVertex2d(0,600); glEnd(); glEnable(GL_TEXTURE_2D); glColor3ub(180,180,0); write(myFont,200,300, "Hello World!"); glFlush(); SDL_GL_SwapBuffers(); while (SDL_PollEvent(&event)) { if(event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && (event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_RETURN))) quit=true; } } myFont.clean(); SDL_Quit(); } [/code]
  2. Hello ! I'm having troubles with lesson 43. I can't get FreeType to work and display text. I made a test program to try to make it work. I've changed some things from lesson 43, taken out some things I wouldn't need, changed some variables names to respect my own conventions, and mixed it up a little with the tutorial on FreeType's website. Problem is I don't get any text. OpenGL works fine, as I get a red rectangle. But no text. The main problem is I don't really understand all that was done in the tutorial, so I might have changed some stuff I wasn't supposed to... I especially cut a whole lot in the "print()" function (renamed "write()" in my code). Can someone help me get this code to work? Or point out at least what vital part I'm missing, so I can look it up in the tutorial? Thanks ! Code follows: [code]#include <SDL.h> #include <GL/gl.h> #include <GL/glu.h> #include <ft2build.h> #include FT_FREETYPE_H #include <vector> #include <string> #include <iostream> using namespace std; struct font_data { int h; GLuint *textures; GLuint listBase; void init(string fontName, unsigned int h); //create font of required height void clean(); //clean font data }; void write(const font_data &ft_font, int x, int y, string text); //get power of two right above given number inline int nextP2(int nb) { int ret=1; while(ret < nb) ret *= 2; return ret; } //create a display lit corresponding to the given character void makeDList(FT_Face font, char ch, GLuint listBase, GLuint *texBase) { if(FT_Load_Char(font, ch, FT_LOAD_RENDER)) cout << "FT_Load_Char failed in makeDList." << endl; FT_Bitmap &bitmap = font->glyph->bitmap; //get required with and height to get correct texture size int width = nextP2(bitmap.width); int height = nextP2(bitmap.rows); GLubyte *expandedData = new GLubyte [2*width*height]; for(int j=0;j<height;j++) { for(int i=0;i<width;i++) expandedData[2*(i+j*width)] = expandedData[2*(i+j*width)+1] = (i>=bitmap.width || j>=bitmap.rows) ? 0 : bitmap.buffer[i+bitmap.width*j]; } glBindTexture(GL_TEXTURE_2D, texBase[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, expandedData); delete [] expandedData; glNewList(listBase + ch, GL_COMPILE); glBindTexture(GL_TEXTURE_2D, texBase[ch]); glPushMatrix(); //glTranslatef(font->glyph->left,0,0); //shift character to have right amount of space before //glTranslatef(0,font->glyph->top - bitmap.rows,0); //move down a little if previous line has lower character int x = bitmap.width / width; //take empty space around char into account int y = bitmap.rows / 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(font->glyph->advance.x * 64,0,0); glEndList(); } void font_data::init(string fontName, unsigned int h) { textures = new GLuint[128]; this->h=h; FT_Library library; if(FT_Init_FreeType(&library)) cout << "Could not initialize Freetype library" << endl; FT_Face font; if(FT_New_Face(library, fontName.c_str(), 0, &font)) cout << "Could not open font \"" <<fontName<<"\"."<<endl; FT_Set_Char_Size(font, h*64,h*64,96,96); //set font size //allocate resources for textures and display lists listBase=glGenLists(128); glGenTextures(128,textures); //create each of the fonts display lists for(unsigned char i=0;i<128;i++) makeDList(font,i,listBase,textures); FT_Done_Face(font); FT_Done_FreeType(library); } void font_data::clean() { glDeleteLists(listBase,128); glDeleteTextures(128,textures); delete [] textures; } void write(const font_data &ft_font, int x, int y, string text) { GLuint font = ft_font.listBase; glListBase(font); glPushMatrix(); glLoadIdentity(); glTranslatef(x,y,0); //move to text glCallLists(text.length(), GL_UNSIGNED_BYTE,text.c_str()); glPopMatrix(); } int main ( int argc, char** argv ) { SDL_Init( SDL_INIT_VIDEO ); SDL_SetVideoMode(800, 600, 32, SDL_OPENGL); //initialize freetype /*FT_Library freetype; if(FT_Init_FreeType(&freetype) != 0) { cout << "Unable to initialize Freetype library." <<endl; exit(EXIT_FAILURE); }*/ //set openGL parameters glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0,800,600,0); glDisable(GL_DEPTH_TEST); //depth buffering glEnable(GL_TEXTURE_2D); //texture using glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); font_data myFont; myFont.init("../TD/fonts/jester.ttf", 40); SDL_Event event; bool quit = false; while(!quit) { glClear(GL_COLOR_BUFFER_BIT); glColor3ub(255,0,0); glDisable(GL_TEXTURE_2D); glBegin(GL_QUADS); glVertex2d(180,280); glVertex2d(480,280); glVertex2d(480,480); glVertex2d(180,480); glEnd(); glColor3ub(0,255,0); glEnable(GL_TEXTURE_2D); write(myFont,200,300, "Hello World!"); glFlush(); SDL_GL_SwapBuffers(); while (SDL_PollEvent(&event)) { if(event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && (event.key.keysym.sym == SDLK_ESCAPE || event.key.keysym.sym == SDLK_RETURN))) quit=true; } } myFont.clean(); SDL_Quit(); }[/code]