示例#1
0
// ----------------------------------------------------- console_add_glyph ---
void
console_add_glyph( console_t *self,
                   wchar_t current,
                   wchar_t previous,
                   markup_t *markup )
{
    texture_glyph_t *glyph  = texture_font_get_glyph( markup->font, current );
    if( previous != L'\0' )
    {
        self->pen.x += texture_glyph_get_kerning( glyph, previous );
    }
    float r = markup->foreground_color.r;
    float g = markup->foreground_color.g;
    float b = markup->foreground_color.b;
    float a = markup->foreground_color.a;
    int x0  = self->pen.x + glyph->offset_x;
    int y0  = self->pen.y + glyph->offset_y;
    int x1  = x0 + glyph->width;
    int y1  = y0 - glyph->height;
    float s0 = glyph->s0;
    float t0 = glyph->t0;
    float s1 = glyph->s1;
    float t1 = glyph->t1;

    GLuint indices[] = {0,1,2, 0,2,3};
    vertex_t vertices[] = { { x0,y0,0,  s0,t0,  r,g,b,a },
                            { x0,y1,0,  s0,t1,  r,g,b,a },
                            { x1,y1,0,  s1,t1,  r,g,b,a },
                            { x1,y0,0,  s1,t0,  r,g,b,a } };
    vertex_buffer_push_back( self->buffer, vertices, 4, indices, 6 );

    self->pen.x += glyph->advance_x;
    self->pen.y += glyph->advance_y;
}
示例#2
0
文件: demo-glyph.c 项目: hurry07/v8
// --------------------------------------------------------------- add_text ---
void add_text( vertex_buffer_t * buffer, texture_font_t * font,
               wchar_t *  text, vec4 * color, vec2 * pen )
{
    size_t i;
    float r = color->red, g = color->green, b = color->blue, a = color->alpha;
    for( i=0; i<wcslen(text); ++i )
    {
        texture_glyph_t *glyph = texture_font_get_glyph( font, text[i] );
        if( glyph != NULL )
        {
            int kerning = 0;
            if( i > 0)
            {
                kerning = texture_glyph_get_kerning( glyph, text[i-1] );
            }
            pen->x += kerning;
            int x0  = (int)( pen->x + glyph->offset_x );
            int y0  = (int)( pen->y + glyph->offset_y );
            int x1  = (int)( x0 + glyph->width );
            int y1  = (int)( y0 - glyph->height );
            float s0 = glyph->s0;
            float t0 = glyph->t0;
            float s1 = glyph->s1;
            float t1 = glyph->t1;
            GLuint indices[] = {0,1,2,0,2,3};
            vertex_t vertices[] = { { x0,y0,0,  s0,t0,  r,g,b,a },
                                    { x0,y1,0,  s0,t1,  r,g,b,a },
                                    { x1,y1,0,  s1,t1,  r,g,b,a },
                                    { x1,y0,0,  s1,t0,  r,g,b,a } };
            vertex_buffer_push_back( buffer, vertices, 4, indices, 6 );
            pen->x += glyph->advance_x;
        }
    }
}
// ------------------------------------------------------------------- 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 );
}
示例#4
0
	void add_text( vertex_buffer_t * buffer, texture_font_t * font,
		char* fileBuffer, int bufferSizeBytes,
		const char* text, vec2 * pen, int currentSize )
	{
		vec2 startPos = *pen;
		size_t length = strlen(text);
		Color vertColor = Color::White;

		for(size_t i=0; i < length; ++i)
		{
			if(text[i] == '\n')
			{
				pen->x = startPos.x;
				pen->y -= currentSize;
				continue;
			}

			if(text[i] == '<')
			{
				if(i + 1 < length && text[i + 1] == '#')
				{
					vertColor = ParseColor(text, i);
					i += 11;
				}
			}

			float r = vertColor.r;
			float g = vertColor.g;
			float b = vertColor.b;
			float a = vertColor.a;

			texture_glyph_t *glyph = texture_font_get_glyph( font, fileBuffer, bufferSizeBytes, text[i] );
			if( glyph != NULL )
			{
				float kerning = 0;
				if( i > 0)
				{
					kerning = texture_glyph_get_kerning( glyph, text[i-1] );
				}
				pen->x += kerning;
				int x0  = (int)( pen->x + glyph->offset_x );
				int y0  = (int)( pen->y + glyph->offset_y );
				int x1  = (int)( x0 + glyph->width );
				int y1  = (int)( y0 - glyph->height );
				float s0 = glyph->s0;
				float t0 = glyph->t0;
				float s1 = glyph->s1;
				float t1 = glyph->t1;
				GLuint indices[6] = {0,1,2, 0,2,3};
				vertex_t vertices[4] = { 
					{(float)x0, (float)y0, 1.0f, s0, t0, r, g, b, a},
					{(float)x0, (float)y1, 1.0f, s0, t1, r, g, b, a},
					{(float)x1, (float)y1, 1.0f, s1, t1, r, g, b, a},
					{(float)x1, (float)y0, 1.0f, s1, t0, r, g, b, a} };
				vertex_buffer_push_back( buffer, vertices, 4, indices, 6 );
				pen->x += glyph->advance_x;
			}
		}
	}
示例#5
0
static void
coors_push_to_vector( struct coordinates *coors, vertex_buffer_t * buffer )
{
    vertex_buffer_push_back(
        buffer,
        coors->start_vertex,
        coors->cur_vertex - coors->start_vertex,
        coors->start_index,
        coors->cur_index - coors->start_index );
}
示例#6
0
// ------------------------------------------------------------------- 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;
}
示例#7
0
void
sen_render_push_buffer(vertex_buffer_t* buff,
                       const texture_t* tex,
                       const font_t*    font,
                       const shader_t*  program,
                       blend_func blend)
{
  vertex_buffer_t* gb = get_group_buffer(buff, tex, font, program, blend);
  size_t ivsize = buff->vertices->item_size;
  //size_t iisize = buff->indices->item_size;
  size_t i;
  for (i = 0; i < buff->items->size; ++i) {
    ivec4* item = (ivec4*) vector_get(buff->items, i);
/*
    size_t j; size_t index = 0;
    for (j = 0; j < gb->items->size; ++j) {
      ivec4* gb_item = (ivec4*) vector_get(gb->items, j);
      // FIXME
      vec4* vz1 = ( vec4*) (buff->vertices->items + ivsize*item->x);
      vec4* vz2 = ( vec4*) (gb->vertices->items + ivsize*gb_item->x);
      if (vz1->z < vz2->z ) {
        //_logfi("");
        break;
      }
      index++;
    }
*/

//    vertex_buffer_push_back_vertices(gb, buff->vertices->items, buff->vertices->size );
  //  vertex_buffer_push_back_indicies(gb, buff->indicies->items, buff->indicies->size );

    vertex_buffer_push_back( gb,
                             (char*)(buff->vertices->items) + ivsize*item->x, item->y,
                             indices, 6);
    //vertex_buffer_insert( gb, 0,
      //                       buff->vertices->items + ivsize*item->x, item->y,
        //                     indices, 6);

/*
    vertex_buffer_insert( gb, index,
                             buff->vertices->items + ivsize*item->x, item->y,
                             buff->indices->items + iisize*item->z, item->w);
*/
  }
  //vertex_buffer_push_back_vertices(gb, buff->vertices->items, buff->vertices->size );
  //vertex_buffer_push_back_indices(gb, buff->indices->items, buff->indices->size );

}
    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;
            }
        }
    }
