Beispiel #1
0
void FontRenderer::RenderText(unsigned int x, unsigned int y, const char* pText)
{
    bool IsCullEnabled = glIsEnabled(GL_CULL_FACE);
    
    glDisable(GL_CULL_FACE);
    
    assert(strlen(pText) < MAX_STRING_LEN);
        
    wchar_t text[MAX_STRING_LEN] = { 0 };
    
    int len = mbstowcs(text, pText, strlen(pText));
    assert(len > 0);

    vertex_buffer_clear( m_pTextBuffer );
    
    TextureGlyph* pGlyph = texture_font_get_glyph( m_pFont, text[0] );
    
    assert(pGlyph);

    Pen pen = {(float)x, (float)y};
    texture_glyph_add_to_vertex_buffer( pGlyph, m_pTextBuffer, &markup, &pen, 0 );
    
    for( size_t i=1; i<wcslen(text); ++i )
    {
        pGlyph = texture_font_get_glyph( m_pFont, text[i] );
        assert(pGlyph);
        
        int kerning = texture_glyph_get_kerning( pGlyph, text[i-1] );
        texture_glyph_add_to_vertex_buffer( pGlyph, m_pTextBuffer, &markup, &pen, kerning );
    }
    
    glActiveTexture(GL_TEXTURE0);
    glBindTexture( GL_TEXTURE_2D, m_pManager->atlas->texid );

    m_fontShader.Enable();
    
    int viewport[4];
    glGetIntegerv( GL_VIEWPORT, viewport );

    float xScale = 2.0f / (float)viewport[2];
    float yScale = 2.0f / (float)viewport[3];
    
    GLfloat Trans[] = { xScale, 0.0f,   0.0f, -1.0f,
                        0.0f,   yScale, 0.0f, -1.0f,
                        0.0f,   0.0f,   1.0f,  0.0f,
                        0.0f,   0.0f,   0.0f,  1.0f };

    m_fontShader.SetTransformation(Trans);
    
    vertex_buffer_render( m_pTextBuffer, GL_TRIANGLES, "vtc" );
    
    if (IsCullEnabled) {
        glEnable(GL_CULL_FACE);
    }
}
// ------------------------------------------------------------------- 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 );
}
Beispiel #3
0
// --------------------------------------------------------------- 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;
        }
    }
}
Beispiel #4
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;
}
Beispiel #5
0
	Vector2 Render::GetTextSize(const Font& font, const std::string& text) {
		float totalW = 0;
		float totalH = 0;

		float cx = 0;
		float cy = 0;
		unsigned long len = text.size();

		for (unsigned long i = 0; i < len; i++) {
			char l = text[i];

			texture_glyph_t* glyph = texture_font_get_glyph(font.FontHandle, (wchar_t)text[i]);
			if (glyph == null) {
				TL_ASSERT(false);
				return Vector2::Zero;
			}

			if (i > 0) {
				cx += texture_glyph_get_kerning(glyph, text[i - 1]);
			}

			if (l == '\n') {
				cy += font.FontHandle->height;
				cx = 0;
				continue;
			}

			cx += glyph->advance_x;
			if (cx > totalW) totalW = cx;
			if (cy + font.FontHandle->height > totalH) totalH = cy + font.FontHandle->height;
		}

		return Vector2(totalW, totalH);
	}
void opengl_font_size(
	const wchar_t* text, 
	mFloat* x, 
	mFloat* y)
{	
	opengl_font_t* font = (opengl_font_t*)current_font->data;

	if(x)
	{
		size_t i,
		       len = wcslen(text);
		
		int last_offset;

		mFloat totx = (mFloat)0.0;
		
		for(i = 0 ; i < len ; i++)
		{
			texture_glyph_t *glyph = texture_font_get_glyph(font->font, text[i]);

			if(glyph == NULL)
				continue;

			totx += glyph->advance_x / window_zoom;// - texture_glyph_get_kerning(glyph, text[i]) / window_zoom;
			last_offset = glyph->offset_x;
		}
		
		*x = totx - last_offset;
	}

	if(y)
		*y = (int)font->font->height / window_zoom;
}
Beispiel #7
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;
			}
		}
	}
