TextureFont * font_manager_get_from_filename( FontManager *self, const char * filename, const float size ) { size_t i; TextureFont *font; assert( self ); for( i=0; i<self->fonts->size;++i ) { font = (TextureFont *) vector_get( self->fonts, i ); if( (strcmp(font->filename, filename) == 0) && ( font->size == size) ) { return font; } } font = texture_font_new( self->atlas, filename, size ); texture_font_cache_glyphs( font, self->cache ); if( font ) { vector_push_back( self->fonts, font ); } return font; }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitWindowSize( 800, 400 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Freetype OpenGL / vertex arrays" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); size_t i; texture_font_t *font = 0; texture_atlas_t *atlas = texture_atlas_new( 512, 512, 1 ); const char * filename = "./Vera.ttf"; wchar_t *text = L"A Quick Brown Fox Jumps Over The Lazy Dog 0123456789"; buffer = vertex_buffer_new( "v3f:t2f:c4f" ); vec2 pen = {{0,0}}; vec4 black = {{0,0,0,1}}; for( i=7; i < 27; ++i) { font = texture_font_new( atlas, filename, i ); pen.x = 0; pen.y -= font->height; texture_font_load_glyphs( font, text ); add_text( buffer, font, text, &black, &pen ); texture_font_delete( font ); } glBindTexture( GL_TEXTURE_2D, atlas->id ); glutMainLoop( ); return 0; }
// ----------------------------------------- font_manager_get_from_filename --- texture_font_t * font_manager_get_from_filename( font_manager_t *self, const char * filename, const float size ) { size_t i; texture_font_t *font; assert( self ); for( i=0; i<vector_size(self->fonts); ++i ) { font = * (texture_font_t **) vector_get( self->fonts, i ); if( (strcmp(font->filename, filename) == 0) && ( font->size == size) ) { return font; } } font = texture_font_new( self->atlas, filename, size ); if( font ) { vector_push_back( self->fonts, &font ); texture_font_load_glyphs( font, self->cache ); return font; } fprintf( stderr, "Unable to load \"%s\" (size=%.1f)\n", filename, size ); return 0; }
//texture int init_texture() { memset( &m_texture, 0, sizeof(texture) ); glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 ); //global m_texture.data = (unsigned char *)malloc( IMAGE_W * IMAGE_H * 1 ); glActiveTexture(GL_TEXTURE0); m_texture.text_atlas = texture_atlas_new( 1024, 1024, 1 ); m_texture.text_font = texture_font_new( m_texture.text_atlas, "./fonts/Vera.ttf", 60/*size*/ ); texture_font_load_glyphs( m_texture.text_font, L" !\"#$%&'()*+,-./0123456789:;<=>?" L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" L"`abcdefghijklmnopqrstuvwxyz{|}~"); texture_atlas_upload(m_texture.text_atlas); //uploads data to gpu memory using glTexImage2D(). glActiveTexture(GL_TEXTURE1); glGenTextures(1, &m_texture.m_texture); glBindTexture(GL_TEXTURE_2D, m_texture.m_texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // only for Active texture glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); return (0); }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { size_t width = 800, height = 200; glutInit( &argc, argv ); glutInitWindowSize( width, height ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Glyph Cartoon" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ fprintf( stderr, "Error: %s\n", glewGetErrorString(err) ); exit( EXIT_FAILURE ); } fprintf( stderr, "Using GLEW %s\n", glewGetString(GLEW_VERSION) ); atlas = texture_atlas_new( 1024, 1024, 1 ); buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); texture_font_t *font = texture_font_new( atlas, "fonts/ObelixPro.ttf", 128 ); vec2 pen = {{50, 50}}; vec4 black = {{0.0, 0.0, 0.0, 1.0}}; vec4 yellow = {{1.0, 1.0, 0.0, 1.0}}; vec4 orange1 = {{1.0, 0.9, 0.0, 1.0}}; vec4 orange2 = {{1.0, 0.6, 0.0, 1.0}}; font->outline_type = 2; font->outline_thickness = 7; add_text( buffer, font, L"Freetype GL", pen, black, black ); font->outline_type = 2; font->outline_thickness = 5; add_text( buffer, font, L"Freetype GL", pen, yellow, yellow ); font->outline_type = 1; font->outline_thickness = 3; add_text( buffer, font, L"Freetype GL", pen, black, black ); font->outline_type = 0; font->outline_thickness = 0; add_text( buffer, font, L"Freetype GL", pen, orange1, orange2 ); shader = shader_load("shaders/v3f-t2f-c4f.vert", "shaders/v3f-t2f-c4f.frag"); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); glutMainLoop( ); return 0; }
void opengl_font_reload(font_t* f) { opengl_font_t* o = (opengl_font_t*)f->data; texture_font_delete(o->font); texture_atlas_delete(o->atlas); o->atlas = texture_atlas_new(512, 512, 1); o->font = texture_font_new(o->atlas, o->name, f->size * window_zoom); texture_font_load_glyphs(o->font, cache); }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { size_t i; vec4 color = {{0,0,0,1}}; vec2 pen = {{0,0}}; glutInit( &argc, argv ); glutInitWindowSize( 800, 600 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Freetype OpenGL benchmark" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); glutIdleFunc( idle ); GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ fprintf( stderr, "Error: %s\n", glewGetErrorString(err) ); exit( EXIT_FAILURE ); } fprintf( stderr, "Using GLEW %s\n", glewGetString(GLEW_VERSION) ); atlas = texture_atlas_new( 512, 512, 1 ); font = texture_font_new( atlas, "fonts/VeraMono.ttf", 12 ); buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); pen.y = -font->descender; for( i=0; i<line_count; ++i ) { pen.x = 10.0; add_text( buffer, font, text, &color, &pen ); pen.y += font->height - font->linegap; } glClearColor( 1.0, 1.0, 1.0, 1.0 ); glDisable( GL_DEPTH_TEST ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glEnable( GL_TEXTURE_2D ); glEnable( GL_BLEND ); shader = shader_load("shaders/v3f-t2f-c4f.vert", "shaders/v3f-t2f-c4f.frag"); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); glutMainLoop( ); return EXIT_SUCCESS; }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitWindowSize( 512, 512 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Freetype OpenGL width shaders" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutMotionFunc( mouse_drag ); glutPassiveMotionFunc( mouse_motion ); glutKeyboardFunc( keyboard ); GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ fprintf( stderr, "Error: %s\n", glewGetErrorString(err) ); exit( EXIT_FAILURE ); } fprintf( stderr, "Using GLEW %s\n", glewGetString(GLEW_VERSION) ); unsigned char *map; texture_font_t * font; const char *filename = "fonts/Vera.ttf"; const wchar_t *cache = L" !\"#$%&'()*+,-./0123456789:;<=>?" L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" L"`abcdefghijklmnopqrstuvwxyz{|}~"; atlas = texture_atlas_new( 512, 512, 1 ); font = texture_font_new( atlas, filename, 72 ); texture_font_load_glyphs( font, cache ); texture_font_delete( font ); fprintf( stderr, "Generating distance map...\n" ); map = make_distance_map(atlas->data, atlas->width, atlas->height); fprintf( stderr, "done !\n"); memcpy( atlas->data, map, atlas->width*atlas->height*sizeof(unsigned char) ); free(map); texture_atlas_upload( atlas ); // Create the GLSL program program = shader_load( "shaders/distance-field.vert", "shaders/distance-field.frag" ); glUseProgram( program ); glutMainLoop( ); return 0; }
int modelEngine::initFonts() { /* Texture atlas to store individual glyphs */ atlas = texture_atlas_new( 1024, 1024, 1 ); font1 = texture_font_new( atlas, "./fonts/fonts/custom.ttf", 50 ); font2 = texture_font_new( atlas, "./fonts/fonts/ObelixPro.ttf", 70 ); /* Cache some glyphs to speed things up */ texture_font_load_glyphs( font1, L" !\"#$%&'()*+,-./0123456789:;<=>?" L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" L"`abcdefghijklmnopqrstuvwxyz{|}~"); texture_font_load_glyphs( font2, L" !\"#$%&'()*+,-./0123456789:;<=>?" L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" L"`abcdefghijklmnopqrstuvwxyz{|}~"); texture_atlas_upload(atlas); vec2 pen = {-400,150}; vec4 color = {0.5,0.5,0.5,0.5}; GLuint bufIndex = atlas->id; }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitWindowSize( 800, 400 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Freetype OpenGL / LCD filtering" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); // GLenum err = glewInit(); // if (GLEW_OK != err) // { // /* Problem: glewInit failed, something is seriously wrong. */ // fprintf( stderr, "Error: %s\n", glewGetErrorString(err) ); // exit( EXIT_FAILURE ); // } // fprintf( stderr, "Using GLEW %s\n", glewGetString(GLEW_VERSION) ); size_t i; texture_font_t *font = 0; atlas = texture_atlas_new( 512, 512, 3 ); const char * filename = "fonts/Vera.ttf"; wchar_t *text = L"A Quick Brown Fox Jumps Over The Lazy Dog 0123456789"; buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f,ashift:1f,agamma:1f" ); vec2 pen = {{0,0}}; vec4 color = {{0,0,0,1}}; for( i=7; i < 27; ++i) { font = texture_font_new( atlas, filename, i ); pen.x = 0; pen.y -= font->height; texture_font_load_glyphs( font, text ); add_text( buffer, font, text, &color, &pen ); texture_font_delete( font ); } glBindTexture( GL_TEXTURE_2D, atlas->id ); shader = shader_load( "shaders/text.vert", "shaders/text.frag" ); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); glutMainLoop( ); return 0; }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitWindowSize( 512, 512 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( argv[0] ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); atlas = texture_atlas_new( 512, 512, 1 ); assert(atlas); const char *filename = "../fonts/Vera.ttf"; const wchar_t *cache = L" !\"#$%&'()*+,-./0123456789:;<=>?" L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" L"`abcdefghijklmnopqrstuvwxyz{|}~"; size_t minsize = 8, maxsize = 27; size_t count = maxsize - minsize; size_t i, missed = 0; for( i=minsize; i < maxsize; ++i ) { texture_font_t * font = texture_font_new( atlas, filename, i ); if(!font) { fprintf(stderr, "Failed to load font: \"%s\"\n", filename); return -1; } if(!texture_font_load_glyphs( font, cache )) { missed++; } texture_font_delete( font ); } printf( "Matched font : %s\n", filename ); printf( "Number of fonts : %zd\n", count ); printf( "Number of glyphs per font : %zd\n", wcslen(cache) ); printf( "Number of missed glyphs : %zd\n", missed ); printf( "Total number of glyphs : %zd/%zd\n", wcslen(cache)*count - missed, wcslen(cache)*count ); printf( "Texture size : %zdx%zd\n", atlas->width, atlas->height ); printf( "Texture occupancy : %.2f%%\n", 100.0*atlas->used/(float)(atlas->width*atlas->height) ); glutMainLoop( ); return 0; }
void Font::ResizeFont(int size) { if(m_font) texture_font_delete(m_font); if(m_atlas) texture_atlas_delete(m_atlas); delete m_textureAtlas; m_atlas = texture_atlas_new(512, 512, 1); m_font = texture_font_new(m_atlas, m_fontFile->m_buffer, m_fontFile->m_bufLength, (float)size); texture_font_load_glyphs(m_font, L" !\"#$%&'()*+,-./0123456789:;<=>?" L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" L"`abcdefghijklmnopqrstuvwxyz{|}~", m_fontFile->m_buffer, m_fontFile->m_bufLength); m_textureAtlas = new GLTexture(m_atlas->id, 512, 512); }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { size_t width = 600, height = 200; glutInit( &argc, argv ); glutInitWindowSize( width, height ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Glyph Cartoon" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); atlas = texture_atlas_new( 1024, 1024, 1 ); buffer = vertex_buffer_new( "v3f:t2f:c4f" ); texture_font_t *font = texture_font_new( atlas, "./ObelixPro.ttf", 128 ); vec2 pen = {{30, 50}}; vec4 black = {{0.0, 0.0, 0.0, 1.0}}; vec4 yellow = {{1.0, 1.0, 0.0, 1.0}}; vec4 orange1 = {{1.0, 0.9, 0.0, 1.0}}; vec4 orange2 = {{1.0, 0.6, 0.0, 1.0}}; font->outline_type = 1; font->outline_thickness = 4; add_text( buffer, font, L"Cartoon", pen, black, black ); /* font->outline_type = 2; font->outline_thickness = 4; add_text( buffer, font, L"Cartoon", pen, black, yellow ); font->outline_type = 3; font->outline_thickness = 4; add_text( buffer, font, L"Cartoon", pen, black, yellow ); */ font->outline_type = 0; font->outline_thickness = 0; add_text( buffer, font, L"Cartoon", pen, orange1, orange2 ); glutMainLoop( ); return 0; }
ofxFreeTypeGL::ofxFreeTypeGL(){ texture_atlas_t * atlas = texture_atlas_new( ofGetWidth(), ofGetHeight(), 1 ); texture.allocate(1024, 1024, GL_LUMINANCE_ALPHA); const char *filename = "../../../data/fonts/hiraginoKakugoW6.otf"; const wchar_t *cache = L"Wow,これは面白い!!夜露死苦〠"; size_t minsize = 4, maxsize = 80; size_t count = maxsize - minsize; size_t i, missed = 0; for( i=minsize; i < maxsize; ++i ){ texture_font_t * font = texture_font_new( atlas, filename, i ); missed += texture_font_load_glyphs( font, cache ); texture_font_delete( font ); } printf( "Matched font : %s\n", filename ); printf( "Number of fonts : %ld\n", count ); printf( "Number of glyphs per font : %ld\n", wcslen(cache) ); printf( "Number of missed glyphs : %ld\n", missed ); printf( "Total number of glyphs : %ld/%ld\n", wcslen(cache)*count - missed, wcslen(cache)*count ); printf( "Texture size : %ldx%ld\n", atlas->width, atlas->height ); printf( "Texture occupancy : %.2f%%\n", 100.0*atlas->used/(float)(atlas->width*atlas->height) ); const int SIZE = atlas->width * atlas->height; vector<unsigned char> temp; temp.resize(SIZE * 2); unsigned char *src = atlas->data; unsigned char *dst = temp.data(); for (int i = 0; i < SIZE; i++){ dst[0] = 255; dst[1] = *src; src++; dst += 2; } texture.loadData(temp.data(), 1024, 1024, GL_LUMINANCE_ALPHA); }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitWindowSize( 260, 330 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Freetype OpenGL / subpixel rendering" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); size_t i; texture_font_t *font; const char * filename = "./Vera.ttf"; wchar_t *text = L"|... A Quick Brown Fox Jumps Over The Lazy Dog"; vec2 pen = {{0,0}}; vec4 black = {{0,0,0,1}}; atlas = texture_atlas_new( 512, 512, 3 ); font = texture_font_new( atlas, filename, 9 ); buffer = vertex_buffer_new( "v3f:t2f:c4f:1g1f" ); pen.x = 0; pen.y = 0; pen.y -= font->ascender; for( i=0; i < 30; ++i) { pen.x = 20 + i * 0.1; pen.y = 310 - i * 10; add_text( buffer, font, text, &black, &pen ); } // Create the GLSL program char * vertex_shader_source = read_shader("./subpixel.vert"); char * fragment_shader_source = read_shader("./subpixel.frag"); program = build_program( vertex_shader_source, fragment_shader_source ); texture_location = glGetUniformLocation(program, "texture"); pixel_location = glGetUniformLocation(program, "pixel"); glBindTexture( GL_TEXTURE_2D, atlas->id ); glutMainLoop( ); return 0; }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitWindowSize( 512, 512 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Distance fields demo" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); glutTimerFunc( 1000.0/60, timer, 60 ); GLenum err = glewInit(); if (GLEW_OK != err) { /* Problem: glewInit failed, something is seriously wrong. */ fprintf( stderr, "Error: %s\n", glewGetErrorString(err) ); exit( EXIT_FAILURE ); } fprintf( stderr, "Using GLEW %s\n", glewGetString(GLEW_VERSION) ); program = shader_load( "shaders/distance-field.vert", "shaders/distance-field-3.frag" ); glUseProgram( program ); atlas = texture_atlas_new( 512, 512, 1 ); font = texture_font_new( atlas, "fonts/Vera.ttf", 32 ); texture_glyph_t *glyph; // Generate the glyp at 512 points, compute distance field and scale it // back to 32 points // Just load another glyph if you want to see difference (draw render a '@') glyph = load_glyph( "fonts/Vera.ttf", L'@', 512, 64, 0.1); vector_push_back( font->glyphs, &glyph ); texture_atlas_upload( atlas ); glutMainLoop( ); return 0; }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { size_t i; vec4 color = {{0,0,0,1}}; vec2 pen = {{0,0}}; glutInit( &argc, argv ); glutInitWindowSize( 800, 600 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Freetype OpenGL benchmark" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); glutIdleFunc( idle ); atlas = texture_atlas_new( 512, 512, 1 ); font = texture_font_new( atlas, "fonts/VeraMono.ttf", 12 ); buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); pen.y = -font->descender; for( i=0; i<line_count; ++i ) { pen.x = 10.0; add_text( buffer, font, text, &color, &pen ); pen.y += font->height - font->linegap; } glClearColor( 1.0, 1.0, 1.0, 1.0 ); glDisable( GL_DEPTH_TEST ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glEnable( GL_TEXTURE_2D ); glEnable( GL_BLEND ); shader = shader_load("shaders/v3f-t2f-c4f.vert", "shaders/v3f-t2f-c4f.frag"); glutMainLoop( ); return EXIT_SUCCESS; }
int opengl_font_build( font_t* font, const char* file, int size) { opengl_font_t* o; if((o = (opengl_font_t*)malloc(sizeof(opengl_font_t))) == NULL) return 0; font->size = size; font->data = (void*)o; m_sprintf(o->name, MAX_BUFFER, DATA_PATH "/" FONTS "/%s", file); o->atlas = texture_atlas_new(512, 512, 1); o->font = texture_font_new(o->atlas, o->name, size * window_zoom); texture_font_load_glyphs(o->font, cache); current_font = font; // Set last build to current one. return 1; }
// ----------------------------------------------------------- build_buffer --- void build_buffer( void ) { vec2 pen; size_t i; texture_font_t *font; texture_glyph_t *glyph; vec4 white = {{1.0, 1.0, 1.0, 1.0}}; vec4 none = {{1.0, 1.0, 1.0, 0.0}}; markup_t markup = { .family = "Arial", .size = 10.0, .bold = 0, .italic = 0, .rise = 0.0, .spacing = 0.0, .gamma = 2.2, .foreground_color = white, .background_color = none, .underline = 0, .underline_color = white, .overline = 0, .overline_color = white, .strikethrough = 0, .strikethrough_color = white, .font = 0, }; vertex_buffer_clear( buffer ); texture_atlas_clear( atlas ); if( p_family == VERA) { font = texture_font_new( atlas, "fonts/Vera.ttf", p_size ); } else if( p_family == VERA_MONO) { font = texture_font_new( atlas, "fonts/VeraMono.ttf", p_size ); } else if( p_family == GEORGIA) { font = texture_font_new( atlas, "fonts/Georgia.ttf", p_size ); } else if( p_family == TIMES ) { font = texture_font_new( atlas, "fonts/Times.ttf", p_size ); } else if( p_family == TAHOMA ) { font = texture_font_new( atlas, "fonts/Tahoma.ttf", p_size ); } else if( p_family == ARIAL ) { font = texture_font_new( atlas, "fonts/Arial.ttf", p_size ); } else if( p_family == VERDANA ) { font = texture_font_new( atlas, "fonts/Verdana.ttf", p_size ); } else { fprintf( stderr, "Error : Unknown family type\n" ); return; } font->hinting = p_hinting; font->filtering = 1; float norm = 1.0/(p_primary + 2*p_secondary + 2*p_tertiary); font->lcd_weights[0] = (unsigned char)(p_tertiary*norm*256); font->lcd_weights[1] = (unsigned char)(p_secondary*norm*256); font->lcd_weights[2] = (unsigned char)(p_primary*norm*256); font->lcd_weights[3] = (unsigned char)(p_secondary*norm*256); font->lcd_weights[4] = (unsigned char)(p_tertiary*norm*256); texture_font_load_glyphs( font, L" !\"#$%&'()*+,-./0123456789:;<=>?" L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" L"`abcdefghijklmnopqrstuvwxyz{|}~" ); pen.x = 10; pen.y = 600 - font->height - 10; glyph = texture_font_get_glyph( font, text[0] ); add_glyph( glyph, buffer, &markup, &pen, 0 ); for( i=1; i<wcslen(text); ++i ) { if( text[i] == '\n' ) { pen.x = 10; pen.y -= font->height; // + 0.01*(size - (int)size)*font->height; } else { glyph = texture_font_get_glyph( font, text[i] ); float kerning = 0.0; if( p_kerning ) { kerning = texture_glyph_get_kerning( glyph, text[i-1] ); } add_glyph( glyph, buffer, &markup, &pen, kerning ); } } texture_font_delete (font ); } // ---------------------------------------------------------------- display --- void display(void) { if( p_invert ) { glClearColor( 0, 0, 0, 1 ); } else { glClearColor( 1, 1, 1, 1 ); } glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glEnable( GL_TEXTURE_2D ); glBindTexture( GL_TEXTURE_2D, atlas->id ); if( !p_lcd_filtering ) { glEnable( GL_COLOR_MATERIAL ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); if( p_invert ) { glColor4f(1,1,1,1); } else { glColor4f(0,0,0,1); } } else { glEnable( GL_COLOR_MATERIAL ); glBlendFunc( GL_CONSTANT_COLOR_EXT, GL_ONE_MINUS_SRC_COLOR ); glEnable( GL_BLEND ); glColor3f( 1,1,1 ); if( p_invert ) { glBlendColor( 1, 1, 1, 1 ); } else { glBlendColor( 0, 0, 0, 1 ); } } if( !p_lcd_filtering ) { vertex_buffer_render( buffer, GL_TRIANGLES, "vt" ); } else { glUseProgram( program ); glUniform1i( texture_location, 0 ); glUniform1f( gamma_location, p_gamma ); float norm = 1.0/(p_primary+2*p_secondary+2*p_tertiary); glUniform1f( primary_location, p_primary*norm ); glUniform1f( secondary_location, p_secondary*norm ); glUniform1f( tertiary_location, p_tertiary*norm ); glUniform2f( pixel_location, 1.0/atlas->width, 1.0/atlas->height ); vertex_buffer_render( buffer, GL_TRIANGLES, "vtc" ); glUseProgram( 0 ); } TwDraw( ); glutSwapBuffers( ); } // ---------------------------------------------------------------- reshape --- void reshape( int width, int height ) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, width, 0, height, -1, 1); glMatrixMode(GL_MODELVIEW); TwWindowSize( width, height ); }
// ----------------------------------------------------------- build_buffer --- void build_buffer( void ) { vec2 pen; texture_font_t *font; vec4 black = {{0.0, 0.0, 0.0, 1.0}}; vec4 white = {{1.0, 1.0, 1.0, 1.0}}; vec4 none = {{1.0, 1.0, 1.0, 0.0}}; vec4 color = white; if( p_invert ) { color = black; } markup_t markup = { .family = "Arial", .size = 10.0, .bold = 0, .italic = 0, .rise = 0.0, .spacing = p_interval, .gamma = p_gamma, .foreground_color = color, .background_color = none, .underline = 0, .underline_color = color, .overline = 0, .overline_color = color, .strikethrough = 0, .strikethrough_color = color, .font = 0, }; text_buffer_clear( buffer ); texture_atlas_t * atlas = buffer->manager->atlas; texture_atlas_clear( atlas ); if( p_family == VERA) { font = texture_font_new( atlas, "fonts/Vera.ttf", p_size ); } else if( p_family == VERA_MONO) { font = texture_font_new( atlas, "fonts/VeraMono.ttf", p_size ); } else if( p_family == GEORGIA) { font = texture_font_new( atlas, "fonts/Georgia.ttf", p_size ); } else if( p_family == TIMES ) { font = texture_font_new( atlas, "fonts/Times.ttf", p_size ); } else if( p_family == TAHOMA ) { font = texture_font_new( atlas, "fonts/Tahoma.ttf", p_size ); } else if( p_family == ARIAL ) { font = texture_font_new( atlas, "fonts/Arial.ttf", p_size ); } else if( p_family == VERDANA ) { font = texture_font_new( atlas, "fonts/Verdana.ttf", p_size ); } else { fprintf( stderr, "Error : Unknown family type\n" ); return; } markup.font = font; font->hinting = p_hinting; font->kerning = p_kerning; font->filtering = 1; float norm = 1.0/(p_primary + 2*p_secondary + 2*p_tertiary); font->lcd_weights[0] = (unsigned char)(p_tertiary*norm*256); font->lcd_weights[1] = (unsigned char)(p_secondary*norm*256); font->lcd_weights[2] = (unsigned char)(p_primary*norm*256); font->lcd_weights[3] = (unsigned char)(p_secondary*norm*256); font->lcd_weights[4] = (unsigned char)(p_tertiary*norm*256); pen.x = 10; pen.y = 600 - font->height - 10; text_buffer_printf( buffer, &pen, &markup, text, NULL ); // Post-processing for width and orientation vertex_buffer_t * vbuffer = buffer->buffer; size_t i; for( i=0; i < vector_size( vbuffer->items ); ++i ) { ivec4 *item = (ivec4 *) vector_get( vbuffer->items, i); glyph_vertex_t * v0 = /* x0,y0 */ (glyph_vertex_t *) vector_get( vbuffer->vertices, item->vstart+0 ); //glyph_vertex_t * v1 = /* x0,y1 */ // (glyph_vertex_t *) vector_get( vbuffer->vertices, item->vstart+1 ); glyph_vertex_t * v2 = /* x1,y1 */ (glyph_vertex_t *) vector_get( vbuffer->vertices, item->vstart+2 ); glyph_vertex_t * v3 = /* x1,y0 */ (glyph_vertex_t *) vector_get( vbuffer->vertices, item->vstart+3 ); float x0 = v0->x, y0 = v0->y; float x1 = v2->x, y1 = v2->y; v2->x = v3->x = x0 + (x1-x0)*p_width; float dy = abs(y1-y0); float dx = tan(p_faux_italic/180.0 * M_PI) * dy; v0->x += dx; v0->shift = fmod(v0->shift + dx-(int)(dx),1.0); v3->x += dx; v3->shift = fmod(v3->shift + dx-(int)(dx),1.0); } texture_font_delete( font ); } // ---------------------------------------------------------------- display --- void display(void) { vec4 black = {{0.0, 0.0, 0.0, 1.0}}; vec4 white = {{1.0, 1.0, 1.0, 1.0}}; if( !p_invert ) { glClearColor( 0, 0, 0, 1 ); buffer->base_color = white; } else { glClearColor( 1, 1, 1, 1 ); buffer->base_color = black; } glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glUseProgram( buffer->shader ); { glUniformMatrix4fv( glGetUniformLocation( buffer->shader, "model" ), 1, 0, model.data); glUniformMatrix4fv( glGetUniformLocation( buffer->shader, "view" ), 1, 0, view.data); glUniformMatrix4fv( glGetUniformLocation( buffer->shader, "projection" ), 1, 0, projection.data); text_buffer_render( buffer ); } TwDraw( ); glutSwapBuffers( ); }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { int width = 600; int height = 600; glutInit( &argc, argv ); glutInitWindowSize( width, height ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Freetype OpenGL" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); // GLenum err = glewInit(); // if (GLEW_OK != err) // { // /* Problem: glewInit failed, something is seriously wrong. */ // fprintf( stderr, "Error: %s\n", glewGetErrorString(err) ); // exit( EXIT_FAILURE ); // } // fprintf( stderr, "Using GLEW %s\n", glewGetString(GLEW_VERSION) ); vec4 blue = {{0,0,1,1}}; vec4 black = {{0,0,0,1}}; texture_atlas_t * atlas = texture_atlas_new( 512, 512, 1); texture_font_t * big = texture_font_new( atlas, "fonts/Vera.ttf", 400); texture_font_t * small = texture_font_new( atlas, "fonts/Vera.ttf", 18); texture_font_t * title = texture_font_new( atlas, "fonts/Vera.ttf", 32); text_buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); line_buffer = vertex_buffer_new( "vertex:3f,color:4f" ); point_buffer = vertex_buffer_new( "vertex:3f,color:4f" ); vec2 pen, origin; texture_glyph_t *glyph = texture_font_get_glyph( big, L'g' ); origin.x = width/2 - glyph->offset_x - glyph->width/2; origin.y = height/2 - glyph->offset_y + glyph->height/2; add_text( text_buffer, big, L"g", &black, &origin ); // title pen.x = 50; pen.y = 560; add_text( text_buffer, title, L"Glyph metrics", &black, &pen ); point_t vertices[] = { // Baseline {0.1*width, origin.y, 0, black}, {0.9*width, origin.y, 0, black}, // Top line {0.1*width, origin.y + glyph->offset_y, 0, black}, {0.9*width, origin.y + glyph->offset_y, 0, black}, // Bottom line {0.1*width, origin.y + glyph->offset_y - glyph->height, 0, black}, {0.9*width, origin.y + glyph->offset_y - glyph->height, 0, black}, // Left line at origin {width/2-glyph->offset_x-glyph->width/2, 0.1*height, 0, black}, {width/2-glyph->offset_x-glyph->width/2, 0.9*height, 0, black}, // Left line {width/2 - glyph->width/2, .3*height, 0, black}, {width/2 - glyph->width/2, .9*height, 0, black}, // Right line {width/2 + glyph->width/2, .3*height, 0, black}, {width/2 + glyph->width/2, .9*height, 0, black}, // Right line at origin {width/2-glyph->offset_x-glyph->width/2+glyph->advance_x, 0.1*height, 0, black}, {width/2-glyph->offset_x-glyph->width/2+glyph->advance_x, 0.7*height, 0, black}, // Width {width/2 - glyph->width/2, 0.8*height, 0, blue}, {width/2 + glyph->width/2, 0.8*height, 0, blue}, // Advance_x {width/2-glyph->width/2-glyph->offset_x, 0.2*height, 0, blue}, {width/2-glyph->width/2-glyph->offset_x+glyph->advance_x, 0.2*height, 0, blue}, // Offset_x {width/2-glyph->width/2-glyph->offset_x, 0.85*height, 0, blue}, {width/2-glyph->width/2, 0.85*height, 0, blue}, // Height {0.3*width/2, origin.y + glyph->offset_y - glyph->height, 0, blue}, {0.3*width/2, origin.y + glyph->offset_y, 0, blue}, // Offset y {0.8*width, origin.y + glyph->offset_y, 0, blue}, {0.8*width, origin.y , 0, blue}, }; GLuint indices [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12, 13,14,15,16,17,18,19,20,21,22,23,24,25}; vertex_buffer_push_back( line_buffer, vertices, 26, indices, 26 ); pen.x = width/2 - 48; pen.y = .2*height - 18; add_text( text_buffer, small, L"advance_x", &blue, &pen ); pen.x = width/2 - 20; pen.y = .8*height + 3; add_text( text_buffer, small, L"width", &blue, &pen ); pen.x = width/2 - glyph->width/2 + 5; pen.y = .85*height-8; add_text( text_buffer, small, L"offset_x", &blue, &pen ); pen.x = 0.2*width/2-30; pen.y = origin.y + glyph->offset_y - glyph->height/2; add_text( text_buffer, small, L"height", &blue, &pen ); pen.x = 0.8*width+3; pen.y = origin.y + glyph->offset_y/2 -6; add_text( text_buffer, small, L"offset_y", &blue, &pen ); pen.x = width/2 - glyph->offset_x - glyph->width/2 - 58; pen.y = height/2 - glyph->offset_y + glyph->height/2 - 20; add_text( text_buffer, small, L"Origin", &black, &pen ); GLuint i = 0; point_t p; p.color = black; // Origin point p.x = width/2 - glyph->offset_x - glyph->width/2; p.y = height/2 - glyph->offset_y + glyph->height/2; vertex_buffer_push_back( point_buffer, &p, 1, &i, 1 ); // Advance point p.x = width/2 - glyph->offset_x - glyph->width/2 + glyph->advance_x; p.y = height/2 - glyph->offset_y + glyph->height/2; vertex_buffer_push_back( point_buffer, &p, 1, &i, 1 ); text_shader = shader_load( "shaders/v3f-t2f-c4f.vert", "shaders/v3f-t2f-c4f.frag" ); shader = shader_load( "shaders/v3f-c4f.vert", "shaders/v3f-c4f.frag" ); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); glutMainLoop( ); return 0; }
// ------------------------------------------------------------ console_new --- console_t * console_new( void ) { console_t *self = (console_t *) malloc( sizeof(console_t) ); if( !self ) { return self; } self->lines = vector_new( sizeof(wchar_t *) ); self->prompt = (wchar_t *) wcsdup( L">>> " ); self->cursor = 0; self->buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); self->input[0] = L'\0'; self->killring[0] = L'\0'; self->handlers[__SIGNAL_ACTIVATE__] = 0; self->handlers[__SIGNAL_COMPLETE__] = 0; self->handlers[__SIGNAL_HISTORY_NEXT__] = 0; self->handlers[__SIGNAL_HISTORY_PREV__] = 0; self->pen.x = self->pen.y = 0; texture_atlas_t * atlas = texture_atlas_new( 512, 512, 1 ); vec4 white = {{1,1,1,1}}; vec4 black = {{0,0,0,1}}; vec4 none = {{0,0,1,0}}; markup_t normal; normal.family = "fonts/VeraMono.ttf"; normal.size = 13.0; normal.bold = 0; normal.italic = 0; normal.rise = 0.0; normal.spacing = 0.0; normal.gamma = 1.0; normal.foreground_color = black; normal.background_color = none; normal.underline = 0; normal.underline_color = white; normal.overline = 0; normal.overline_color = white; normal.strikethrough = 0; normal.strikethrough_color = white; normal.font = texture_font_new( atlas, "fonts/VeraMono.ttf", 13 ); markup_t bold = normal; bold.bold = 1; bold.font = texture_font_new( atlas, "fonts/VeraMoBd.ttf", 13 ); markup_t italic = normal; italic.italic = 1; bold.font = texture_font_new( atlas, "fonts/VeraMoIt.ttf", 13 ); markup_t bold_italic = normal; bold.bold = 1; italic.italic = 1; italic.font = texture_font_new( atlas, "fonts/VeraMoBI.ttf", 13 ); markup_t faint = normal; faint.foreground_color.r = 0.35; faint.foreground_color.g = 0.35; faint.foreground_color.b = 0.35; markup_t error = normal; error.foreground_color.r = 1.00; error.foreground_color.g = 0.00; error.foreground_color.b = 0.00; markup_t warning = normal; warning.foreground_color.r = 1.00; warning.foreground_color.g = 0.50; warning.foreground_color.b = 0.50; markup_t output = normal; output.foreground_color.r = 0.00; output.foreground_color.g = 0.00; output.foreground_color.b = 1.00; self->markup[MARKUP_NORMAL] = normal; self->markup[MARKUP_ERROR] = error; self->markup[MARKUP_WARNING] = warning; self->markup[MARKUP_OUTPUT] = output; self->markup[MARKUP_FAINT] = faint; self->markup[MARKUP_BOLD] = bold; self->markup[MARKUP_ITALIC] = italic; self->markup[MARKUP_BOLD_ITALIC] = bold_italic; return self; }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitWindowSize( 512, 512 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Freetype OpenGL" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); size_t i; vec4 black = {{0.0, 0.0, 0.0, 1.0}}; vec4 white = {{1.0, 1.0, 1.0, 1.0}}; vec4 none = {{1.0, 1.0, 1.0, 0.0}}; markup_t markup = { .family = "Bitstream Vera Sans", .size = 15.0, .bold = 0, .italic = 0, .rise = 0.0, .spacing = 0.0, .gamma = 1.5, .foreground_color = white, .background_color = none, .underline = 0, .underline_color = white, .overline = 0, .overline_color = white, .strikethrough = 0, .strikethrough_color = white, .font = 0, }; atlas = texture_atlas_new( 512, 512, 3 ); buffer = vertex_buffer_new( "v3f:t2f:c4f:1g1f:2g1f" ); markup.font = texture_font_new( atlas, "./Vera.ttf", markup.size ); vec2 pen; pen.y = 512.0 - markup.font->ascender - 5; for( i=0; i < 14; ++i ) { pen.x = 25.0; markup.gamma = 0.75 + 1.5*i*(1.0/14); add_text( buffer, &pen, &markup, L"The quick brown fox jumps over the lazy dog. ", &markup, L"0123456789.", NULL); pen.y -= markup.font->height; } markup.foreground_color = black; pen.y = 256.0 - markup.font->ascender - 5; for( i=0; i < 14; ++i ) { pen.x = 25.0; markup.gamma = 0.75 + 1.5*i*(1.0/14); add_text( buffer, &pen, &markup, L"The quick brown fox jumps over the lazy dog. ", &markup, L"0123456789.", NULL); pen.y -= markup.font->height; } // Create the GLSL program char * vertex_shader_source = read_shader("./markup.vert"); char * fragment_shader_source = read_shader("./markup.frag"); program = build_program( vertex_shader_source, fragment_shader_source ); texture_location = glGetUniformLocation(program, "texture"); pixel_location = glGetUniformLocation(program, "pixel"); glutMainLoop( ); return 0; }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { size_t i; size_t width = 600, height = 250; glutInit( &argc, argv ); glutInitWindowSize( width, height ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Glyph Outline" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); // GLenum err = glewInit(); // if (GLEW_OK != err) // { // /* Problem: glewInit failed, something is seriously wrong. */ // fprintf( stderr, "Error: %s\n", glewGetErrorString(err) ); // exit( EXIT_FAILURE ); // } // fprintf( stderr, "Using GLEW %s\n", glewGetString(GLEW_VERSION) ); atlas = texture_atlas_new( 512, 512, 1 ); buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); vec4 white = {{1.0, 1.0, 1.0, 1.0}}; vec4 none = {{1.0, 1.0, 1.0, 0.0}}; markup_t markup; markup.family = "fonts/Vera.ttf"; markup.size = 80.0; markup.bold = 0; markup.italic = 0; markup.rise = 0.0; markup.spacing = 0.0; markup.gamma = 1.5; markup.foreground_color = white; markup.background_color = none; markup.underline = 0; markup.underline_color = white; markup.overline = 0; markup.overline_color = white; markup.strikethrough = 0; markup.strikethrough_color = white; markup.font = 0; markup.font = texture_font_new( atlas, "fonts/Vera.ttf", markup.size ); markup.font->outline_type = 1; vec2 pen; pen.x = 40; pen.y = 190; for( i=0; i< 10; ++i) { markup.font->outline_thickness = 2*((i+1)/10.0); add_text( buffer, &pen, &markup, L"g", NULL ); } pen.x = 40; pen.y = 110; markup.font->outline_type = 2; for( i=0; i< 10; ++i) { markup.font->outline_thickness = 2*((i+1)/10.0); add_text( buffer, &pen, &markup, L"g", NULL ); } pen.x = 40; pen.y = 30; markup.font->outline_type = 3; for( i=0; i< 10; ++i) { markup.font->outline_thickness = 1*((i+1)/10.0); add_text( buffer, &pen, &markup, L"g", NULL ); } shader = shader_load("shaders/v3f-t2f-c4f.vert", "shaders/v3f-t2f-c4f.frag"); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); glutMainLoop( ); return 0; }
// ------------------------------------------------------------------- main --- int main_texture( int argc, char **argv ) { glutInit( &argc, argv ); glutInitWindowSize( 512, 512 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( argv[0] ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); // GLenum err = glewInit(); // if (GLEW_OK != err) // { // /* Problem: glewInit failed, something is seriously wrong. */ // fprintf( stderr, "Error: %s\n", glewGetErrorString(err) ); // exit( EXIT_FAILURE ); // } // fprintf( stderr, "Using GLEW %s\n", glewGetString(GLEW_VERSION) ); texture_atlas_t * atlas = texture_atlas_new( 512, 512, 1 ); // const char *filename = "/Users/jie/svn/v8/deps/freetype-gl-read-only/fonts/Vera.ttf"; const char *filename = "/Users/jie/svn/v8/deps/freetype-gl-read-only/fonts/fat.ttf"; // const wchar_t *cache = L" !\"#$%&'()*+,-./0123456789:;<=>?" // L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" // L"`abcdefghijklmnopqrstuvwxyz{|}~"; wchar_t unicode[6]; unicode[0] = 22909; unicode[1] = 20320; unicode[2] = 25438; unicode[3] = 28156; unicode[4] = 48; unicode[5] = 0; wchar_t* cache = (wchar_t*)unicode; printf("%d %d\n", cache[0], wcslen(cache)); size_t minsize = 20, maxsize = 40; size_t count = maxsize - minsize; size_t i, missed = 0; for( i=minsize; i < maxsize; ++i ) { texture_font_t * font = texture_font_new( atlas, filename, i ); missed += texture_font_load_glyphs( font, cache ); texture_font_delete( font ); } printf( "Matched font : %s\n", filename ); printf( "Number of fonts : %ld\n", count ); printf( "Number of glyphs per font : %ld\n", wcslen(cache) ); printf( "Number of missed glyphs : %ld\n", missed ); printf( "Total number of glyphs : %ld/%ld\n", wcslen(cache)*count - missed, wcslen(cache)*count ); printf( "Texture size : %ldx%ld\n", atlas->width, atlas->height ); printf( "Texture occupancy : %.2f%%\n", 100.0*atlas->used/(float)(atlas->width*atlas->height) ); glClearColor(1,1,1,1); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glEnable( GL_TEXTURE_2D ); glBindTexture( GL_TEXTURE_2D, atlas->id ); typedef struct { float x,y,z, u,v, r,g,b,a; } vertex_t; vertex_t vertices[4] = { { 0, 0, 0, 0,1, 0,0,0,1}, { 0, 512,0, 0,0, 0,0,0,1}, { 512,512,0, 1,0, 0,0,0,1}, { 512, 0,0, 1,1, 0,0,0,1} }; GLuint indices[6] = { 0,1,2, 0,2,3 }; buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); vertex_buffer_push_back( buffer, vertices, 4, indices, 6 ); shader = shader_load("/Users/jie/svn/v8/deps/freetype-gl-read-only/shaders/v3f-t2f-c4f.vert", "/Users/jie/svn/v8/deps/freetype-gl-read-only/shaders/v3f-t2f-c4f.frag"); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); glutMainLoop( ); return 0; }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { size_t i, j; wchar_t * font_cache = L" !\"#$%&'()*+,-./0123456789:;<=>?" L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" L"`abcdefghijklmnopqrstuvwxyz{|}~"; float font_size = 16.0; char * font_filename = "fonts/Arial.ttf"; char * header_filename = "arial-16.h"; texture_atlas_t * atlas = texture_atlas_new( 128, 128, 1 ); texture_font_t * font = texture_font_new( atlas, font_filename, font_size ); glutInit( &argc, argv ); glutInitWindowSize( atlas->width, atlas->height ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Freetype OpenGL" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); size_t missed = texture_font_load_glyphs( font, font_cache ); wprintf( L"Font filename : %s\n", font_filename ); wprintf( L"Font size : %.1f\n", font_size ); wprintf( L"Number of glyphs : %ld\n", wcslen(font_cache) ); wprintf( L"Number of missed glyphs : %ld\n", missed ); wprintf( L"Texture size : %ldx%ldx%ld\n", atlas->width, atlas->height, atlas->depth ); wprintf( L"Texture occupancy : %.2f%%\n", 100.0*atlas->used/(float)(atlas->width*atlas->height) ); wprintf( L"\n" ); wprintf( L"Header filename : %s\n", header_filename ); size_t texture_size = atlas->width * atlas->height *atlas->depth; size_t glyph_count = font->glyphs->size; size_t max_kerning_count = 1; for( i=0; i < glyph_count; ++i ) { texture_glyph_t *glyph = *(texture_glyph_t **) vector_get( font->glyphs, i ); if( vector_size(glyph->kerning) > max_kerning_count ) { max_kerning_count = vector_size(glyph->kerning); } } FILE *file = fopen( header_filename, "w" ); // ------------- // Header // ------------- fwprintf( file, L"/* ============================================================================\n" L" * Freetype GL - A C OpenGL Freetype engine\n" L" * Platform: Any\n" L" * WWW: http://code.google.com/p/freetype-gl/\n" L" * ----------------------------------------------------------------------------\n" L" * Copyright 2011,2012 Nicolas P. Rougier. All rights reserved.\n" L" *\n" L" * Redistribution and use in source and binary forms, with or without\n" L" * modification, are permitted provided that the following conditions are met:\n" L" *\n" L" * 1. Redistributions of source code must retain the above copyright notice,\n" L" * this list of conditions and the following disclaimer.\n" L" *\n" L" * 2. Redistributions in binary form must reproduce the above copyright\n" L" * notice, this list of conditions and the following disclaimer in the\n" L" * documentation and/or other materials provided with the distribution.\n" L" *\n" L" * THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR\n" L" * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n" L" * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n" L" * EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\n" L" * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n" L" * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n" L" * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n" L" * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" L" * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n" L" * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" L" *\n" L" * The views and conclusions contained in the software and documentation are\n" L" * those of the authors and should not be interpreted as representing official\n" L" * policies, either expressed or implied, of Nicolas P. Rougier.\n" L" * ===============================================================================\n" L" */\n"); // ---------------------- // Structure declarations // ---------------------- fwprintf( file, L"#include <stddef.h>\n" L"#ifdef __cplusplus\n" L"extern \"C\" {\n" L"#endif\n" L"\n" L"typedef struct\n" L"{\n" L" wchar_t charcode;\n" L" float kerning;\n" L"} kerning_t;\n\n" ); fwprintf( file, L"typedef struct\n" L"{\n" L" wchar_t charcode;\n" L" int width, height;\n" L" int offset_x, offset_y;\n" L" float advance_x, advance_y;\n" L" float s0, t0, s1, t1;\n" L" size_t kerning_count;\n" L" kerning_t kerning[%d];\n" L"} texture_glyph_t;\n\n", max_kerning_count ); fwprintf( file, L"typedef struct\n" L"{\n" L" size_t tex_width;\n" L" size_t tex_height;\n" L" size_t tex_depth;\n" L" char tex_data[%d];\n" L" float size;\n" L" float height;\n" L" float linegap;\n" L" float ascender;\n" L" float descender;\n" L" size_t glyphs_count;\n" L" texture_glyph_t glyphs[%d];\n" L"} texture_font_t;\n\n", texture_size, glyph_count ); fwprintf( file, L"texture_font_t font = {\n" ); // ------------ // Texture data // ------------ fwprintf( file, L" %d, %d, %d, \n", atlas->width, atlas->height, atlas->depth ); fwprintf( file, L" {" ); for( i=0; i < texture_size; i+= 32 ) { for( j=0; j < 32 && (j+i) < texture_size ; ++ j) { if( (j+i) < (texture_size-1) ) { fwprintf( file, L"%d,", atlas->data[i+j] ); } else { fwprintf( file, L"%d", atlas->data[i+j] ); } } if( (j+i) < texture_size ) { fwprintf( file, L"\n " ); } } fwprintf( file, L"}, \n" ); // ------------------- // Texture information // ------------------- fwprintf( file, L" %ff, %ff, %ff, %ff, %ff, %d, \n", font->size, font->height, font->linegap,font->ascender, font->descender, glyph_count ); // -------------- // Texture glyphs // -------------- fwprintf( file, L" {\n" ); for( i=0; i < glyph_count; ++i ) { texture_glyph_t * glyph = *(texture_glyph_t **) vector_get( font->glyphs, i ); /* // Debugging information wprintf( L"glyph : '%lc'\n", glyph->charcode ); wprintf( L" size : %dx%d\n", glyph->width, glyph->height ); wprintf( L" offset : %+d%+d\n", glyph->offset_x, glyph->offset_y ); wprintf( L" advance : %ff, %ff\n", glyph->advance_x, glyph->advance_y ); wprintf( L" tex coords.: %ff, %ff, %ff, %ff\n", glyph->u0, glyph->v0, glyph->u1, glyph->v1 ); wprintf( L" kerning : " ); if( glyph->kerning_count ) { for( j=0; j < glyph->kerning_count; ++j ) { wprintf( L"('%lc', %ff)", glyph->kerning[j].charcode, glyph->kerning[j].kerning ); if( j < (glyph->kerning_count-1) ) { wprintf( L", " ); } } } else { wprintf( L"None" ); } wprintf( L"\n\n" ); */ // TextureFont if( (glyph->charcode == L'\'' ) || (glyph->charcode == L'\\' ) ) { fwprintf( file, L" {L'\\%lc', ", glyph->charcode ); //wprintf( L" {L'\\%lc', ", glyph->charcode ); } else if( glyph->charcode == (wchar_t)(-1) ) { fwprintf( file, L" {L'\\0', " ); //wprintf( L" {L'\\0', " ); } else { fwprintf( file, L" {L'%lc', ", glyph->charcode ); //wprintf( L" {L'%lc', ", glyph->charcode ); } fwprintf( file, L"%d, %d, ", glyph->width, glyph->height ); fwprintf( file, L"%d, %d, ", glyph->offset_x, glyph->offset_y ); fwprintf( file, L"%ff, %ff, ", glyph->advance_x, glyph->advance_y ); fwprintf( file, L"%ff, %ff, %ff, %ff, ", glyph->s0, glyph->t0, glyph->s1, glyph->t1 ); fwprintf( file, L"%d, ", vector_size(glyph->kerning) ); fwprintf( file, L"{ " ); for( j=0; j < vector_size(glyph->kerning); ++j ) { kerning_t *kerning = (kerning_t *) vector_get( glyph->kerning, j); wchar_t charcode = kerning->charcode; if( (charcode == L'\'' ) || (charcode == L'\\') ) { fwprintf( file, L"{L'\\%lc', %ff}", charcode, kerning->kerning ); } else if( (charcode != (wchar_t)(-1) ) ) { fwprintf( file, L"{L'%lc', %ff}", charcode, kerning->kerning ); } if( j < (vector_size(glyph->kerning)-1)) { fwprintf( file, L", " ); } } fwprintf( file, L"} },\n" ); } fwprintf( file, L" }\n};\n" ); fwprintf( file, L"#ifdef __cplusplus\n" L"}\n" L"#endif\n" ); return 0; }