// TestFT2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include <GL/GL.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include <iostream>
#include <sdl/SDL.h>
#include <SDL/SDL_image.h>
using namespace std;
class FT2
{
int gltexture;
public:
int init(char* fname, int width, int height);
GLuint loadchar(wchar_t ch);
private:
FT_Library ftlib;
FT_Face face;
int nextp2(int n);
};
int FT2::nextp2(int n)
{
int rval=1;
// rval<<=1 Is A Prettier Way Of Writing rval*=2;
while(rval<n) {rval = rval* 2;}
return rval;
}
int FT2::init(char* fname, int width, int height)
{
if (FT_Init_FreeType(&ftlib))
{
cout <<"Error during lib initialization"<<endl;
return 1;
}
if (FT_New_Face(ftlib,fname,0,&face))
{
cout <<"error during face initialization"<<endl;
return 2;
}
FT_Select_Charmap(face, FT_ENCODING_UNICODE);
FT_Set_Pixel_Sizes(face,width, height);
gltexture = 0;
return 0;
}
GLuint FT2::loadchar(wchar_t ch)
{
FT_GlyphSlot slot = face->glyph;
int pen_x,pen_y;
if(FT_Load_Char(face, ch,FT_LOAD_RENDER|FT_LOAD_FORCE_AUTOHINT|
(true ? FT_LOAD_TARGET_NORMAL : FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO) ) )
{
return 0;
}
//Draw function
FT_Glyph glyph;
if(FT_Get_Glyph( face->glyph, &glyph ))
cout << "FT_Get_Glyph failed";
// Convert The Glyph To A Bitmap.
FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD);
FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1 );
FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
// This Reference Will Make Accessing The Bitmap Easier.
FT_Bitmap& bitmap = bitmap_glyph->bitmap;
face->size->metrics.y_ppem;
//Padding for bitmapformat
int h = nextp2(bitmap.rows);
int w = nextp2(bitmap.width);
char* pBuf = new char[w * h * 4];
cout <<"before pbuf"<<endl;
/*
for(int j=0; j <h;j++) for(int i=0; i < w; i++) {
pBuf[2*(i+j*w)] = 255;
pBuf[2*(i+j*w)+1] = (i>=bitmap.width || j>=bitmap.rows) ?
0 : bitmap.buffer[i + bitmap.width*j];
}
*/
GLuint texture;
glGenTextures( 1, &texture );
glBindTexture(GL_TEXTURE_2D,texture);
memset(pBuf, 0 , w * h * 4);
// /*
for(int j=0; j < bitmap.rows ; j++)
{
for(int i=0; i < bitmap.width; i++)
{
unsigned char _vl = (i>=bitmap.width || j>=bitmap.rows) ? 255 : bitmap.buffer[i + bitmap.width*j];
pBuf[(4*i + (h - j - 1) * w * 4) ] = 0xff;
pBuf[(4*i + (h - j - 1) * w * 4)+1] = 0xff;
pBuf[(4*i + (h - j - 1) * w * 4)+2] = 0xff;
pBuf[(4*i + (h - j - 1) * w * 4)+3] = _vl;
}
}
//*/
cout <<"after pbuf"<<endl;
FT_Done_Glyph(glyph);
glTexImage2D( GL_TEXTURE_2D,0,GL_RGBA,32, 32,0,GL_RGBA,GL_UNSIGNED_BYTE,pBuf);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//glTexEnvi(GL_TEXTURE_2D,GL_TEXTURE_ENV_MODE,GL_REPLACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
cout <<"after writing data"<<endl;
/////////////////////////////////////////
FT_Done_FreeType(ftlib);
delete []pBuf;
gltexture = texture;
return 0;
}
void drawtext()
{
glClearColor(1.0f,1.0f,1.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glLoadIdentity();
glBegin ( GL_QUADS );
{
glTexCoord2f(0.0f, 0.0f); glVertex3f(30, 20, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(60, 20, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(60, 50 , 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(30 , 50 , 1.0f);
glColor3f(1.f,0.f,0.f);
glVertex3f(50 , 140 , 1.0f);
glVertex3f(80, 140 , 1.0f);
glVertex3f(80, 120, 1.0f);
glVertex3f(50, 120, 1.0f);
}
glEnd();
cout <<"drawtext ended"<<endl;
SDL_GL_SwapBuffers();
//pen_x + = slot->advance.x>>6;
//glDeleteTextures(1, &texture);
}
void init(int w , int h )
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_Surface* drawContext;
Uint32 flags;
flags = SDL_OPENGL | SDL_RESIZABLE;
drawContext = SDL_SetVideoMode(w, h, 0, flags);
glMatrixMode(GL_PROJECTION);
glOrtho(0,w , 0 , h , -1000,1000);
glMatrixMode(GL_MODELVIEW);
FT2 text;
int a = text.init("c://windows//fonts//simhei.ttf",32,32);
text.loadchar((L"猪")[0]);
}
#pragma comment(lib, "SDL.lib")
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib,"freetype.lib")
void EventLoop(void)
{
SDL_Event event;
bool done = false;
while(!done)
{
while( SDL_PeepEvents(&event,1,SDL_GETEVENT,0) )
{
switch(event.type)
{
case SDL_KEYDOWN:
done = true;
// Handle any key presses here.
break;
case SDL_MOUSEBUTTONDOWN:
// Handle mouse clicks here.
break;
case SDL_QUIT:
done = true;
break;
default:
break;
} // End switch
}
drawtext();
SDL_GL_SwapBuffers();
} // End while
}
int _tmain(int argc, char *argv[])
{
//Initialize SDL + OpenGL
init( 512, 512);
EventLoop();
SDL_Quit();
return 0;
}