TextureGlyph* TextureFont::GetGlyph(wchar_t charcode) {
    texture_glyph_t* glypht = texture_font_get_glyph(static_cast<texture_font_t*>(self_),
                                                    charcode);
    TextureGlyph*& glyphp = glyphs_[static_cast<void*>(glypht)];
    if(!glyphp)
        glyphp = new TextureGlyph(static_cast<void*>(glypht));
    return glyphp;
}
Beispiel #9
0
	Vector2 Render::GetTextSize(char letter) {
		texture_glyph_t* glyph = texture_font_get_glyph(this->DefaultFont->FontHandle, (wchar_t)letter);
		if (glyph == null) {
			TL_ASSERT(false);
			return Vector2::Zero;
		}

		return Vector2((float)glyph->width, (float)glyph->height);
	}
Beispiel #10
0
/**
 * @text
 * @floatarray [offsetx,offsety,width,height,s0,t0,s1,t1]
 * @start optional
 * @end optional
 */
METHOD_BEGIN(glyphs, info) {
    HandleScope scope;
    Font* font = internalPtr<Font>(info, CLASS_Font);
    if(font == 0) {
        return;
    }

    // text
    v8::Local<v8::String> tmp = info[0]->ToString();
    int length = tmp->Length();
    uint16_t uchars[length + 1];
    tmp->Write(uchars);

    // Float32Array
    ClassBase* ptr = internalArg<ClassBase>(info[1], CLASS_Float32Array);
    if(ptr == 0) {
        ThrowException(String::New("Font.measure Float32Array not found"));
        return;
    }
    ByteBuffer buf;
    ptr->getUnderlying(&buf);
    
    // start and end
    int start = 0;
    int end = length;
    if(info.Length() >= 3) {
        start = info[2]->Uint32Value();
    }
    if(info.Length() >= 4) {
        end = info[3]->Uint32Value();
    }

    // setup
    float empty[8] = { 0,0,0,0,0,0,0,0 };
    int starti = 0;
    for(int i = start; i < end; i++) {
        texture_glyph_t *glyph = texture_font_get_glyph(font->font, uchars[i] );
        if(glyph != NULL) {
            float values[8] = { 0,0,0,0,glyph->s0,glyph->t0,glyph->s1,glyph->t1 };
            values[0] = glyph->offset_x;
            values[1] = glyph->offset_y;
            values[2] = glyph->width;
            values[3] = glyph->height;
            buf.set_value<float>(starti, values, 8);
        } else {
            buf.set_value<float>(starti, empty, 8);
        }
        starti += 8;
    }
}
Beispiel #11
0
/**
 * @text
 * @floatarray [advance,kerning...]
 * @start optional
 * @end optional
 */
