Jump to content

  • Log In with Google      Sign In   
  • Create Account

Katz

Member Since 21 Jun 2011
Offline Last Active Jun 22 2011 12:56 PM

Topics I've Started

Problem with lesson 43

21 June 2011 - 08:06 AM

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:
#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();
}

PARTNERS