示例#9
0
// --------------------------------------------------------------- add_text ---
vec4
add_text( vertex_buffer_t * buffer, texture_font_t * font,
          char *text, vec4 * color, vec2 * pen )
{
    vec4 bbox = {{0,0,0,0}};
    size_t i;
    float r = color->red, g = color->green, b = color->blue, a = color->alpha;
    for( i = 0; i < strlen(text); ++i )
    {
        texture_glyph_t *glyph = texture_font_get_glyph( font, text + i );
        if( glyph != NULL )
        {
            float kerning = 0.0f;
            if( i > 0)
            {
                kerning = texture_glyph_get_kerning( glyph, text + i - 1 );
            }
            pen->x += kerning;
            int x0  = (int)( pen->x + glyph->offset_x );
            int y0  = (int)( pen->y + glyph->offset_y );
            int x1  = (int)( x0 + glyph->width );
            int y1  = (int)( y0 - glyph->height );
            float s0 = glyph->s0;
            float t0 = glyph->t0;
            float s1 = glyph->s1;
            float t1 = glyph->t1;
            GLuint indices[6] = {0,1,2, 0,2,3};
            vertex_t vertices[4] = { { x0,y0,0,  s0,t0,  r,g,b,a },
                                     { x0,y1,0,  s0,t1,  r,g,b,a },
                                     { x1,y1,0,  s1,t1,  r,g,b,a },
                                     { x1,y0,0,  s1,t0,  r,g,b,a } };
            vertex_buffer_push_back( buffer, vertices, 4, indices, 6 );
            pen->x += glyph->advance_x;

            if  (x0 < bbox.x)                bbox.x = x0;
            if  (y1 < bbox.y)                bbox.y = y1;
            if ((x1 - bbox.x) > bbox.width)  bbox.width  = x1-bbox.x;
            if ((y0 - bbox.y) > bbox.height) bbox.height = y0-bbox.y;
        }
    }
    return bbox;
}
示例#10
0
// --------------------------------------------------------------- add_text ---
vec4
add_text( vertex_buffer_t * buffer, texture_font_t * font,
          const char *text, vec4 * color, vec2 * pen )
{
    auto bbox = vec4{0,0,0,0};
    size_t i;
    auto r = color->red, g = color->green, b = color->blue, a = color->alpha;
    for( i = 0; i < strlen(text); ++i ) {
        glfwSetTime(total_time);
        auto glyph = texture_font_get_glyph( font, text + i );
        total_time += glfwGetTime();
        if( glyph  ) {
            float kerning = 0.0f;
            if( i > 0) {
                kerning = texture_glyph_get_kerning( glyph, text + i - 1 );
            }
            pen->x += kerning;
            auto x0  = (float)( pen->x + glyph->offset_x );
            auto y0  = (float)( pen->y + glyph->offset_y );
            auto x1  = (float)( x0 + glyph->width );
            auto y1  = (float)( y0 - glyph->height );
            auto s0 = glyph->s0;
            auto t0 = glyph->t0;
            auto s1 = glyph->s1;
            auto t1 = glyph->t1;
            GLuint indices[6] = {0,1,2, 0,2,3};
            vertex vertices[4]   = { { x0,y0,0,  s0,t0,  r,g,b,a },
                                     { x0,y1,0,  s0,t1,  r,g,b,a },
                                     { x1,y1,0,  s1,t1,  r,g,b,a },
                                     { x1,y0,0,  s1,t0,  r,g,b,a } };
            vertex_buffer_push_back( buffer, vertices, 4, indices, 6 );
            pen->x += glyph->advance_x;

            if  (x0 < bbox.x)                bbox.x = x0;
            if  (y1 < bbox.y)                bbox.y = y1;
            if ((x1 - bbox.x) > bbox.width)  bbox.width  = x1-bbox.x;
            if ((y0 - bbox.y) > bbox.height) bbox.height = y0-bbox.y;
        }
    }
    return bbox;
}
// ------------------------------------------------------------------- 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 );
}
示例#12
0
文件: markup.cpp 项目: ginozh/my_wmm
void init()
{
    text_shader = shader_load( "text.vert",
                               "text.frag" );

    font_manager = font_manager_new( 512, 512, LCD_FILTERING_ON );
    buffer = text_buffer_new( );

    vec4 black  = {{0.0, 0.0, 0.0, 1.0}};
    vec4 white  = {{1.0, 1.0, 1.0, 1.0}};
    vec4 yellow = {{1.0, 1.0, 0.0, 1.0}};
    vec4 grey   = {{0.5, 0.5, 0.5, 1.0}};
    vec4 none   = {{1.0, 1.0, 1.0, 0.0}};

    //char *f_normal   = match_description("Vera:size=50");
    char *f_normal   = match_description("Arial");
    char *f_bold     = match_description("Arial", true);
    //char *f_bold     = match_description("sans\\-serif:size=24");
    char *f_italic   = match_description("sans\\-serif", false, true);
    //char *f_italic   = match_description("SimSun", false, true);
    //char *f_japanese = match_description("Droid Sans:size=18:lang=ja");
    //char *f_japanese = match_description("sans-serif:size=18:lang=zh");
    //char *f_japanese = match_description("sans\\-serif:size=18:lang=zh\\-CN");
    //char *f_japanese = match_description("FZLanTingHeiS\\-UL\\-GB:size=18:lang=zh\\-CN"); //ok
    //char *f_japanese = match_description("FZLanTingHeiS\\-UL\\-GB"); //ok
    //char *f_japanese = match_description("Yu Gothic UI Semibold"); //ok
    //char *f_japanese = match_description("jj:size=18"); //ok
    //char *f_japanese = match_description("Brush Script MT"); //ok
    char *f_japanese = match_description("Microsoft JhengHei UI"); //ok
    //char *f_japanese = match_description("华文隶书:size=28:lang=zh\\-CN"); //no
    char *f_math     = match_description("DejaVu Sans");
    printf("init. f_normal: %s f_bold: %s f_italic: %s f_japanese: %s f_math: %s\n" , f_normal, f_bold, f_italic, f_japanese, f_math);
    //printf("init. f_japanese: %s\n" , f_japanese);

    //exit(0);
    markup_t normal = {
        .family  = f_normal,
        .size    = 20.0, .bold    = 0,   .italic  = 0,
        .spacing = 0.0,  .gamma   = 2.,
        .foreground_color    = white, .background_color    = none,
        .outline           = 0,     .outline_color     = white,
        .underline           = 0,     .underline_color     = white,
        .overline            = 0,     .overline_color      = white,
        .strikethrough       = 0,     .strikethrough_color = white,
        .font = 0,
    };
    markup_t highlight = normal; highlight.background_color = grey;
    markup_t reverse   = normal; reverse.foreground_color = black;
                                 reverse.background_color = white;
                                 reverse.gamma = 1.0;
    markup_t overline  = normal; overline.overline = 1;
    markup_t underline = normal; underline.underline = 1;
    markup_t small     = normal; small.size = 10.0;
    markup_t big       = normal; big.size = 48.0;
                                 big.italic = 1;
                                 big.foreground_color = yellow;
    markup_t bold      = normal; bold.bold = 1; bold.family = f_bold;
    markup_t italic    = normal; italic.italic = 1; italic.family = f_italic;
    markup_t japanese  = normal; japanese.family = f_japanese;
    //markup_t japanese  = normal; japanese.family = "C:/Windows/Fonts/simsun.ttc";
    //markup_t japanese  = normal; japanese.family = "c:/qtproject/opengl/freetype-gl/fonts/fireflysung.ttf";
                                 japanese.size = 25.0;
    markup_t math      = normal; math.family = f_math;
#if 1
    normal.font = font_manager_get_from_markup( font_manager, &normal );
    highlight.font = font_manager_get_from_markup( font_manager, &highlight );
    reverse.font = font_manager_get_from_markup( font_manager, &reverse );
    overline.font = font_manager_get_from_markup( font_manager, &overline );
    underline.font = font_manager_get_from_markup( font_manager, &underline );
    small.font = font_manager_get_from_markup( font_manager, &small );
    big.font = font_manager_get_from_markup( font_manager, &big );
    bold.font = font_manager_get_from_markup( font_manager, &bold );
    italic.font = font_manager_get_from_markup( font_manager, &italic );
    japanese.font = font_manager_get_from_markup( font_manager, &japanese );
    math.font = font_manager_get_from_markup( font_manager, &math );
#else
    japanese.font = font_manager_get_from_markup( font_manager, &japanese );
#endif

    vec2 pen = {{20, 200}};
#if 1
    text_buffer_printf( buffer, &pen,
                        &underline, "The",
                        &normal,    " Quick",
                        &big,       " brown ",
                        &reverse,   " fox \n",
                        &italic,    "jumps over ",
                        &bold,      "the lazy ",
                        &normal,    "dog.\n",
                        &small,     "Now is the time for all good men "
                                    "to come to the aid of the party.\n",
                        &italic,    "Ég get etið gler án þess að meiða mig.\n",
                        &japanese,  "aaa张私はガラスを食べられます。 それは私を傷つけません\n",
                        &math,      "ℕ ⊆ ℤ ⊂ ℚ ⊂ ℝ ⊂ ℂ",
                        NULL );
#else
    text_buffer_printf( buffer, &pen,
                        &japanese,  "Brush Script MT张私はガラスを食べられます。 それは私を傷つけません\n",
                        NULL );
#endif

    glGenTextures( 1, &font_manager->atlas->id );
    glBindTexture( GL_TEXTURE_2D, font_manager->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, font_manager->atlas->width,
                  font_manager->atlas->height, 0, GL_RGB, GL_UNSIGNED_BYTE,
                  font_manager->atlas->data );
    printf("init font_manager->atlas->width: %d font_manager->atlas->height: %d\n"
            , font_manager->atlas->width, font_manager->atlas->height);

    text_buffer_align( buffer, &pen, ALIGN_CENTER );

    vec4 bounds = text_buffer_get_bounds( buffer, &pen );
    float left = bounds.left;
    float right = bounds.left + bounds.width;
    float top = bounds.top;
    float bottom = bounds.top - bounds.height;

    bounds_shader = shader_load( "v3f-c4f.vert",
                                 "v3f-c4f.frag" );

    lines_buffer = vertex_buffer_new( "vertex:3f,color:4f" );
    vertex_t vertices[] = { { left - 10,         top, 0, 0,0,0,1}, // top
                            {right + 10,         top, 0, 0,0,0,1},

                            { left - 10,      bottom, 0, 0,0,0,1}, // bottom
                            {right + 10,      bottom, 0, 0,0,0,1},

                            {      left,    top + 10, 0, 0,0,0,1}, // left
                            {      left, bottom - 10, 0, 0,0,0,1},
                            {     right,    top + 10, 0, 0,0,0,1}, // right
                            {     right, bottom - 10, 0, 0,0,0,1} };
    GLuint indices[] = { 0,1,2,3,4,5,6,7 };
    vertex_buffer_push_back( lines_buffer, vertices, 8, indices, 8);

    mat4_set_identity( &projection );
    mat4_set_identity( &model );
    mat4_set_identity( &view );
}