METHOD_BEGIN(measure, info) {
    HandleScope scope;
    Font* font = internalPtr<Font>(info, CLASS_Font);
    if(font == 0) {
        return;
    }

    // text
    v8::Local<v8::String> tmp = info[0]->ToString();
    int length = tmp->Length();
    uint16_t uchars[length + 1];
    tmp->Write(uchars);

    // Float32Array
    ClassBase* ptr = internalArg<ClassBase>(info[1], CLASS_Float32Array);
    if(ptr == 0) {
        ThrowException(String::New("Font.measure Float32Array not found"));
        return;
    }
    ByteBuffer buf;
    ptr->getUnderlying(&buf);

    // start and end
    int start = 0;
    int end = length;
    if(info.Length() >= 3) {
        start = info[2]->Uint32Value();
    }
    if(info.Length() >= 4) {
        end = info[3]->Uint32Value();
    }

    // setup
    for(int i = start; i < end; i++) {
        texture_glyph_t *glyph = texture_font_get_glyph(font->font, uchars[i] );
        if(glyph != NULL) {
            if(i > 0) {
                float values[2] = { glyph->advance_x, texture_glyph_get_kerning(glyph, uchars[i - 1]) };
                buf.set_value<float>((i - start) * 2, values, 2);
            } else {
                float values[2] = { glyph->advance_x, 0 };
                buf.set_value<float>((i - start) * 2, values, 2);
            }
        } else {
            float values[2] = { 0, 0 };
            buf.set_value<float>((i - start) * 2, values, 2);
        }
    }
}
Beispiel #12
0
float OLabel::getCharWidth(const char& c)
{
    float width = 0;
    
    const maths::vec2& scale = m_Font->GetScale();
    ftgl::texture_font_t* ftFont = m_Font->GetFTFont();

    ftgl::texture_glyph_t* glyph = texture_font_get_glyph(ftFont, c);
    if (glyph != nullptr) {
        float gwidth = glyph->advance_x / scale.x;
        width += gwidth;
    }
    
    return width;
}
// ---------------------------------------------------------------- display ---
void
display( void )
{
    glClearColor(1.0,1.0,1.0,1.0);
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, atlas->id);
    glEnable( GL_TEXTURE_2D );
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

    GLuint handle = glGetUniformLocation( program, "texture" );
    glUniform1i( handle, 0);

    texture_glyph_t * glyph = texture_font_get_glyph( font, L'@');

    float s0 = glyph->s0;
    float t0 = glyph->t0;
    float s1 = glyph->s1;
    float t1 = glyph->t1;

    int width = 512;
    int height = 512;
    if( glyph->width > glyph->height )
        height = glyph->height * width/(float)glyph->width;
    else
        width = glyph->width * height/(float)glyph->height;
    int x = 0 - width/2;
    int y = 0 - height/2;

    glPushMatrix();
    glTranslatef(256,256,0);
    glRotatef(angle, 0,0,1);
    float s = .025+.975*(1+cos(angle/100.0))/2.;
    glScalef(s,s,s);

    glBegin(GL_QUADS);
    glTexCoord2f( s0, t1 ); glVertex2f( x, y );
    glTexCoord2f( s0, t0 ); glVertex2f( x, y+height );
    glTexCoord2f( s1, t0 ); glVertex2f( x+width, y+height );
    glTexCoord2f( s1, t1 ); glVertex2f( x+width, y );
    glEnd();
    glPopMatrix();

    glutSwapBuffers( );
}
// ---------------------------------------------------------------- display ---
void display( GLFWwindow* window )
{
    glClearColor(1.0,1.0,1.0,1.0);
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, atlas->id);
    glEnable( GL_TEXTURE_2D );
    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

    texture_glyph_t * glyph = texture_font_get_glyph( font, "@");

    int width = 512;
    int height = 512;
    float glyph_height = glyph->height * width/(float)glyph->width;
    float glyph_width  = glyph->width * height/(float)glyph->height;
    int x = -glyph_width/2 + 512/2.;
    int y = -glyph_height/2 + 512/2.;

    float s = .025+.975*(1+cos(angle/100.0))/2.;

    vec4 color = {{1.0, 1.0, 1.0, 1.0 }};

    mat4_set_identity( &model );
    mat4_scale( &model, width * s, width * s, 1 );
    mat4_rotate( &model, angle, 0, 0, 1 );
    mat4_translate( &model, 256, 256, 0 );

    glUseProgram( program );
    {
        glUniform1i( glGetUniformLocation( program, "u_texture" ),
                     0);
        glUniform4f( glGetUniformLocation( program, "u_color" ),
                     color.r, color.g, color.b, color.a);
        glUniformMatrix4fv( glGetUniformLocation( program, "u_model" ),
                            1, 0, model.data);
        glUniformMatrix4fv( glGetUniformLocation( program, "u_view" ),
                            1, 0, view.data);
        glUniformMatrix4fv( glGetUniformLocation( program, "u_projection" ),
                            1, 0, projection.data);

        vertex_buffer_render( buffer, GL_TRIANGLES );
    }

    glfwSwapBuffers( window );
}
    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;
            }
        }
    }
