// ------------------------------------------------------------------- init --- void init( void ) { atlas = texture_atlas_new( 512, 512, 1 ); auto filename = "fonts/Vera.ttf"; auto text = "A Quick Brown Fox Jumps Over The Lazy Dog 0123456789"; buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); vec2 pen = {0,0}; auto black = vec4{1,1,1,1}; auto font = texture_font_new_from_file( atlas, 48, filename ); font->rendermode = RENDER_SIGNED_DISTANCE_FIELD; auto bbox = add_text( buffer, font, text, &black, &pen ); size_t i; auto vertices = buffer->vertices; for( i=0; i< vector_size(vertices); ++i ) { auto vert = (vertex *) vector_get(vertices,i); vert->x -= (int)(bbox.x + bbox.width/2); vert->y -= (int)(bbox.y + bbox.height/2); } glGenTextures( 1, &atlas->id ); glBindTexture( GL_TEXTURE_2D, atlas->id ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); 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_RED, atlas->width, atlas->height, 0, GL_RED, GL_UNSIGNED_BYTE, atlas->data ); shader = shader_load( "shaders/distance-field-2v5.vert", "shaders/distance-field-2v5.frag" ); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); }
bool FontRenderer::InitFontRenderer() { m_pManager = font_manager_new( 512, 512, 1 ); if (!m_pManager) { fprintf(stderr, "%s:%d - error initializing the font manager\n", __FILE__, __LINE__); return false; } m_pFont = font_manager_get_from_markup( m_pManager, &markup ); if (!m_pFont) { fprintf(stderr, "%s:%d - error getting the font\n", __FILE__, __LINE__); return false; } m_pTextBuffer = vertex_buffer_new( "v3f:t2f:c4f" ); if (!m_pTextBuffer) { fprintf(stderr, "%s:%d - error creating the text buffer\n", __FILE__, __LINE__); return false; } if (!m_fontShader.InitFontShader()) { fprintf(stderr, "%s:%d - error compiling the shader program\n", __FILE__, __LINE__); return false; } m_fontShader.Enable(); m_fontShader.SetFontMapTextureUnit(0); return true; }
// ------------------------------------------------------------------- init --- void init( void ) { glClearColor( 1.0f, 1.0f, 1.0f, 1.0f ); glDisable( GL_DEPTH_TEST ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); // Make program program = build_program( vertex_shader_source, fragment_shader_source ); //GLuint attrib = glGetAttribLocation(program, "thickness"); //printf("%d\n", attrib); // Make lines lines = vertex_buffer_new( "v2f:t2f:c4f:1g1f" ); float r=0.0f, g=0.0f, b=0.0f, a=1.0f; size_t i; for( i=0; i<57; ++i) { float thickness = (i+1)*0.2; float x0 = 2+i*10+0.315; float y0 = 5+0.315; float x1 = 35+i*10+0.315; float y1 = 170+0.315; make_segment(lines, x0,y0, x1,y1, thickness, r,g,b,a); } }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH ); glutInitWindowSize( 256, 256) ; glutCreateWindow( argv[0] ); glutDisplayFunc( display ); glutReshapeFunc( reshape ); glutKeyboardFunc( keyboard ); buffer = vertex_buffer_new( "v3f:c4f:t3f" ); program = shader_load( "shaders/line-aa.vert", "shaders/line-aa-round.frag" ); size_t n = 20, i; vec4 color = {{0,0,0,1}}; for (i = 0; i < n; ++i) { float x0 = 30; float y0 = 230 - i*10; float thickness = (i+1)/10.0; vec2 points[] = { {{ x0+ 0, y0+10 }}, {{x0+ 40, y0-10 }}, {{ x0+ 80, y0+10 }}, {{ x0+120, y0-10 }}, {{ x0+160, y0+10 }}, {{ x0+200, y0-10 }} }; vertex_buffer_add_polyline( buffer, points, 6, color, thickness, round_join, round_cap); } glutMainLoop(); return 0; }
// ------------------------------------------------------------------- init --- void init( void ) { atlas = texture_atlas_new( 512, 512, 1 ); font = texture_font_new_from_file( atlas, 32, "../media/fonts/Vera.ttf" ); 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( "../media/fonts/Vera.ttf", "@", 512, 64, 0.1); vector_push_back( font->glyphs, &glyph ); texture_atlas_upload( atlas ); glyph = texture_font_get_glyph( font, "@"); GLuint indices[6] = {0,1,2, 0,2,3}; vertex_t vertices[4] = { { -.5,-.5,0, glyph->s0,glyph->t1, 0,0,0,1 }, { -.5, .5,0, glyph->s0,glyph->t0, 0,0,0,1 }, { .5, .5,0, glyph->s1,glyph->t0, 0,0,0,1 }, { .5,-.5,0, glyph->s1,glyph->t1, 0,0,0,1 } }; buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); vertex_buffer_push_back( buffer, vertices, 4, indices, 6 ); program = shader_load( "../media/shaders/distance-field.vert", "../media/shaders/distance-field-2.frag" ); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); }
// ------------------------------------------------------------------- init --- void init( void ) { size_t i; vec2 pen = {{0,0}}; vec4 color = {{0,0,0,1}}; atlas = texture_atlas_new( 512, 512, 1 ); font = texture_font_new_from_file( atlas, 12, "../media/fonts/VeraMono.ttf" ); 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("../media/shaders/v3f-t2f-c4f.vert", "../media/shaders/v3f-t2f-c4f.frag"); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); }
// ------------------------------------------------------------------- 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; }
text_buffer_t * text_buffer_new_with_program( size_t depth, GLuint program ) { text_buffer_t *self = (text_buffer_t *) malloc (sizeof(text_buffer_t)); self->buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f,ashift:1f,agamma:1f" ); self->manager = font_manager_new( 512, 512, depth ); self->shader = program; self->shader_texture = glGetUniformLocation(self->shader, "tex"); self->shader_pixel = glGetUniformLocation(self->shader, "pixel"); self->line_start = 0; self->line_ascender = 0; self->base_color.r = 0.0; self->base_color.g = 0.0; self->base_color.b = 0.0; self->base_color.a = 1.0; self->line_descender = 0; self->lines = vector_new( sizeof(line_info_t) ); self->bounds.left = 0.0; self->bounds.top = 0.0; self->bounds.width = 0.0; self->bounds.height = 0.0; return self; }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitWindowSize( 800, 600 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( "Signed Distance Field" ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); #ifndef __APPLE__ glewExperimental = GL_TRUE; 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) ); #endif texture_font_t *font = 0; texture_atlas_t *atlas = texture_atlas_new( 512, 512, 1 ); 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" ); vec2 pen = {{0,0}}; vec4 black = {{1,1,1,1}}; font = texture_font_new_from_file( atlas, 48, filename ); vec4 bbox = add_text( buffer, font, text, &black, &pen ); size_t i; vector_t * vertices = buffer->vertices; for( i=0; i< vector_size(vertices); ++i ) { vertex_t * vertex = (vertex_t *) vector_get(vertices,i); vertex->x -= (int)(bbox.x + bbox.width/2); vertex->y -= (int)(bbox.y + bbox.height/2); } glBindTexture( GL_TEXTURE_2D, atlas->id ); fprintf( stderr, "Generating distance map...\n" ); unsigned char *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 ); shader = shader_load( "shaders/distance-field-2.vert", "shaders/distance-field-2.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 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_from_file( atlas, 128, "fonts/ObelixPro.ttf" ); 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; }
// ------------------------------------------------------------------- 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; }
shader_group_t* shader_group_new(const shader_t* program, const vertex_buffer_t* buff, const char* name, int z, struct tex_group_t* tg, struct blend_group_t* bg) { struct_malloc(shader_group_t, self); self->program = program; self->name = sen_strdup(name); self->buff = vertex_buffer_new(vertex_buffer_format(buff)); self->num = 0; self->z = z; self->tg = tg; self->bg = bg; return self; }
// ------------------------------------------------------------------- main --- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitWindowSize( 400, 400 ); glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutCreateWindow( argv[0] ); glutReshapeFunc( reshape ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); //glutTimerFunc( 1000/60, timer, 1000/60 ); // not working on some systems (bug in GLUT) glutIdleFunc(display); glewExperimental = GL_TRUE; 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) ); typedef struct { float x,y,z;} xyz; typedef struct { float r,g,b,a;} rgba; typedef struct { xyz position, normal; rgba color;} vertex; xyz v[] = { { 1, 1, 1}, {-1, 1, 1}, {-1,-1, 1}, { 1,-1, 1}, { 1,-1,-1}, { 1, 1,-1}, {-1, 1,-1}, {-1,-1,-1} }; xyz n[] = { { 0, 0, 1}, { 1, 0, 0}, { 0, 1, 0} , {-1, 0, 1}, { 0,-1, 0}, { 0, 0,-1} }; rgba c[] = { {1, 1, 1, 1}, {1, 1, 0, 1}, {1, 0, 1, 1}, {0, 1, 1, 1}, {1, 0, 0, 1}, {0, 0, 1, 1}, {0, 1, 0, 1}, {0, 0, 0, 1} }; vertex vertices[24] = { {v[0],n[0],c[0]}, {v[1],n[0],c[1]}, {v[2],n[0],c[2]}, {v[3],n[0],c[3]}, {v[0],n[1],c[0]}, {v[3],n[1],c[3]}, {v[4],n[1],c[4]}, {v[5],n[1],c[5]}, {v[0],n[2],c[0]}, {v[5],n[2],c[5]}, {v[6],n[2],c[6]}, {v[1],n[2],c[1]}, {v[1],n[3],c[1]}, {v[6],n[3],c[6]}, {v[7],n[3],c[7]}, {v[2],n[3],c[2]}, {v[7],n[4],c[7]}, {v[4],n[4],c[4]}, {v[3],n[4],c[3]}, {v[2],n[4],c[2]}, {v[4],n[5],c[4]}, {v[7],n[5],c[7]}, {v[6],n[5],c[6]}, {v[5],n[5],c[5]} }; GLuint indices[24] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, 12,13,14,15, 16,17,18,19, 20,21,22,23 }; cube = vertex_buffer_new( "vertex:3f,normal:3f,color:4f" ); vertex_buffer_push_back( cube, vertices, 24, indices, 24 ); shader = shader_load("shaders/cube.vert","shaders/cube.frag"); init( ); glutMainLoop( ); return EXIT_SUCCESS; }
// ------------------------------------------------------------------- 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 ); glewExperimental = GL_TRUE; 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_from_file( atlas, i, filename ); 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; }
struct render* render_new() { struct render* r = STRUCT_NEW(render); r->cur_program = 0; r->cur_tex_id = 0; r->vertex_buffer = vertex_buffer_new(); r->render_state = 0; r->shader = shader_new(); r->scissors.x = 0; r->scissors.y = 0; r->scissors.width = GAME->config.window_width; r->scissors.width = GAME->config.window_height; r->drawcall = 0; return r; }
text_buffer_t *text_buffer_new( GLuint shader, const ivec2 *size, int depth ) { text_buffer_t *self = (text_buffer_t *) malloc (sizeof(text_buffer_t)); self->buffer = vertex_buffer_new( "v3f:t2f:c4f:1g1f:2g1f" ); glyph_cache_init( &self->cache, size, depth ); self->shader = shader; self->shader_texture = glGetUniformLocation(self->shader, "texture"); self->shader_pixel = glGetUniformLocation(self->shader, "pixel"); self->line_start = 0; self->line_ascender = 0; self->line_descender = 0; return self; }
// ---------------------------------------------------------------------------- text_buffer_t * text_buffer_new( size_t depth ) { text_buffer_t *self = (text_buffer_t *) malloc (sizeof(text_buffer_t)); self->buffer = vertex_buffer_new( "v3f:t2f:c4f:1g1f:2g1f" ); self->manager = font_manager_new( 512, 512, depth ); self->shader = shader_load("shaders/text.vert", "shaders/text.frag"); self->shader_texture = glGetUniformLocation(self->shader, "texture"); self->shader_pixel = glGetUniformLocation(self->shader, "pixel"); self->line_start = 0; self->line_ascender = 0; self->line_descender = 0; return self; }
// ---------------------------------------------------------------------------- text_buffer_t * text_buffer_new( size_t depth ) { text_buffer_t *self = (text_buffer_t *) malloc (sizeof(text_buffer_t)); self->buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f,ashift:1f,agamma:1f" ); self->manager = font_manager_new( 512, 512, depth ); self->shader = shader_load("shaders/text.vert", "shaders/text.frag"); self->shader_texture = glGetUniformLocation(self->shader, "texture"); self->shader_pixel = glGetUniformLocation(self->shader, "pixel"); self->line_start = 0; self->line_ascender = 0; self->line_descender = 0; return self; }
// ---------------------------------------------------------------------------- vertex_buffer_t * vertex_buffer_new_from_data( const char *format, size_t vcount, void *vertices, size_t icount, GLuint *indices ) { vertex_buffer_t *self = vertex_buffer_new( format ); vector_resize( self->vertices, vcount ); assert( self->vertices->size == vcount); memcpy( self->vertices->items, vertices, vcount*self->vertices->item_size ); vector_resize( self->indices, icount ); assert( self->indices->size == icount); memcpy( self->indices->items, indices, icount*self->indices->item_size ); self->dirty = 1; return self; }
void FontBufferCache::Add(const std::string &text, const Point3 &position, const GameColor &color, texture_font_t *font) { HashedString hash(text.c_str()); vertex_buffer_t *buffer = 0; if(Contains(text)) { buffer = m_vertexBufferMap.find(hash.getHashValue())->second; vertex_buffer_clear(buffer); } else { buffer = vertex_buffer_new("vertex:3f,tex_coord:2f,color:4f"); m_vertexBufferMap[hash.getHashValue()] = buffer; } F32 r = color.GetX(), g = color.GetY(), b = color.GetZ(), a = color.GetW(); F32 x = 0.0f; U32 size = (U32)text.size(); for(U32 i = 0; i < size; ++i) { texture_glyph_t *glyph = texture_font_get_glyph(font, text[i]); if(glyph != NULL) { I32 kerning = 0; if(i > 0) { kerning = texture_glyph_get_kerning(glyph, text[i - 1]); } x += (float)kerning; F32 x0 = (F32)(position.GetX() + x + glyph->offset_x); F32 y0 = (F32)(position.GetY() + glyph->offset_y); F32 x1 = (F32)(x0 + glyph->width); F32 y1 = (F32)(y0 - glyph->height); F32 s0 = glyph->s0; F32 t0 = glyph->t0; F32 s1 = glyph->s1; F32 t1 = glyph->t1; GLuint indices[6] = {0, 1, 2, 0, 2, 3}; vertex_t vertices[4] = { { x0, y0, 0.0f, s0, t0, r, g, b, a }, { x0, y1, 0.0f, s0, t1, r, g, b, a }, { x1, y1, 0.0f, s1, t1, r, g, b, a }, { x1, y0, 0.0f, s1, t0, r, g, b, a } }; vertex_buffer_push_back(buffer, vertices, 4, indices, 6); x += glyph->advance_x; } } }
// ------------------------------------------------------------------- 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; }
// ------------------------------------------------------------------- init --- void init( void ) { 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_from_file( atlas, 128, "fonts/LuckiestGuy.ttf" ); 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->rendermode = RENDER_OUTLINE_POSITIVE; font->outline_thickness = 7; add_text( buffer, font, "Freetype GL", pen, black, black ); font->rendermode = RENDER_OUTLINE_POSITIVE; font->outline_thickness = 5; add_text( buffer, font, "Freetype GL", pen, yellow, yellow ); font->rendermode = RENDER_OUTLINE_EDGE; font->outline_thickness = 3; add_text( buffer, font, "Freetype GL", pen, black, black ); font->rendermode = RENDER_NORMAL; font->outline_thickness = 0; add_text( buffer, font, "Freetype GL", pen, orange1, orange2 ); glGenTextures( 1, &atlas->id ); glBindTexture( GL_TEXTURE_2D, atlas->id ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); 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_RED, atlas->width, atlas->height, 0, GL_RED, GL_UNSIGNED_BYTE, atlas->data ); 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 ); }
sprite_t* sen_sprite_new(const char* name, const char* texture_name) { // _logfi("+sprite %s, texture=%s", (name ? name : "autoName"), texture_name); struct_malloc(sprite_t, self); sen_node_init(self, name, 0); self->tex = sen_textures_get(texture_name); sen_assert(self->tex); self->program = sen_shaders_get("sprite"); sen_assert(self->program); self->quad = vertex_buffer_new("a_pos:4f,a_tex_coords:2f,a_color:4f"); //update_quad(self); update_buffer(self); ((node_t*)self)->vt = &sprite_interface; return self; }
Font::Font(const char* filepath, int size) : m_font(NULL), m_atlas(NULL), m_buffer(NULL), m_textureAtlas(NULL), m_color(Color::White), m_currentSize(size) { REQUIRES(filepath) CLFileImporter fileImporter; m_fontFile = fileImporter.LoadFile(filepath); REQUIRES(m_fontFile->m_buffer && m_fontFile->m_bufLength > 0) m_buffer = vertex_buffer_new("vertex:3f,tex_coord:2f,color:4f"); ResizeFont(size); if(!m_glProgram) m_glProgram = new GLProgram("Data/Shaders/FontShader.vert", "Data/Shaders/FontShader.frag"); }
// ------------------------------------------------------------------- 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 ) { 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; }
// ------------------------------------------------------------------- init --- void init( void ) { texture_font_t *font = 0; texture_atlas_t *atlas = texture_atlas_new( 512, 512, 1 ); const char * filename = "fonts/Vera.ttf"; char *text = "A Quick Brown Fox Jumps Over The Lazy Dog 0123456789"; buffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,color:4f" ); vec2 pen = {{0,0}}; vec4 black = {{1,1,1,1}}; font = texture_font_new_from_file( atlas, 48, filename ); vec4 bbox = add_text( buffer, font, text, &black, &pen ); texture_atlas_upload( font->atlas ); size_t i; vector_t * vertices = buffer->vertices; for( i=0; i< vector_size(vertices); ++i ) { vertex_t * vertex = (vertex_t *) vector_get(vertices,i); vertex->x -= (int)(bbox.x + bbox.width/2); vertex->y -= (int)(bbox.y + bbox.height/2); } glBindTexture( GL_TEXTURE_2D, atlas->id ); fprintf( stderr, "Generating distance map...\n" ); unsigned char *map = make_distance_mapb(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 ); shader = shader_load( "shaders/distance-field.vert", "shaders/distance-field-2.frag" ); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); }
// ------------------------------------------------------------------- init --- void init( void ) { typedef struct { float x,y,z;} xyz; typedef struct { float r,g,b,a;} rgba; typedef struct { xyz position, normal; rgba color;} vertex; xyz v[] = { { 1, 1, 1}, {-1, 1, 1}, {-1,-1, 1}, { 1,-1, 1}, { 1,-1,-1}, { 1, 1,-1}, {-1, 1,-1}, {-1,-1,-1} }; xyz n[] = { { 0, 0, 1}, { 1, 0, 0}, { 0, 1, 0} , {-1, 0, 1}, { 0,-1, 0}, { 0, 0,-1} }; rgba c[] = { {1, 1, 1, 1}, {1, 1, 0, 1}, {1, 0, 1, 1}, {0, 1, 1, 1}, {1, 0, 0, 1}, {0, 0, 1, 1}, {0, 1, 0, 1}, {0, 0, 0, 1} }; vertex vertices[24] = { {v[0],n[0],c[0]}, {v[1],n[0],c[1]}, {v[2],n[0],c[2]}, {v[3],n[0],c[3]}, {v[0],n[1],c[0]}, {v[3],n[1],c[3]}, {v[4],n[1],c[4]}, {v[5],n[1],c[5]}, {v[0],n[2],c[0]}, {v[5],n[2],c[5]}, {v[6],n[2],c[6]}, {v[1],n[2],c[1]}, {v[1],n[3],c[1]}, {v[6],n[3],c[6]}, {v[7],n[3],c[7]}, {v[2],n[3],c[2]}, {v[7],n[4],c[7]}, {v[4],n[4],c[4]}, {v[3],n[4],c[3]}, {v[2],n[4],c[2]}, {v[4],n[5],c[4]}, {v[7],n[5],c[7]}, {v[6],n[5],c[6]}, {v[5],n[5],c[5]} }; GLuint indices[24] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, 12,13,14,15, 16,17,18,19, 20,21,22,23 }; cube = vertex_buffer_new( "vertex:3f,normal:3f,color:4f" ); vertex_buffer_push_back( cube, vertices, 24, indices, 24 ); shader = shader_load("../media/shaders/cube.vert","../media/shaders/cube.frag"); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); glPolygonOffset( 1, 1 ); glClearColor( 1.0, 1.0, 1.0, 1.0 ); glEnable( GL_DEPTH_TEST ); glEnable( GL_COLOR_MATERIAL ); glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glEnable( GL_LINE_SMOOTH ); }
// ------------------------------------------------------------------- init --- void init( void ) { size_t i; texture_font_t *font = 0; atlas = texture_atlas_new( 512, 512, 3 ); const char * filename = "fonts/Vera.ttf"; char * text = "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_from_file( atlas, i, filename ); pen.x = 0; pen.y -= font->height; texture_font_load_glyphs( font, text ); add_text( buffer, font, text, &color, &pen ); texture_font_delete( font ); } glGenTextures( 1, &atlas->id ); glBindTexture( GL_TEXTURE_2D, atlas->id ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); 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_RGB, atlas->width, atlas->height, 0, GL_RGB, GL_UNSIGNED_BYTE, atlas->data ); shader = shader_load( "shaders/text.vert", "shaders/text.frag" ); mat4_set_identity( &projection ); mat4_set_identity( &model ); mat4_set_identity( &view ); }
// ------------------------------------------------------------------- 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; }