// ---------------------------------------------------------------- display ---
void display( GLFWwindow* window )
{
    glClearColor(0.40,0.40,0.45,1.00);
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glColor4f(1.00,1.00,1.00,1.00);
    glUseProgram( text_shader );
    {
        glUniformMatrix4fv( glGetUniformLocation( text_shader, "model" ),
                            1, 0, model.data);
        glUniformMatrix4fv( glGetUniformLocation( text_shader, "view" ),
                            1, 0, view.data);
        glUniformMatrix4fv( glGetUniformLocation( text_shader, "projection" ),
                            1, 0, projection.data);
        glUniform1i( glGetUniformLocation( text_shader, "tex" ), 0 );
        glUniform3f( glGetUniformLocation( text_shader, "pixel" ),
                     1.0f/font_manager->atlas->width,
                     1.0f/font_manager->atlas->height,
                     (float)font_manager->atlas->depth );

        glEnable( GL_BLEND );

        glActiveTexture( GL_TEXTURE0 );
        glBindTexture( GL_TEXTURE_2D, font_manager->atlas->id );

        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
        glBlendColor( 1, 1, 1, 1 );

        vertex_buffer_render( buffer->buffer, GL_TRIANGLES );
        glBindTexture( GL_TEXTURE_2D, 0 );
        glBlendColor( 0, 0, 0, 0 );
        glUseProgram( 0 );
    }

    glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
    glBlendColor( 1.0, 1.0, 1.0, 1.0 );
    glUseProgram( bounds_shader );
    {
        glUniformMatrix4fv( glGetUniformLocation( bounds_shader, "model" ),
                            1, 0, model.data);
        glUniformMatrix4fv( glGetUniformLocation( bounds_shader, "view" ),
                            1, 0, view.data);
        glUniformMatrix4fv( glGetUniformLocation( bounds_shader, "projection" ),
                            1, 0, projection.data);
        vertex_buffer_render( lines_buffer, GL_LINES );
    }
    
    glfwSwapBuffers( window );
}
示例#13
0
// ----------------------------------------------------------------------------
void
text_buffer_add_wchar( text_buffer_t * self,
                       vec2 * pen, markup_t * markup,
                       wchar_t current, wchar_t previous )
{
    size_t vcount = 0;
    size_t icount = 0;
    vertex_buffer_t * buffer = self->buffer;
    texture_font_t * font = markup->font;
    float gamma = markup->gamma;

    // Maximum number of vertices is 20 (= 5x2 triangles) per glyph:
    //  - 2 triangles for background
    //  - 2 triangles for overline
    //  - 2 triangles for underline
    //  - 2 triangles for strikethrough
    //  - 2 triangles for glyph
    glyph_vertex_t vertices[4*5];
    GLuint indices[6*5];
    texture_glyph_t *glyph;
    texture_glyph_t *black;
    float kerning = 0;
   
    if( current == L'\n' )
    {
        pen->x = self->origin.x;
        pen->y += self->line_descender;
        self->line_descender = 0;
        self->line_ascender = 0;
        self->line_start = vector_size( self->buffer->items );
        return;
    }

    if( markup->font->ascender > self->line_ascender )
    {
        float y = pen->y;
        pen->y -= (markup->font->ascender - self->line_ascender);
        text_buffer_move_last_line( self, (int)(y-pen->y) );
        self->line_ascender = markup->font->ascender;
    }
    if( markup->font->descender < self->line_descender )
    {
        self->line_descender = markup->font->descender;
    }

    glyph = texture_font_get_glyph( font, current );
    black = texture_font_get_glyph( font, -1 );
        
    if( glyph == NULL )
    {
        return;
    }
    
    if( previous && markup->font->kerning )
    {
        kerning = texture_glyph_get_kerning( glyph, previous );
    }
    pen->x += kerning;
        
    // Background
    if( markup->background_color.alpha > 0 )
    {
        float r = markup->background_color.r;
        float g = markup->background_color.g;
        float b = markup->background_color.b;
        float a = markup->background_color.a;
        float x0 = ( pen->x -kerning );
        float y0 = (int)( pen->y + font->descender );
        float x1 = ( x0 + glyph->advance_x );
        float y1 = (int)( y0 + font->height + font->linegap );
        float s0 = black->s0;
        float t0 = black->t0;
        float s1 = black->s1;
        float t1 = black->t1;

        SET_GLYPH_VERTEX(vertices[vcount+0],
                         (int)x0,y0,0,  s0,t0,  r,g,b,a,  x0-((int)x0), gamma );
        SET_GLYPH_VERTEX(vertices[vcount+1],
                         (int)x0,y1,0,  s0,t1,  r,g,b,a,  x0-((int)x0), gamma );
        SET_GLYPH_VERTEX(vertices[vcount+2],
                         (int)x1,y1,0,  s1,t1,  r,g,b,a,  x1-((int)x1), gamma );
        SET_GLYPH_VERTEX(vertices[vcount+3],
                         (int)x1,y0,0,  s1,t0,  r,g,b,a,  x1-((int)x1), gamma );
        indices[icount + 0] = vcount+0;
        indices[icount + 1] = vcount+1;
        indices[icount + 2] = vcount+2;
        indices[icount + 3] = vcount+0;
        indices[icount + 4] = vcount+2;
        indices[icount + 5] = vcount+3;
        vcount += 4;
        icount += 6;
    }
        
    // Underline
    if( markup->underline )
    {
        float r = markup->underline_color.r;
        float g = markup->underline_color.g;
        float b = markup->underline_color.b;
        float a = markup->underline_color.a;
        float x0 = ( pen->x - kerning );
        float y0 = (int)( pen->y + font->underline_position );
        float x1 = ( x0 + glyph->advance_x );
        float y1 = (int)( y0 + font->underline_thickness ); 
        float s0 = black->s0;
        float t0 = black->t0;
        float s1 = black->s1;
        float t1 = black->t1;

        SET_GLYPH_VERTEX(vertices[vcount+0],
                         (int)x0,y0,0,  s0,t0,  r,g,b,a,  x0-((int)x0), gamma );
        SET_GLYPH_VERTEX(vertices[vcount+1],
                         (int)x0,y1,0,  s0,t1,  r,g,b,a,  x0-((int)x0), gamma );
        SET_GLYPH_VERTEX(vertices[vcount+2],
                         (int)x1,y1,0,  s1,t1,  r,g,b,a,  x1-((int)x1), gamma );
        SET_GLYPH_VERTEX(vertices[vcount+3],
                         (int)x1,y0,0,  s1,t0,  r,g,b,a,  x1-((int)x1), gamma );
        indices[icount + 0] = vcount+0;
        indices[icount + 1] = vcount+1;
        indices[icount + 2] = vcount+2;
        indices[icount + 3] = vcount+0;
        indices[icount + 4] = vcount+2;
        indices[icount + 5] = vcount+3;
        vcount += 4;
        icount += 6;
    }
    
    // Overline
    if( markup->overline )
    {
        float r = markup->overline_color.r;
        float g = markup->overline_color.g;
        float b = markup->overline_color.b;
        float a = markup->overline_color.a;
        float x0 = ( pen->x -kerning );
        float y0 = (int)( pen->y + (int)font->ascender );
        float x1 = ( x0 + glyph->advance_x );
        float y1 = (int)( y0 + (int)font->underline_thickness ); 
        float s0 = black->s0;
        float t0 = black->t0;
        float s1 = black->s1;
        float t1 = black->t1;
        SET_GLYPH_VERTEX(vertices[vcount+0],
                         (int)x0,y0,0,  s0,t0,  r,g,b,a,  x0-((int)x0), gamma );
        SET_GLYPH_VERTEX(vertices[vcount+1],
                         (int)x0,y1,0,  s0,t1,  r,g,b,a,  x0-((int)x0), gamma );
        SET_GLYPH_VERTEX(vertices[vcount+2],
                         (int)x1,y1,0,  s1,t1,  r,g,b,a,  x1-((int)x1), gamma );
        SET_GLYPH_VERTEX(vertices[vcount+3],
                         (int)x1,y0,0,  s1,t0,  r,g,b,a,  x1-((int)x1), gamma );
        indices[icount + 0] = vcount+0;
        indices[icount + 1] = vcount+1;
        indices[icount + 2] = vcount+2;
        indices[icount + 3] = vcount+0;
        indices[icount + 4] = vcount+2;
        indices[icount + 5] = vcount+3;
        vcount += 4;
        icount += 6;
    }
        
    /* Strikethrough */
    if( markup->strikethrough )
    {
        float r = markup->strikethrough_color.r;
        float g = markup->strikethrough_color.g;
        float b = markup->strikethrough_color.b;
        float a = markup->strikethrough_color.a;
        float x0  = ( pen->x -kerning );
        float y0  = (int)( pen->y + (int)font->ascender*.33);
        float x1  = ( x0 + glyph->advance_x );
        float y1  = (int)( y0 + (int)font->underline_thickness ); 
        float s0 = black->s0;
        float t0 = black->t0;
        float s1 = black->s1;
        float t1 = black->t1;
        SET_GLYPH_VERTEX(vertices[vcount+0],
                         (int)x0,y0,0,  s0,t0,  r,g,b,a,  x0-((int)x0), gamma );
        SET_GLYPH_VERTEX(vertices[vcount+1],
                         (int)x0,y1,0,  s0,t1,  r,g,b,a,  x0-((int)x0), gamma );
        SET_GLYPH_VERTEX(vertices[vcount+2],
                         (int)x1,y1,0,  s1,t1,  r,g,b,a,  x1-((int)x1), gamma );
        SET_GLYPH_VERTEX(vertices[vcount+3],
                         (int)x1,y0,0,  s1,t0,  r,g,b,a,  x1-((int)x1), gamma );
        indices[icount + 0] = vcount+0;
        indices[icount + 1] = vcount+1;
        indices[icount + 2] = vcount+2;
        indices[icount + 3] = vcount+0;
        indices[icount + 4] = vcount+2;
        indices[icount + 5] = vcount+3;
        vcount += 4;
        icount += 6;
    }
    {
        // Actual glyph
        float r = markup->foreground_color.red;
        float g = markup->foreground_color.green;
        float b = markup->foreground_color.blue;
        float a = markup->foreground_color.alpha;
        float x0 = ( pen->x + glyph->offset_x );
        float y0 = (int)( pen->y + glyph->offset_y );
        float x1 = ( x0 + glyph->width );
        float y1 = (int)( y0 - glyph->height );
        float s0 = glyph->s0;
        float t0 = glyph->t0;
        float s1 = glyph->s1;
        float t1 = glyph->t1;

        SET_GLYPH_VERTEX(vertices[vcount+0],
                         (int)x0,y0,0,  s0,t0,  r,g,b,a,  x0-((int)x0), gamma );
        SET_GLYPH_VERTEX(vertices[vcount+1],
                         (int)x0,y1,0,  s0,t1,  r,g,b,a,  x0-((int)x0), gamma );
        SET_GLYPH_VERTEX(vertices[vcount+2],
                         (int)x1,y1,0,  s1,t1,  r,g,b,a,  x1-((int)x1), gamma );
        SET_GLYPH_VERTEX(vertices[vcount+3],
                         (int)x1,y0,0,  s1,t0,  r,g,b,a,  x1-((int)x1), gamma );
        indices[icount + 0] = vcount+0;
        indices[icount + 1] = vcount+1;
        indices[icount + 2] = vcount+2;
        indices[icount + 3] = vcount+0;
        indices[icount + 4] = vcount+2;
        indices[icount + 5] = vcount+3;
        vcount += 4;
        icount += 6;
    
        vertex_buffer_push_back( buffer, vertices, vcount, indices, icount );
        pen->x += glyph->advance_x * (1.0 + markup->spacing);
    }
}
示例#14
0
// -------------------------------------------------------- console_render ---
void
console_render( console_t *self )
{
    char* cur_char;
    char* prev_char;

    int viewport[4];
    glGetIntegerv( GL_VIEWPORT, viewport );

    size_t i, index;
    self->pen.x = 0;
    self->pen.y = viewport[3];
    vertex_buffer_clear( console->buffer );

    int cursor_x = self->pen.x;
    int cursor_y = self->pen.y;

    markup_t markup;

    // console_t buffer
    markup = self->markup[MARKUP_FAINT];
    self->pen.y -= markup.font->height;

    for( i=0; i<self->lines->size; ++i )
    {
        char *text = * (char **) vector_get( self->lines, i ) ;
        if( strlen(text) > 0 )
        {
            cur_char = text;
            prev_char = NULL;
            console_add_glyph( console, cur_char, prev_char, &markup );
            prev_char = cur_char;
            for( index=1; index < strlen(text)-1; ++index )
            {
                cur_char = text + index;
                console_add_glyph( console, cur_char, prev_char, &markup );
                prev_char = cur_char;
            }
        }
        self->pen.y -= markup.font->height - markup.font->linegap;
        self->pen.x = 0;
        cursor_x = self->pen.x;
        cursor_y = self->pen.y;
    }

    // Prompt
    markup = self->markup[MARKUP_BOLD];
    if( strlen( self->prompt ) > 0 )
    {
        cur_char = self->prompt;
        prev_char = NULL;
        console_add_glyph( console, cur_char, prev_char, &markup );
        prev_char = cur_char;
        for( index=1; index < strlen(self->prompt); ++index )
        {
            cur_char = self->prompt + index;
            console_add_glyph( console, cur_char, prev_char, &markup );
            prev_char = cur_char;
        }
    }
    cursor_x = (int) self->pen.x;

    // Input
    markup = self->markup[MARKUP_NORMAL];
    if( strlen(self->input) > 0 )
    {
        cur_char = self->input;
        prev_char = NULL;
        console_add_glyph( console, cur_char, prev_char, &markup );
        prev_char = cur_char;
        if( self->cursor > 0)
        {
            cursor_x = (int) self->pen.x;
        }
        for( index=1; index < strlen(self->input); ++index )
        {
            cur_char = self->input + index;
            console_add_glyph( console, cur_char, prev_char, &markup );
            prev_char = cur_char;
            if( index < self->cursor )
            {
                cursor_x = (int) self->pen.x;
            }
        }
    }

    if( self->lines->size || self->prompt[0] != '\0' || self->input[0] != '\0' )
    {
        glBindTexture( GL_TEXTURE_2D, self->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, self->atlas->width,
                      self->atlas->height, 0, GL_RED, GL_UNSIGNED_BYTE,
                      self->atlas->data );
    }

    // Cursor (we use the black character (NULL) as texture )
    texture_glyph_t *glyph  = texture_font_get_glyph( markup.font, NULL );
    float r = markup.foreground_color.r;
    float g = markup.foreground_color.g;
    float b = markup.foreground_color.b;
    float a = markup.foreground_color.a;
    int x0  = cursor_x+1;
    int y0  = cursor_y + markup.font->descender;
    int x1  = cursor_x+2;
    int y1  = y0 + markup.font->height - markup.font->linegap;
    float s0 = glyph->s0;
    float t0 = glyph->t0;
    float s1 = glyph->s1;
    float t1 = glyph->t1;
    GLuint indices[] = {0,1,2, 0,2,3};
    vertex_t vertices[] = { { x0,y0,0,  s0,t0,  r,g,b,a },
                            { x0,y1,0,  s0,t1,  r,g,b,a },
                            { x1,y1,0,  s1,t1,  r,g,b,a },
                            { x1,y0,0,  s1,t0,  r,g,b,a } };
    vertex_buffer_push_back( self->buffer, vertices, 4, indices, 6 );
    glEnable( GL_TEXTURE_2D );

    glUseProgram( shader );
    {
        glUniform1i( glGetUniformLocation( shader, "texture" ),
                     0 );
        glUniformMatrix4fv( glGetUniformLocation( shader, "model" ),
                            1, 0, model.data);
        glUniformMatrix4fv( glGetUniformLocation( shader, "view" ),
                            1, 0, view.data);
        glUniformMatrix4fv( glGetUniformLocation( shader, "projection" ),
                            1, 0, projection.data);
        vertex_buffer_render( console->buffer, GL_TRIANGLES );
    }
}
示例#15
0
// -------------------------------------------------------- console_render ---
void
console_render( console_t *self )
{
    int viewport[4];
    glGetIntegerv( GL_VIEWPORT, viewport );

    size_t i, index;
    self->pen.x = 0;
    self->pen.y = viewport[3];
    vertex_buffer_clear( console->buffer );

    int cursor_x = self->pen.x;
    int cursor_y = self->pen.y;

    markup_t markup;

    // console_t buffer
    markup = self->markup[MARKUP_FAINT];
    self->pen.y -= markup.font->height;

    for( i=0; i<self->lines->size; ++i )
    {
        wchar_t *text = * (wchar_t **) vector_get( self->lines, i ) ;
        if( wcslen(text) > 0 )
        {
            console_add_glyph( console, text[0], L'\0', &markup );
            for( index=1; index < wcslen(text)-1; ++index )
            {
                console_add_glyph( console, text[index], text[index-1], &markup );
            }
        }
        self->pen.y -= markup.font->height - markup.font->linegap;
        self->pen.x = 0;
        cursor_x = self->pen.x;
        cursor_y = self->pen.y;
    }

    // Prompt
    markup = self->markup[MARKUP_BOLD];
    if( wcslen( self->prompt ) > 0 )
    {
        console_add_glyph( console, self->prompt[0], L'\0', &markup );
        for( index=1; index < wcslen(self->prompt); ++index )
        {
            console_add_glyph( console, self->prompt[index], self->prompt[index-1], &markup );
        }
    }
    cursor_x = (int) self->pen.x;

    // Input
    markup = self->markup[MARKUP_NORMAL];
    if( wcslen(self->input) > 0 )
    {
        console_add_glyph( console, self->input[0], L'\0', &markup );
        if( self->cursor > 0)
        {
            cursor_x = (int) self->pen.x;
        }
        for( index=1; index < wcslen(self->input); ++index )
        {
            console_add_glyph( console, self->input[index], self->input[index-1], &markup );
            if( index < self->cursor )
            {
                cursor_x = (int) self->pen.x;
            }
        }
    }

    // Cursor (we use the black character (-1) as texture )
    texture_glyph_t *glyph  = texture_font_get_glyph( markup.font, -1 );
    float r = markup.foreground_color.r;
    float g = markup.foreground_color.g;
    float b = markup.foreground_color.b;
    float a = markup.foreground_color.a;
    int x0  = cursor_x+1;
    int y0  = cursor_y + markup.font->descender;
    int x1  = cursor_x+2;
    int y1  = y0 + markup.font->height - markup.font->linegap;
    float s0 = glyph->s0;
    float t0 = glyph->t0;
    float s1 = glyph->s1;
    float t1 = glyph->t1;
    GLuint indices[] = {0,1,2, 0,2,3};
    vertex_t vertices[] = { { x0,y0,0,  s0,t0,  r,g,b,a },
                            { x0,y1,0,  s0,t1,  r,g,b,a },
                            { x1,y1,0,  s1,t1,  r,g,b,a },
                            { x1,y0,0,  s1,t0,  r,g,b,a } };
    vertex_buffer_push_back( self->buffer, vertices, 4, indices, 6 );
    glEnable( GL_TEXTURE_2D );

    glUseProgram( shader );
    {
        glUniform1i( glGetUniformLocation( shader, "texture" ),
                     0 );
        glUniformMatrix4fv( glGetUniformLocation( shader, "model" ),
                            1, 0, model.data);
        glUniformMatrix4fv( glGetUniformLocation( shader, "view" ),
                            1, 0, view.data);
        glUniformMatrix4fv( glGetUniformLocation( shader, "projection" ),
                            1, 0, projection.data);
        vertex_buffer_render( console->buffer, GL_TRIANGLES );
    }


}
示例#16
0
文件: demo-glyph.c 项目: hurry07/v8
// ------------------------------------------------------------------- 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;
}
// ------------------------------------------------------------------- init ---
void init( void )
{
    size_t i, j;
    int ptSize = 50*64;
    int device_hdpi = 72;
    int device_vdpi = 72;

    atlas = texture_atlas_new( 512, 512, 3 );

    /* Init freetype */
    FT_Library ft_library;
    assert(!FT_Init_FreeType(&ft_library));

    /* Load our fonts */
    FT_Face ft_face[NUM_EXAMPLES];
    assert(!FT_New_Face( ft_library, fonts[ENGLISH], 0, &ft_face[ENGLISH]) );
    assert(!FT_Set_Char_Size( ft_face[ENGLISH], 0, ptSize, device_hdpi, device_vdpi ) );
    // ftfdump( ft_face[ENGLISH] );            // wonderful world of encodings ...
    force_ucs2_charmap( ft_face[ENGLISH] ); // which we ignore.

    assert( !FT_New_Face(ft_library, fonts[ARABIC], 0, &ft_face[ARABIC]) );
    assert( !FT_Set_Char_Size(ft_face[ARABIC], 0, ptSize, device_hdpi, device_vdpi ) );
    // ftfdump( ft_face[ARABIC] );
    force_ucs2_charmap( ft_face[ARABIC] );

    assert(!FT_New_Face( ft_library, fonts[CHINESE], 0, &ft_face[CHINESE]) );
    assert(!FT_Set_Char_Size( ft_face[CHINESE], 0, ptSize, device_hdpi, device_vdpi ) );
    // ftfdump( ft_face[CHINESE] );
    force_ucs2_charmap( ft_face[CHINESE] );

    /* Get our harfbuzz font structs */
    hb_font_t *hb_ft_font[NUM_EXAMPLES];
    hb_ft_font[ENGLISH] = hb_ft_font_create( ft_face[ENGLISH], NULL );
    hb_ft_font[ARABIC]  = hb_ft_font_create( ft_face[ARABIC] , NULL );
    hb_ft_font[CHINESE] = hb_ft_font_create( ft_face[CHINESE], NULL );

    /* Create a buffer for harfbuzz to use */
    hb_buffer_t *buf = hb_buffer_create();

    for (i=0; i < NUM_EXAMPLES; ++i)
    {
        hb_buffer_set_direction( buf, text_directions[i] ); /* or LTR */
        hb_buffer_set_script( buf, scripts[i] ); /* see hb-unicode.h */
        hb_buffer_set_language( buf,
                                hb_language_from_string(languages[i], strlen(languages[i])) );

        /* Layout the text */
        hb_buffer_add_utf8( buf, texts[i], strlen(texts[i]), 0, strlen(texts[i]) );
        hb_shape( hb_ft_font[i], buf, NULL, 0 );

        unsigned int         glyph_count;
        hb_glyph_info_t     *glyph_info   = hb_buffer_get_glyph_infos(buf, &glyph_count);
        hb_glyph_position_t *glyph_pos    = hb_buffer_get_glyph_positions(buf, &glyph_count);


        FT_GlyphSlot slot;
        FT_Bitmap ft_bitmap;
        float size = 24;
        size_t hres = 64;
        FT_Error error;
        FT_Int32 flags = 0;
        flags |= FT_LOAD_RENDER;
        flags |= FT_LOAD_TARGET_LCD;
        FT_Library_SetLcdFilter( ft_library, FT_LCD_FILTER_LIGHT );
        FT_Matrix matrix = { (int)((1.0/hres) * 0x10000L),
                             (int)((0.0)      * 0x10000L),
                             (int)((0.0)      * 0x10000L),
                             (int)((1.0)      * 0x10000L) };
        /* Set char size */
        error = FT_Set_Char_Size( ft_face[i], (int)(ptSize), 0, 72*hres, 72 );
        if( error )
        {
            //fprintf( stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
            //         __LINE__, FT_Errors[error].code, FT_Errors[error].message );
            FT_Done_Face( ft_face[i] );
            break;
        }

        /* Set transform matrix */
        FT_Set_Transform( ft_face[i], &matrix, NULL );

        for (j = 0; j < glyph_count; ++j)
        {
            /* Load glyph */
            error = FT_Load_Glyph( ft_face[i], glyph_info[j].codepoint, flags );
            if( error )
            {
                //fprintf( stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
                //         __LINE__, FT_Errors[error].code, FT_Errors[error].message );
                FT_Done_Face( ft_face[i] );
                break;
            }

            slot = ft_face[i]->glyph;
            ft_bitmap = slot->bitmap;
            int ft_bitmap_width = slot->bitmap.width;
            int ft_bitmap_rows  = slot->bitmap.rows;
            int ft_bitmap_pitch = slot->bitmap.pitch;
            int ft_glyph_top    = slot->bitmap_top;
            int ft_glyph_left   = slot->bitmap_left;

            int w = ft_bitmap_width/3; // 3 because of LCD/RGB encoding
            int h = ft_bitmap_rows;

            ivec4 region = texture_atlas_get_region( atlas, w+1, h+1 );
            if ( region.x < 0 )
            {
                fprintf( stderr, "Texture atlas is full (line %d)\n",  __LINE__ );
                continue;
            }
            int x = region.x, y = region.y;
            texture_atlas_set_region( atlas, region.x, region.y,
                                      w, h, ft_bitmap.buffer, ft_bitmap.pitch );
            printf("%d: %dx%d %f %f\n",
                   glyph_info[j].codepoint,
                   ft_bitmap_width,
                   ft_bitmap_rows,
                   glyph_pos[j].x_advance/64.,
                   glyph_pos[j].y_advance/64.);
        }

        /* clean up the buffer, but don't kill it just yet */
        hb_buffer_reset(buf);
    }


    /* Cleanup */
    hb_buffer_destroy( buf );
    for( i=0; i < NUM_EXAMPLES; ++i )
        hb_font_destroy( hb_ft_font[i] );
    FT_Done_FreeType( ft_library );

    glClearColor(1,1,1,1);
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    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 );

    typedef struct { float x,y,z, u,v, r,g,b,a, shift, gamma; } vertex_t;
    vertex_t vertices[4] =  {
        {  0,  0,0, 0,1, 0,0,0,1, 0, 1},
        {  0,512,0, 0,0, 0,0,0,1, 0, 1},
        {512,512,0, 1,0, 0,0,0,1, 0, 1},
        {512,  0,0, 1,1, 0,0,0,1, 0, 1} };
    GLuint indices[6] = { 0, 1, 2, 0,2,3 };
    buffer = vertex_buffer_new( "vertex:3f,"
                                "tex_coord:2f,"
                                "color:4f,"
                                "ashift:1f,"
                                "agamma:1f" );
    vertex_buffer_push_back( buffer, vertices, 4, indices, 6 );

    shader = shader_load("shaders/text.vert",
                         "shaders/text.frag");
    mat4_set_identity( &projection );
    mat4_set_identity( &model );
    mat4_set_identity( &view );
}
示例#18
0
// ------------------------------------------------------------------- main ---
int main( int argc, char **argv )
{
    int width = 600;
    int height = 600;
    GLFWwindow* window;

    glfwSetErrorCallback( error_callback );

    if (!glfwInit( ))
    {
        exit( EXIT_FAILURE );
    }

    glfwWindowHint( GLFW_VISIBLE, GL_TRUE );
    glfwWindowHint( GLFW_RESIZABLE, GL_FALSE );

    window = glfwCreateWindow( 1, 1, "Freetype OpenGL", NULL, NULL );

    if (!window)
    {
        glfwTerminate( );
        exit( EXIT_FAILURE );
    }

    glfwMakeContextCurrent( window );
    glfwSwapInterval( 1 );

    glfwSetFramebufferSizeCallback( window, reshape );
    glfwSetWindowRefreshCallback( window, display );
    glfwSetKeyCallback( window, 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
    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_from_file( atlas, 400, "fonts/Vera.ttf");
    texture_font_t * small = texture_font_new_from_file( atlas, 18, "fonts/Vera.ttf");
    texture_font_t * title = texture_font_new_from_file( atlas, 32, "fonts/Vera.ttf");

    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 );

    glfwSetWindowSize( window, width, height );
    glfwShowWindow( window );

    while(!glfwWindowShouldClose( window ))
    {
        display( window );
        glfwPollEvents( );
    }

    glfwDestroyWindow( window );
    glfwTerminate( );

    return 0;
}
示例#19
0
// ------------------------------------------------------------------- main ---
int main( int argc, char **argv )
{
    GLFWwindow* window;

    glfwSetErrorCallback( error_callback );

    if (!glfwInit( ))
    {
        exit( EXIT_FAILURE );
    }

    glfwWindowHint( GLFW_VISIBLE, GL_TRUE );
    glfwWindowHint( GLFW_RESIZABLE, GL_FALSE );

    window = glfwCreateWindow( 1, 1, "Distance fields demo", NULL, NULL );

    if (!window)
    {
        glfwTerminate( );
        exit( EXIT_FAILURE );
    }

    glfwMakeContextCurrent( window );
    glfwSwapInterval( 1 );

    glfwSetFramebufferSizeCallback( window, reshape );
    glfwSetWindowRefreshCallback( window, display );
    glfwSetKeyCallback( window, 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

    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( );

    glfwSetWindowSize( window, 400, 400 );
    glfwShowWindow( window );

    glfwSetTime(0.0);

    while(!glfwWindowShouldClose( window ))
    {
        display( window );
        glfwPollEvents( );
    }

    glfwDestroyWindow( window );
    glfwTerminate( );

    return EXIT_SUCCESS;
}
示例#20
0
static void
update_buffer(sprite_t* self)
{
  int status  =  ((node_t*)self)->updated;
  const vec4* col = &(((node_t*)self)->color);
  float r = col->r;
  float g = col->g;
  float b = col->b;
  float a = col->a;
  vec4* bbox = & ( ((node_t*) self)->bbox );
  vec2* size = & ( ((node_t*) self)->size );
  const vec4* coords;
  float sw, sh;
  float x0,y0,x1,y1,s0,s1,t0,t1;
  V4F_T2F_C4F vertices[4];
  int update_model;

  if (status & SEN_NODE_UPDATE_INVALIDATE_BUFFER) {
    vertex_buffer_invalidate(self->quad);
    status &= ~SEN_NODE_UPDATE_INVALIDATE_BUFFER;
  }

  if (status & SEN_NODE_UPDATE_BBOX) {
    vertex_buffer_clear(self->quad);

    sw = self->tex->img_width / 2.0f;
    sh = self->tex->img_height / 2.0f;

    x0 = -sw; x1 = sw;
    y0 = -sh; y1 = sh;

    coords = &(self->tex->coords);

    s0 = coords->s0;
    t0 = coords->t0;
    s1 = coords->s1;
    t1 = coords->t1;

    /*
    V4F_T2F_C4F vertices[4] = {{ -sw,-sh,0,1, coords->s0,coords->t1, col->r,col->g,col->b,col->a,},
                              {  -sw, sh,0,1, coords->s0,coords->t0, col->r,col->g,col->b,col->a,},
                              {   sw, sh,0,1, coords->s1,coords->t0, col->r,col->g,col->b,col->a,},
                              {   sw,-sh,0,1, coords->s1,coords->t1, col->r,col->g,col->b,col->a,}};*/

    vertices[0].x = (float)x0;
    vertices[0].y = (float)y0;
    vertices[0].z = 0.0f;
    vertices[0].w = 1.0f;
    vertices[0].s = s0;
    vertices[0].t = t1;
    vertices[0].r = r;
    vertices[0].g = g;
    vertices[0].b = b;
    vertices[0].a = a;


    vertices[1].x = (float)x0;
    vertices[1].y = (float)y1;
    vertices[1].z = 0.0f;
    vertices[1].w = 1.0f;
    vertices[1].s = s0;
    vertices[1].t = t0;
    vertices[1].r = r;
    vertices[1].g = g;
    vertices[1].b = b;
    vertices[1].a = a;

    vertices[2].x = (float)x1;
    vertices[2].y = (float)y1;
    vertices[2].z = 0.0f;
    vertices[2].w = 1.0f;
    vertices[2].s = s1;
    vertices[2].t = t0;
    vertices[2].r = r;
    vertices[2].g = g;
    vertices[2].b = b;
    vertices[2].a = a;

    vertices[3].x = (float)x1;
    vertices[3].y = (float)y0;
    vertices[3].z = 0.0f;
    vertices[3].w = 1.0f;
    vertices[3].s = s1;
    vertices[3].t = t1;
    vertices[3].r = r;
    vertices[3].g = g;
    vertices[3].b = b;
    vertices[3].a = a;


    bbox->x = -sw; bbox->y = -sh;  bbox->z = sw; bbox->w = sh;
    size->x = (float) (self->tex->img_width);
    size->y = (float) (self->tex->img_height);

    vertex_buffer_push_back( self->quad, vertices, 4, indices, 6 );
   // vertex_buffer_push_back_vertices( self->quad, vertices, 4);
    memcpy(self->vertices, vertices, sizeof(vertices));
    status &= ~SEN_NODE_UPDATE_BBOX;
    status |= SEN_NODE_UPDATE_MODEL;
  }

  update_model = status & SEN_NODE_UPDATE_MODEL;

  if ( status & (SEN_NODE_UPDATE_MODEL | SEN_NODE_UPDATE_COLOR)) {
    //V4F_T2F_C4F vertices[4];
//    memcpy(vertices, self->vertices, 4*sizeof(V4F_T2F_C4F));

    const mat4* model = sen_node_model(self);

    int i;
    for (i=0; i<4; ++i) {
      if (update_model) {
//        vec4* v =  (vec4*) ( i*sizeof(V4F_T2F_C4F )+(self->quad->vertices->items));
        //vec4* v =  (vec4*) ( i*sizeof(V4F_T2F_C4F )+(vertices));
        //vec4* v =  (vec4*)  (& vertices[i]);// ( i*sizeof(V4F_T2F_C4F )+(vertices));
        vec4* vp =  (vec4*)  (& (self->vertices[i]) );
        vec4* v =   (vec4*)  ( (char*)(self->quad->vertices->items) + i*sizeof(V4F_T2F_C4F ) );
        //v4_transform(model->data, v->data,v->data);
        v4_transform(model->data, vp->data,v->data);

        if ( i ) {
          if (v->x < bbox->x) bbox->x = v->x; else if (v->x > bbox->z) bbox->z = v->x;
          if (v->y < bbox->y) bbox->y = v->y; else if (v->y > bbox->w) bbox->w = v->y;
        }
        else {
          bbox->x = bbox->z = v->x;
          bbox->y = bbox->w = v->y;
        }
      }

      if (status & SEN_NODE_UPDATE_COLOR) {
        vec4* c =  (vec4*) ( (char*)(self->quad->vertices->items)+
                             i*sizeof(V4F_T2F_C4F )+
                             sizeof(float)*6);
//        vec4* c =  (vec4*) ( i*sizeof(V4F_T2F_C4F )+sizeof(float)*6+(vertices));
        //vec4* c =  (vec4*) (& (vertices[i].r) );//  i*sizeof(V4F_T2F_C4F )+sizeof(float)*6+(vertices));
//        vec4* c =  (vec4*) (& (self->vertices[i].r) );//  i*sizeof(V4F_T2F_C4F )+sizeof(float)*6+(vertices));
        memcpy(c,col,sizeof(vec4));
      }
    }
    //self->quad->state = 1;
    status &= ~(SEN_NODE_UPDATE_COLOR|SEN_NODE_UPDATE_MODEL|SEN_NODE_UPDATE_PARENT_MODEL);
  }

  ((node_t*)self)->updated = status;
}
示例#21
0
// ------------------------------------------------------------------- main ---
int main( int argc, char **argv )
{
    size_t i, j;
    GLFWwindow* window;

    glfwSetErrorCallback( error_callback );

    if (!glfwInit( ))
    {
        exit( EXIT_FAILURE );
    }

    glfwWindowHint( GLFW_VISIBLE, GL_TRUE );
    glfwWindowHint( GLFW_RESIZABLE, GL_FALSE );

    window = glfwCreateWindow( 1, 1, argv[0], NULL, NULL );

    if (!window)
    {
        glfwTerminate( );
        exit( EXIT_FAILURE );
    }

    glfwMakeContextCurrent( window );
    glfwSwapInterval( 1 );

    glfwSetFramebufferSizeCallback( window, reshape );
    glfwSetWindowRefreshCallback( window, display );
    glfwSetKeyCallback( window, 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_atlas_t * atlas = texture_atlas_new( 512, 512, 3 );
    texture_font_t *fonts[20];
    for ( i=0; i< 20; ++i )
    {
        fonts[i] =  texture_font_new_from_file(atlas, 12+i, font_filename),
        texture_font_load_glyphs(fonts[i], text, direction, language, script );
    }


    typedef struct { float x,y,z, u,v, r,g,b,a, shift, gamma; } vertex_t;
    vbuffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,"
                                "color:4f,ashift:1f,agamma:1f" );

    /* Create a buffer for harfbuzz to use */
    hb_buffer_t *buffer = hb_buffer_create();

    for (i=0; i < 20; ++i)
    {
        hb_buffer_set_direction( buffer, direction );
        hb_buffer_set_script( buffer, script );
        hb_buffer_set_language( buffer,
                                hb_language_from_string(language, strlen(language)) );
        hb_buffer_add_utf8( buffer, text, strlen(text), 0, strlen(text) );
        hb_shape( fonts[i]->hb_ft_font, buffer, NULL, 0 );

        unsigned int         glyph_count;
        hb_glyph_info_t     *glyph_info =
            hb_buffer_get_glyph_infos(buffer, &glyph_count);
        hb_glyph_position_t *glyph_pos =
            hb_buffer_get_glyph_positions(buffer, &glyph_count);

        texture_font_load_glyphs( fonts[i], text,
                                  direction, language, script );

        float gamma = 1.0;
        float shift = 0.0;
        float x = 0;
        float y = 600 - i * (10+i) - 15;
        float width = 0.0;
        float hres = fonts[i]->hres;
        for (j = 0; j < glyph_count; ++j)
        {
            int codepoint = glyph_info[j].codepoint;
            float x_advance = glyph_pos[j].x_advance/(float)(hres*64);
            float x_offset = glyph_pos[j].x_offset/(float)(hres*64);
            texture_glyph_t *glyph = texture_font_get_glyph(fonts[i], codepoint);
            if( i < (glyph_count-1) )
                width += x_advance + x_offset;
            else
                width += glyph->offset_x + glyph->width;
        }

        x = 800 - width - 10 ;
        for (j = 0; j < glyph_count; ++j)
        {
            int codepoint = glyph_info[j].codepoint;
            // because of vhinting trick we need the extra 64 (hres)
            float x_advance = glyph_pos[j].x_advance/(float)(hres*64);
            float x_offset = glyph_pos[j].x_offset/(float)(hres*64);
            float y_advance = glyph_pos[j].y_advance/(float)(64);
            float y_offset = glyph_pos[j].y_offset/(float)(64);
            texture_glyph_t *glyph = texture_font_get_glyph(fonts[i], codepoint);

            float r = 0.0;
            float g = 0.0;
            float b = 0.0;
            float a = 1.0;
            float x0 = x + x_offset + glyph->offset_x;
            float x1 = x0 + glyph->width;
            float y0 = floor(y + y_offset + glyph->offset_y);
            float y1 = floor(y0 - glyph->height);
            float s0 = glyph->s0;
            float t0 = glyph->t0;
            float s1 = glyph->s1;
            float t1 = glyph->t1;
            vertex_t vertices[4] =  {
                {x0,y0,0, s0,t0, r,g,b,a, shift, gamma},
                {x0,y1,0, s0,t1, r,g,b,a, shift, gamma},
                {x1,y1,0, s1,t1, r,g,b,a, shift, gamma},
                {x1,y0,0, s1,t0, r,g,b,a, shift, gamma} };
            GLushort indices[6] = { 0,1,2, 0,2,3 };
            vertex_buffer_push_back( vbuffer, vertices, 4, indices, 6 );
            x += x_advance;
            y += y_advance;
        }
        /* clean up the buffer, but don't kill it just yet */
        hb_buffer_reset(buffer);
    }

    glClearColor(1,1,1,1);
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
    glBindTexture( GL_TEXTURE_2D, atlas->id );
    texture_atlas_upload( atlas );
    vertex_buffer_upload( vbuffer );
    shader = shader_load("shaders/text.vert", "shaders/text.frag");
    mat4_set_identity( &projection );
    mat4_set_identity( &model );
    mat4_set_identity( &view );

    glfwSetWindowSize( window, 800, 600 );
    glfwShowWindow( window );

    while(!glfwWindowShouldClose( window ))
    {
        display( window );
        glfwPollEvents( );
    }

    glfwDestroyWindow( window );
    glfwTerminate( );

    return 0;
}
示例#22
0
// ------------------------------------------------------------------- main ---
int main( int argc, char **argv )
{
    size_t i, j;
    int ptSize = 50*64;
    int device_hdpi = 72;
    int device_vdpi = 72;


    glutInit( &argc, argv );
    glutInitWindowSize( 512, 512 );
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
    glutCreateWindow( argv[0] );
    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_atlas_t * atlas = texture_atlas_new( 512, 512, 3 );


    /* Init freetype */
    FT_Library ft_library;
    assert(!FT_Init_FreeType(&ft_library));

    /* Load our fonts */
    FT_Face ft_face[NUM_EXAMPLES];
    assert(!FT_New_Face( ft_library, fonts[ENGLISH], 0, &ft_face[ENGLISH]) );
    assert(!FT_Set_Char_Size( ft_face[ENGLISH], 0, ptSize, device_hdpi, device_vdpi ) );
    // ftfdump( ft_face[ENGLISH] );            // wonderful world of encodings ...
    force_ucs2_charmap( ft_face[ENGLISH] ); // which we ignore.

    assert( !FT_New_Face(ft_library, fonts[ARABIC], 0, &ft_face[ARABIC]) );
    assert( !FT_Set_Char_Size(ft_face[ARABIC], 0, ptSize, device_hdpi, device_vdpi ) );
    // ftfdump( ft_face[ARABIC] );
    force_ucs2_charmap( ft_face[ARABIC] );

    assert(!FT_New_Face( ft_library, fonts[CHINESE], 0, &ft_face[CHINESE]) );
    assert(!FT_Set_Char_Size( ft_face[CHINESE], 0, ptSize, device_hdpi, device_vdpi ) );
    // ftfdump( ft_face[CHINESE] );
    force_ucs2_charmap( ft_face[CHINESE] );

    /* Get our harfbuzz font structs */
    hb_font_t *hb_ft_font[NUM_EXAMPLES];
    hb_ft_font[ENGLISH] = hb_ft_font_create( ft_face[ENGLISH], NULL );
    hb_ft_font[ARABIC]  = hb_ft_font_create( ft_face[ARABIC] , NULL );
    hb_ft_font[CHINESE] = hb_ft_font_create( ft_face[CHINESE], NULL );

    /* Create a buffer for harfbuzz to use */
    hb_buffer_t *buf = hb_buffer_create();

    for (i=0; i < NUM_EXAMPLES; ++i)
    {
        hb_buffer_set_direction( buf, text_directions[i] ); /* or LTR */
        hb_buffer_set_script( buf, scripts[i] ); /* see hb-unicode.h */
        hb_buffer_set_language( buf,
                                hb_language_from_string(languages[i], strlen(languages[i])) );

        /* Layout the text */
        hb_buffer_add_utf8( buf, texts[i], strlen(texts[i]), 0, strlen(texts[i]) );
        hb_shape( hb_ft_font[i], buf, NULL, 0 );

        unsigned int         glyph_count;
        hb_glyph_info_t     *glyph_info   = hb_buffer_get_glyph_infos(buf, &glyph_count);
        hb_glyph_position_t *glyph_pos    = hb_buffer_get_glyph_positions(buf, &glyph_count);


        FT_GlyphSlot slot;
        FT_Bitmap ft_bitmap;
        float size = 24;
        size_t hres = 64;
        FT_Error error;
        FT_Int32 flags = 0;
        flags |= FT_LOAD_RENDER;
        flags |= FT_LOAD_TARGET_LCD;
        FT_Library_SetLcdFilter( ft_library, FT_LCD_FILTER_LIGHT );
        FT_Matrix matrix = { (int)((1.0/hres) * 0x10000L),
                             (int)((0.0)      * 0x10000L),
                             (int)((0.0)      * 0x10000L),
                             (int)((1.0)      * 0x10000L) };
        /* Set char size */
        error = FT_Set_Char_Size( ft_face[i], (int)(ptSize), 0, 72*hres, 72 );
        if( error )
        {
            //fprintf( stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
            //         __LINE__, FT_Errors[error].code, FT_Errors[error].message );
            FT_Done_Face( ft_face[i] );
            break;
        }

        /* Set transform matrix */
        FT_Set_Transform( ft_face[i], &matrix, NULL );

        for (j = 0; j < glyph_count; ++j)
        {
            /* Load glyph */
            error = FT_Load_Glyph( ft_face[i], glyph_info[j].codepoint, flags );
            if( error )
            {
                //fprintf( stderr, "FT_Error (line %d, code 0x%02x) : %s\n",
                //         __LINE__, FT_Errors[error].code, FT_Errors[error].message );
                FT_Done_Face( ft_face[i] );
                break;
            }

            slot = ft_face[i]->glyph;
            ft_bitmap = slot->bitmap;
            int ft_bitmap_width = slot->bitmap.width;
            int ft_bitmap_rows  = slot->bitmap.rows;
            int ft_bitmap_pitch = slot->bitmap.pitch;
            int ft_glyph_top    = slot->bitmap_top;
            int ft_glyph_left   = slot->bitmap_left;

            int w = ft_bitmap_width/3; // 3 because of LCD/RGB encoding
            int h = ft_bitmap_rows;

            ivec4 region = texture_atlas_get_region( atlas, w+1, h+1 );
            if ( region.x < 0 )
            {
                fprintf( stderr, "Texture atlas is full (line %d)\n",  __LINE__ );
                continue;
            }
            int x = region.x, y = region.y;
            texture_atlas_set_region( atlas, region.x, region.y,
                                      w, h, ft_bitmap.buffer, ft_bitmap.pitch );
            printf("%d: %dx%d %f %f\n",
                   glyph_info[j].codepoint,
                   ft_bitmap_width,
                   ft_bitmap_rows,
                   glyph_pos[j].x_advance/64.,
                   glyph_pos[j].y_advance/64.);
        }

        /* clean up the buffer, but don't kill it just yet */
        hb_buffer_reset(buf);
    }


    /* Cleanup */
    hb_buffer_destroy( buf );
    for( i=0; i < NUM_EXAMPLES; ++i )
        hb_font_destroy( hb_ft_font[i] );
    FT_Done_FreeType( ft_library );

    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 );
    texture_atlas_upload( atlas );

    typedef struct { float x,y,z, u,v, r,g,b,a, shift, gamma; } vertex_t;
    vertex_t vertices[4] =  {
        {  0,  0,0, 0,1, 0,0,0,1, 0, 1},
        {  0,512,0, 0,0, 0,0,0,1, 0, 1},
        {512,512,0, 1,0, 0,0,0,1, 0, 1},
        {512,  0,0, 1,1, 0,0,0,1, 0, 1} };
    GLuint indices[6] = { 0, 1, 2, 0,2,3 };
    buffer = vertex_buffer_new( "vertex:3f,"
                                "tex_coord:2f,"
                                "color:4f,"
                                "ashift:1f,"
                                "agamma:1f" );






    vertex_buffer_push_back( buffer, vertices, 4, indices, 6 );
    shader = shader_load("shaders/text.vert", "shaders/text.frag");
    mat4_set_identity( &projection );
    mat4_set_identity( &model );
    mat4_set_identity( &view );
    glutMainLoop( );
    return 0;
}
示例#23
0
// ------------------------------------------------------------------- main ---
int main( int argc, char **argv )
{

#ifndef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
    fprintf(stderr,
            "This demo requires freetype to be compiled "
            "with subpixel rendering.\n");
    exit( EXIT_FAILURE) ;
#endif

    glutInit( &argc, argv );
    glutInitWindowSize( 260, 330 );
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
    glutCreateWindow( argv[0] );
    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
    buffer = vertex_buffer_new( "vertex:3f,color:4f" );
    vertex_t vertices[4*2] = { { 15,  0,0, 0,0,0,1},
        { 15,330,0, 0,0,0,1},
        {245,  0,0, 0,0,0,1},
        {245,330,0, 0,0,0,1}
    };
    GLuint indices[4*3] = { 0,1,2,3, };
    vertex_buffer_push_back( buffer, vertices, 4, indices, 4 );

    text_buffer = text_buffer_new( LCD_FILTERING_ON );
    vec4 black  = {{0.0, 0.0, 0.0, 1.0}};
    text_buffer->base_color = black;

    vec4 none   = {{1.0, 1.0, 1.0, 0.0}};
    markup_t markup;
    markup.family  = "fonts/Vera.ttf";
    markup.size    = 9.0;
    markup.bold    = 0;
    markup.italic  = 0;
    markup.rise    = 0.0;
    markup.spacing = 0.0;
    markup.gamma   = 1.0;
    markup.foreground_color    = black;
    markup.background_color    = none;
    markup.underline           = 0;
    markup.underline_color     = black;
    markup.overline            = 0;
    markup.overline_color      = black;
    markup.strikethrough       = 0;
    markup.strikethrough_color = black;
    markup.font = 0;

    size_t i;
    vec2 pen = {{20, 320}};
    wchar_t *text = L"| A Quick Brown Fox Jumps Over The Lazy Dog\n";
    for( i=0; i < 30; ++i)
    {
        text_buffer_add_text( text_buffer, &pen, &markup, text, wcslen(text) );
        pen.x += i*0.1;
    }

    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;
}
示例#24
0
// ------------------------------------------------------------------- init ---
void init( void )
{
    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_from_file( atlas, 400, "fonts/Vera.ttf");
    texture_font_t * small = texture_font_new_from_file( atlas, 18, "fonts/Vera.ttf");
    texture_font_t * title = texture_font_new_from_file( atlas, 32, "fonts/Vera.ttf");

    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, "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, "g", &black, &origin );

    // title
    pen.x = 50;
    pen.y = 560;
    add_text( text_buffer, title, "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, "advance_x", &blue, &pen );

    pen.x = width/2 - 20;
    pen.y = .8*height + 3;
    add_text( text_buffer, small, "width", &blue, &pen );

    pen.x = width/2 - glyph->width/2 + 5;
    pen.y = .85*height-8;
    add_text( text_buffer, small, "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, "height", &blue, &pen );

    pen.x = 0.8*width+3;
    pen.y = origin.y + glyph->offset_y/2 -6;
    add_text( text_buffer, small, "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, "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 );
}
示例#25
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;
}
示例#26
0
// ------------------------------------------------------------------- init ---
void init( void )
{
    size_t i, j;

    texture_atlas_t * atlas = texture_atlas_new( 512, 512, 3 );
    texture_font_t *fonts[20];
    for ( i=0; i< 20; ++i )
    {
        fonts[i] =  texture_font_new_from_file(atlas, 12+i, font_filename),
        texture_font_load_glyphs(fonts[i], text, direction, language, script );
    }


    typedef struct { float x,y,z, u,v, r,g,b,a, shift, gamma; } vertex_t;
    vbuffer = vertex_buffer_new( "vertex:3f,tex_coord:2f,"
                                "color:4f,ashift:1f,agamma:1f" );

    /* Create a buffer for harfbuzz to use */
    hb_buffer_t *buffer = hb_buffer_create();

    for (i=0; i < 20; ++i)
    {
        hb_buffer_set_direction( buffer, direction );
        hb_buffer_set_script( buffer, script );
        hb_buffer_set_language( buffer,
                                hb_language_from_string(language, strlen(language)) );
        hb_buffer_add_utf8( buffer, text, strlen(text), 0, strlen(text) );
        hb_shape( fonts[i]->hb_ft_font, buffer, NULL, 0 );

        unsigned int         glyph_count;
        hb_glyph_info_t     *glyph_info =
            hb_buffer_get_glyph_infos(buffer, &glyph_count);
        hb_glyph_position_t *glyph_pos =
            hb_buffer_get_glyph_positions(buffer, &glyph_count);

        texture_font_load_glyphs( fonts[i], text,
                                  direction, language, script );

        float gamma = 1.0;
        float shift = 0.0;
        float x = 0;
        float y = 600 - i * (10+i) - 15;
        float width = 0.0;
        float hres = fonts[i]->hres;
        for (j = 0; j < glyph_count; ++j)
        {
            int codepoint = glyph_info[j].codepoint;
            float x_advance = glyph_pos[j].x_advance/(float)(hres*64);
            float x_offset = glyph_pos[j].x_offset/(float)(hres*64);
            texture_glyph_t *glyph = texture_font_get_glyph(fonts[i], codepoint);
            if( i < (glyph_count-1) )
                width += x_advance + x_offset;
            else
                width += glyph->offset_x + glyph->width;
        }

        x = 800 - width - 10 ;
        for (j = 0; j < glyph_count; ++j)
        {
            int codepoint = glyph_info[j].codepoint;
            // because of vhinting trick we need the extra 64 (hres)
            float x_advance = glyph_pos[j].x_advance/(float)(hres*64);
            float x_offset = glyph_pos[j].x_offset/(float)(hres*64);
            float y_advance = glyph_pos[j].y_advance/(float)(64);
            float y_offset = glyph_pos[j].y_offset/(float)(64);
            texture_glyph_t *glyph = texture_font_get_glyph(fonts[i], codepoint);

            float r = 0.0;
            float g = 0.0;
            float b = 0.0;
            float a = 1.0;
            float x0 = x + x_offset + glyph->offset_x;
            float x1 = x0 + glyph->width;
            float y0 = floor(y + y_offset + glyph->offset_y);
            float y1 = floor(y0 - glyph->height);
            float s0 = glyph->s0;
            float t0 = glyph->t0;
            float s1 = glyph->s1;
            float t1 = glyph->t1;
            vertex_t vertices[4] =  {
                {x0,y0,0, s0,t0, r,g,b,a, shift, gamma},
                {x0,y1,0, s0,t1, r,g,b,a, shift, gamma},
                {x1,y1,0, s1,t1, r,g,b,a, shift, gamma},
                {x1,y0,0, s1,t0, r,g,b,a, shift, gamma} };
            GLuint indices[6] = { 0,1,2, 0,2,3 };
            vertex_buffer_push_back( vbuffer, vertices, 4, indices, 6 );
            x += x_advance;
            y += y_advance;
        }
        /* clean up the buffer, but don't kill it just yet */
        hb_buffer_reset(buffer);
    }

    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 );
    texture_atlas_upload( atlas );
    vertex_buffer_upload( vbuffer );
    shader = shader_load("shaders/text.vert", "shaders/text.frag");
    mat4_set_identity( &projection );
    mat4_set_identity( &model );
    mat4_set_identity( &view );
}