// --------------------------------------------------------------- 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;
}
// --------------------------------------------------------------- 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;
}
Beispiel #18
0
float OLabel::getWordWidth(const std::string& word)
{
    float width = 0;
    
    const maths::vec2& scale = m_Font->GetScale();
    ftgl::texture_font_t* ftFont = m_Font->GetFTFont();
    for (uint i = 0; i < word.length(); i++)
    {
        char c = word[i];
        ftgl::texture_glyph_t* glyph = texture_font_get_glyph(ftFont, c);
        if (glyph != nullptr) {
            if (i > 0)
            {
                float kerning = texture_glyph_get_kerning(glyph, m_Text[i - 1]);
                width += kerning / scale.x;
            }
            float gwidth = glyph->advance_x / scale.x;
            width += gwidth;
        }
    }
    return width;
}
Beispiel #19
0
// --------------------------------------------------------------- add_text ---
void add_text( vertex_buffer_t * buffer, texture_font_t * font,
               char * 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 < 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 index = buffer->vertices->size;
            GLuint indices[] = {index, index+1, index+2,
                                index, index+2, index+3};
            vertex_t vertices[] = { { x0,y0,0,  s0,t0,  r,g,b,a, 0,1 },
                                    { x0,y1,0,  s0,t1,  r,g,b,a, 0,1 },
                                    { x1,y1,0,  s1,t1,  r,g,b,a, 0,1 },
                                    { x1,y0,0,  s1,t0,  r,g,b,a, 0,1 } };
            vertex_buffer_push_back_indices( buffer, indices, 6 );
            vertex_buffer_push_back_vertices( buffer, vertices, 4 );
            pen->x += glyph->advance_x;
        }
    }
}
Beispiel #20
0
// --------------------------------------------------------------- add_text ---
void add_text( vertex_buffer_t * buffer, texture_font_t * font,
               char *text, vec2 pen, vec4 fg_color_1, vec4 fg_color_2 )
{
    size_t i;
    for( i = 0; i < strlen(text); ++i )
    {
        texture_glyph_t *glyph = texture_font_get_glyph( font, text + i );
        float kerning = 0.0f;
        if( i > 0)
        {
            kerning = texture_glyph_get_kerning( glyph, text + i - 1 );
        }
        pen.x += kerning;

        /* Actual glyph */
        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;
        GLuint index = buffer->vertices->size;
        GLuint indices[] = {index, index+1, index+2,
                            index, index+2, index+3};
        vertex_t vertices[] = {
            { (int)x0,y0,0,  s0,t0,  fg_color_1 },
            { (int)x0,y1,0,  s0,t1,  fg_color_2 },
            { (int)x1,y1,0,  s1,t1,  fg_color_2 },
            { (int)x1,y0,0,  s1,t0,  fg_color_1 } };
        vertex_buffer_push_back_indices( buffer, indices, 6 );
        vertex_buffer_push_back_vertices( buffer, vertices, 4 );
        pen.x += glyph->advance_x;
    }
}
Beispiel #21
0
// ------------------------------------------------------- texture_font_new ---
texture_font_t *
texture_font_new( texture_atlas_t * atlas,
                  const char * filename,
                  const float size)
{
    assert( filename );
    assert( size );

    texture_font_t *self = (texture_font_t *) malloc( sizeof(texture_font_t) );
    if( self == NULL)
    {
        fprintf( stderr,
                 "line %d: No more memory for allocating data\n", __LINE__ );
        exit( EXIT_FAILURE );
    }
    self->glyphs = vector_new( sizeof(texture_glyph_t *) );
    self->atlas = atlas;
    self->height = 0;
    self->ascender = 0;
    self->descender = 0;
    self->filename = strdup( filename );
    self->size = size;
    self->outline_type = 0;
    self->outline_thickness = 0.0;
    self->hinting = 1;
    self->filtering = 1;
    // FT_LCD_FILTER_LIGHT   is (0x00, 0x55, 0x56, 0x55, 0x00)
    // FT_LCD_FILTER_DEFAULT is (0x10, 0x40, 0x70, 0x40, 0x10)
    self->lcd_weights[0] = 0x10;
    self->lcd_weights[1] = 0x40;
    self->lcd_weights[2] = 0x70;
    self->lcd_weights[3] = 0x40;
    self->lcd_weights[4] = 0x10;

    /* Get font metrics at high resolution */
    FT_Library library;
    FT_Face face;
    if( !texture_font_load_face( &library, self->filename, self->size*100, &face ) )
    {
        return self;
    }

    // 64 * 64 because of 26.6 encoding AND the transform matrix used
    // in texture_font_load_face (hres = 64)
    self->underline_position = face->underline_position / (float)(64.0f*64.0f) * self->size;
    self->underline_position = round( self->underline_position );
    if( self->underline_position > -2 )
    {
        self->underline_position = -2.0;
    }

    self->underline_thickness = face->underline_thickness / (float)(64.0f*64.0f) * self->size;
    self->underline_thickness = round( self->underline_thickness );
    if( self->underline_thickness < 1 )
    {
        self->underline_thickness = 1.0;
    }

    FT_Size_Metrics metrics = face->size->metrics; 
    self->ascender = (metrics.ascender >> 6) / 100.0;
    self->descender = (metrics.descender >> 6) / 100.0;
    self->height = (metrics.height >> 6) / 100.0;
    self->linegap = self->height - self->ascender + self->descender;
    FT_Done_Face( face );
    FT_Done_FreeType( library );

    /* -1 is a special glyph */
    texture_font_get_glyph( self, -1 );

    return self;
}
// --------------------------------------------------------------- add_text ---
void add_text( vertex_buffer_t * buffer, vec2 * pen, ... )
{
    markup_t *markup;
    char *text;
    va_list args;
    va_start ( args, pen );

    do {
        markup = va_arg( args, markup_t * );
        if( markup == NULL )
        {
            break;
        }
        text = va_arg( args, char * );

        size_t i;
        texture_font_t * font = markup->font;
        float r = markup->foreground_color.red;
        float g = markup->foreground_color.green;
        float b = markup->foreground_color.blue;
        float a = markup->foreground_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;

                /* Actual glyph */
                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;
                GLuint index = buffer->vertices->size;
                GLuint indices[] = {index, index+1, index+2,
                                    index, index+2, index+3
                                   };
                vertex_t vertices[] = {
                    { (int)x0,y0,0,  s0,t0,  r,g,b,a },
                    { (int)x0,y1,0,  s0,t1,  r,g,b,a },
                    { (int)x1,y1,0,  s1,t1,  r,g,b,a },
                    { (int)x1,y0,0,  s1,t0,  r,g,b,a }
                };
                vertex_buffer_push_back_indices( buffer, indices, 6 );
                vertex_buffer_push_back_vertices( buffer, vertices, 4 );
                pen->x += glyph->advance_x;
            }

        }
    } while( markup != 0 );
    va_end ( args );
}
Beispiel #23
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);
    }
}
Beispiel #24
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;
}
Beispiel #25
0
// ----------------------------------------------------------- build_buffer ---
void
build_buffer( void )
{ 
    vec2 pen;
    size_t i;
    texture_font_t *font;
    texture_glyph_t *glyph;

    vec4 white  = {{1.0, 1.0, 1.0, 1.0}};
    vec4 none   = {{1.0, 1.0, 1.0, 0.0}};
    markup_t markup = {
        .family  = "Arial",
        .size    = 10.0,
        .bold    = 0,
        .italic  = 0,
        .rise    = 0.0,
        .spacing = 0.0,
        .gamma   = 2.2,
        .foreground_color    = white,
        .background_color    = none,
        .underline           = 0,
        .underline_color     = white,
        .overline            = 0,
        .overline_color      = white,
        .strikethrough       = 0,
        .strikethrough_color = white,
        .font = 0,
    };



    vertex_buffer_clear( buffer );
    texture_atlas_clear( atlas );

    if( p_family == VERA)
    {
        font = texture_font_new( atlas, "fonts/Vera.ttf", p_size );
    }
    else if( p_family == VERA_MONO)
    {
        font = texture_font_new( atlas, "fonts/VeraMono.ttf", p_size );
    }
    else if( p_family == GEORGIA)
    {
        font = texture_font_new( atlas, "fonts/Georgia.ttf", p_size );
    }
    else if( p_family == TIMES )
    {
        font = texture_font_new( atlas, "fonts/Times.ttf", p_size );
    }
    else if( p_family == TAHOMA )
    {
        font = texture_font_new( atlas, "fonts/Tahoma.ttf", p_size );
    }
    else if( p_family == ARIAL )
    {
        font = texture_font_new( atlas, "fonts/Arial.ttf", p_size );
    }
    else if( p_family == VERDANA )
    {
        font = texture_font_new( atlas, "fonts/Verdana.ttf", p_size );
    }
    else
    {
        fprintf( stderr, "Error : Unknown family type\n" );
        return;
    }

    font->hinting = p_hinting;
    font->filtering = 1;
    float norm = 1.0/(p_primary + 2*p_secondary + 2*p_tertiary);
    font->lcd_weights[0] = (unsigned char)(p_tertiary*norm*256);
    font->lcd_weights[1] = (unsigned char)(p_secondary*norm*256);
    font->lcd_weights[2] = (unsigned char)(p_primary*norm*256);
    font->lcd_weights[3] = (unsigned char)(p_secondary*norm*256);
    font->lcd_weights[4] = (unsigned char)(p_tertiary*norm*256);

    texture_font_load_glyphs( font, 
                              L" !\"#$%&'()*+,-./0123456789:;<=>?"
                              L"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
                              L"`abcdefghijklmnopqrstuvwxyz{|}~" );
    pen.x = 10;
    pen.y = 600 - font->height - 10;

    glyph = texture_font_get_glyph( font, text[0] );
    add_glyph( glyph, buffer, &markup, &pen, 0 );
    for( i=1; i<wcslen(text); ++i )
    {
        if( text[i] == '\n' )
        {
            pen.x  = 10;
            pen.y -= font->height; // + 0.01*(size - (int)size)*font->height;
        }
        else
        {
            glyph = texture_font_get_glyph( font, text[i] );
            float kerning = 0.0;
            if( p_kerning )
            {
                kerning = texture_glyph_get_kerning( glyph, text[i-1] );
            }
            add_glyph( glyph, buffer, &markup, &pen, kerning );
        }
    }

    texture_font_delete (font );
}



// ---------------------------------------------------------------- display ---
void display(void)
{
    if( p_invert )
    {
        glClearColor( 0, 0, 0, 1 );
    }
    else
    {
        glClearColor( 1, 1, 1, 1 );
    }
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glEnable( GL_TEXTURE_2D );
    glBindTexture( GL_TEXTURE_2D, atlas->id );
    if( !p_lcd_filtering )
    {
        glEnable( GL_COLOR_MATERIAL );
        glEnable( GL_BLEND );
        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
        if( p_invert )
        {
            glColor4f(1,1,1,1);
        }
        else
        {
            glColor4f(0,0,0,1);
        }
    }
    else
    {
        glEnable( GL_COLOR_MATERIAL );
        glBlendFunc( GL_CONSTANT_COLOR_EXT,
                     GL_ONE_MINUS_SRC_COLOR );
        glEnable( GL_BLEND );
        glColor3f( 1,1,1 );
        if( p_invert )
        {
            glBlendColor( 1, 1, 1, 1 );
        }
        else
        {
            glBlendColor( 0, 0, 0, 1 );
        }
    }

    if( !p_lcd_filtering )
    {
        vertex_buffer_render( buffer, GL_TRIANGLES, "vt" );
    }
    else
    {
        glUseProgram( program );
        glUniform1i( texture_location, 0 );
        glUniform1f( gamma_location, p_gamma );

        float norm = 1.0/(p_primary+2*p_secondary+2*p_tertiary);
        glUniform1f( primary_location,   p_primary*norm );
        glUniform1f( secondary_location, p_secondary*norm );
        glUniform1f( tertiary_location,  p_tertiary*norm );
        glUniform2f( pixel_location,
                     1.0/atlas->width,
                     1.0/atlas->height );
        vertex_buffer_render( buffer, GL_TRIANGLES, "vtc" );
        glUseProgram( 0 );
    }

    TwDraw( );
    glutSwapBuffers( );
}


// ---------------------------------------------------------------- reshape ---
void reshape( int width, int height )
{
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, width, 0, height, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    TwWindowSize( width, height );
}
void modelEngine::add_text(texture_font_t * font, wchar_t * text, vec4 * color, vec2 * pen, GLuint vertexBuffer, GLfloat Zoffset)
{
    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;

			GLfloat indices[6] = {0,1,2, 0,2,3};
			GLfloat vertexCoordinates[] = {
				x0,y0,Zoffset,
				x0,y1,Zoffset,
				x1,y1,Zoffset,
				x0,y0,Zoffset,
				x1,y1,Zoffset,
				x1,y0,Zoffset,
			};
			for(int i = 0; i < 18; i++)
			{
				vertexCoordinates[i] = vertexCoordinates[i] / 1000;
			}

			GLfloat textureCoordinates[] = {
				s0,t0,
				s0,t1,
				s1,t1,
				s0,t0,
				s1,t1,
				s1,t0,
			};

			GLfloat colors[] = {
				r, g, b, a,
				r, g, b, a,
				r, g, b, a,
				r, g, b, a,
				r, g, b, a,
				r, g, b, a,
			};

            GLfloat 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,
              x0,y0,0,
              s0,t0,
              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;
			// Store vertices to buffer
			// Generate buffer
			GLuint verticeBuffer = 0;
			GLuint textureBuffer = 0;
			GLuint colorBuffer = 0;

			// Generate vertex buffer
			glGenBuffers(1, &verticeBuffer);
			// Bind buffer
			glBindBuffer(GL_ARRAY_BUFFER, verticeBuffer);
			// Create buffer data
			glBufferData(GL_ARRAY_BUFFER, 216, &vertexCoordinates, GL_STATIC_DRAW);
			// Unbind buffer
			glBindBuffer(GL_ARRAY_BUFFER, 0); 
			// Generate texture buffer
			glGenBuffers(1, &textureBuffer);
			// Bind buffer
			glBindBuffer(GL_ARRAY_BUFFER, textureBuffer);
			// Create buffer data
			glBufferData(GL_ARRAY_BUFFER, 48, &textureCoordinates, GL_STATIC_DRAW);
			// Unbind buffer
			glBindBuffer(GL_ARRAY_BUFFER, 0); 
			// Generate color buffer
			glGenBuffers(1, &colorBuffer);
			// Bind buffer
			glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
			// Create buffer data
			glBufferData(GL_ARRAY_BUFFER, 48, &colors, GL_STATIC_DRAW);
			// Unbind buffer
			glBindBuffer(GL_ARRAY_BUFFER, 0); 

			// Enabling color array makes font dissapear
			//glEnableClientState(GL_COLOR_ARRAY);

			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glEnableClientState( GL_VERTEX_ARRAY );

			//glDisable(GL_TEXTURE_2D);
			//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
			//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);

			// Start with a clear screen
			glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

			// Draw on screen
			// Bind texture
			glBindTexture(GL_TEXTURE_2D, atlas->id);
			// Bind buffers
			// Bind vertex buffer
			glBindBuffer(GL_ARRAY_BUFFER, verticeBuffer);
			glVertexPointer(3, GL_FLOAT, 0, NULL);
			// Bind texture buffer
			glBindBuffer(GL_ARRAY_BUFFER, textureBuffer);
			glTexCoordPointer(2, GL_FLOAT, 0, NULL);
			// Bind color buffer
			glBindBuffer(GL_ARRAY_BUFFER, colorBuffer); 
			glColorPointer(4, GL_FLOAT, 0, NULL);
	
			glPushMatrix();

			// Move model
			glTranslatef(0.0f,0.0f,20.0f);
			// Rotate model
			glRotatef(0.0f, 1.0, 0.0, 0.0);
			glRotatef(0.0f, 0.0, 1.0, 0.0);
			glRotatef(0.0f, 0.0, 0.0, 1.0);
			// Scale model
			glScalef(15.0f,15.0f,15.0f);

			glColor4f(0.0f, 0.6f, 1.0f, 0.5f);

			glDrawArrays(GL_TRIANGLES, 0, 6);

			// Display
			eglSwapBuffers(state.display, state.surface);

			glBindBuffer(GL_ARRAY_BUFFER, 0);
			glEnableClientState(GL_NORMAL_ARRAY);
			glDisableClientState(GL_COLOR_ARRAY);
			glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
			//glEnable(GL_TEXTURE_2D);
			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
			glPopMatrix();
		}
    }
}
Beispiel #27
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 );
    }


}
// Text functions
// Create text string with specified font
// Begin at [0,0]
// Store data to modelText[modelIndex]
int modelEngine::createText(int modelIndex, texture_font_t * font, wchar_t * text, vec4 * color, vec2 * pen, vec3 * offset, vec2 * scale)
{
	size_t i;
	vec2 startPen = *pen;
	//Zoffset = Zoffset * 400;
	// Make room to store vertices and texture coordinates for 50 characters
	GLfloat vertices[3600];
	int verticesIndex = 0;
	GLfloat texCoordinates[2400];
	int texIndex = 0;
	// Return -1 if model index is invalid
	if(modelIndex == -1)
	{
		return -1;
	}
    float r = color->red, g = color->green, b = color->blue, a = color->alpha;
    for( i=0; i<wcslen(text); ++i )
    {
		// Check for special character
		wchar_t currentChar = text[i];
		wchar_t* currentCharPointer = text + i;
		//wchar_t newLineChar = L"\n";
		//if((text + i) == L"\n")
		int result = wcsncmp(currentCharPointer, L"\n", 1);
		if(result == 0)
		{
			// New line found
			pen->x = startPen.x;
			pen->y = startPen.y - font->height;
			startPen.y = pen->y;
		}
        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;

			GLfloat vertexCoordinates[] = {
				x0,y0,0,
				x0,y1,0,
				x1,y1,0,
				x0,y0,0,
				x1,y1,0,
				x1,y0,0,
			};
			for(int i = 0; i < 18; i++)
			{
				vertexCoordinates[i] = vertexCoordinates[i] / 400;
			}
			GLfloat textureCoordinates[] = {
				s0,t0,
				s0,t1,
				s1,t1,
				s0,t0,
				s1,t1,
				s1,t0,
			};
			// Copy vertex data
			memcpy (vertices + verticesIndex, vertexCoordinates, 18 * sizeof(GLfloat));
			// Increase pointer 
			verticesIndex += 18;
			// Copy texture data
			memcpy (texCoordinates + texIndex, textureCoordinates, 12 * sizeof(GLfloat));
			// Increase pointer
			texIndex += 12;
			// Increase pen position
			pen->x += glyph->advance_x;
		}
	}
	// Scale all data in X and Y direction
	for(int i = 0; i < verticesIndex; i+=3)
	{
		vertices[i] = vertices[i] * scale->x;
		vertices[i+1] = vertices[i+1] * scale->y;
	}
	// Store data to buffers
	// First, orphan GL buffers
	// Check if text has been enabled
	if(modelText[modelIndex].textReady != 0)
	{
		glDeleteBuffers(1,  &modelText[modelIndex].vertexBuffer);
		glDeleteBuffers(1,  &modelText[modelIndex].texBuffer);
		//orphanArrayBuffer(modelText[modelIndex].vertexBuffer, modelText[modelIndex].vertexBufferSize);
		//orphanArrayBuffer(modelText[modelIndex].texBuffer, modelText[modelIndex].texBufferSize);
	}

	// Generate vertex buffer
	glGenBuffers(1, &modelText[modelIndex].vertexBuffer);
	// Bind buffer
	glBindBuffer(GL_ARRAY_BUFFER, modelText[modelIndex].vertexBuffer);
	// Create buffer data
	glBufferData(GL_ARRAY_BUFFER, verticesIndex * sizeof(GLfloat), &vertices, GL_STATIC_DRAW);
	checkGLError();
	// Unbind buffer
	glBindBuffer(GL_ARRAY_BUFFER, 0); 
	// Store number of vertices
	modelText[modelIndex].vertexBufferSize = verticesIndex;

	// Generate texture buffer
	glGenBuffers(1, &modelText[modelIndex].texBuffer);
	// Bind buffer
	glBindBuffer(GL_ARRAY_BUFFER, modelText[modelIndex].texBuffer);
	// Create buffer data
	glBufferData(GL_ARRAY_BUFFER, texIndex * sizeof(GLfloat), &texCoordinates, GL_STATIC_DRAW);
	checkGLError();
	// Unbind buffer
	glBindBuffer(GL_ARRAY_BUFFER, 0); 
	// Store number of vertices
	modelText[modelIndex].texBufferSize = texIndex;

	// Store number of characters
	modelText[modelIndex].characters = wcslen(text);

	// Store font color
	modelText[modelIndex].fontColor.r = color->r;
	modelText[modelIndex].fontColor.g = color->g;
	modelText[modelIndex].fontColor.b = color->b;
	modelText[modelIndex].fontColor.a = color->a;
	// Store font offset on model
	modelText[modelIndex].offset = *offset;

	modelText[modelIndex].textReady = 1;

	return 0;
}
Beispiel #29
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;
}
Beispiel #30
0
// ------------------------------------------------------------------- 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;
}