예제 #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;
        }
    }
}
예제 #3
0
파일: Render.cpp 프로젝트: edunad/TomatoLib
	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);
	}
예제 #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
파일: freetypeGL.cpp 프로젝트: Eizen/ogldev
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);
    }
}
예제 #6
0
파일: Font.cpp 프로젝트: hurry07/v8
/**
 * @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);
        }
    }
}
예제 #7
0
    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;
            }
        }
    }
예제 #8
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;
}
예제 #9
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;
}
예제 #10
0
파일: OLabel.cpp 프로젝트: Uliori/Origami
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;
}
예제 #11
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;
        }
    }
}
예제 #12
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;
    }
}
예제 #13
0
void mesh_init_vertices_text() 
{
	int i,j,k, kerning = 0;
	float x0,y0,x1,y1;
	float s0,t0,s1,t1;
	float base_x = m_text.base_1_x;
	float base_y = m_text.base_1_y;
	texture_glyph_t *glyph;
	m_text.char_len_1 = swprintf(m_text.text_1, 8, L"%d/%d", m_info.next_image, m_info.image_count);
	if(m_text.char_len_1 > 0)
	{
		for(i=0;i<m_text.char_len_1;i++)
		{
			glyph = texture_font_get_glyph(m_texture.text_font, m_text.text_1[i]);
			if( glyph != NULL )
			{
				kerning = 0;
				if( i > 0) //test if needed
				{kerning = texture_glyph_get_kerning( glyph, m_text.text_1[i-1] );}
				base_x += kerning;
				/*
				x0 = ( base_x + (float)glyph->offset_x );
				y0 = ( base_y + (float)glyph->offset_y );
				x1 = ( x0 + (float)glyph->width );
				y1 = ( y0 - (float)glyph->height );
				*/
				x0 = ( base_x + (((float)glyph->offset_x)*4/3) );
				y0 = ( base_y + (float)glyph->offset_y );
				x1 = ( x0 + (((float)glyph->width)*4/3) );
				y1 = ( y0 - (float)glyph->height );

				x0 = (2*x0)/m_display.scr_width;
				x1 = (2*x1)/m_display.scr_width;
				y0 = (2*y0)/m_display.scr_height;
				y1 = (2*y1)/m_display.scr_height;

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

				j=18*i;
				k=12*i;

				m_mesh.m_attribute.pos_text[j]=x0;		m_mesh.m_attribute.pos_text[j+1]=y0;		m_mesh.m_attribute.pos_text[j+2]=0.0;
				m_mesh.m_attribute.texCoord_text[k]=s0;			m_mesh.m_attribute.texCoord_text[k+1]=t0;
				m_mesh.m_attribute.pos_text[j+3]=x0;	m_mesh.m_attribute.pos_text[j+4]=y1;		m_mesh.m_attribute.pos_text[j+5]=0.0;
				m_mesh.m_attribute.texCoord_text[k+2]=s0;		m_mesh.m_attribute.texCoord_text[k+3]=t1;
				m_mesh.m_attribute.pos_text[j+6]=x1;	m_mesh.m_attribute.pos_text[j+7]=y1;		m_mesh.m_attribute.pos_text[j+8]=0.0;
				m_mesh.m_attribute.texCoord_text[k+4]=s1;		m_mesh.m_attribute.texCoord_text[k+5]=t1;
				m_mesh.m_attribute.pos_text[j+9]=x0;	m_mesh.m_attribute.pos_text[j+10]=y0;		m_mesh.m_attribute.pos_text[j+11]=0.0;
				m_mesh.m_attribute.texCoord_text[k+6]=s0;		m_mesh.m_attribute.texCoord_text[k+7]=t0;
				m_mesh.m_attribute.pos_text[j+12]=x1;	m_mesh.m_attribute.pos_text[j+13]=y1;		m_mesh.m_attribute.pos_text[j+14]=0.0;
				m_mesh.m_attribute.texCoord_text[k+8]=s1;		m_mesh.m_attribute.texCoord_text[k+9]=t1;
				m_mesh.m_attribute.pos_text[j+15]=x1;	m_mesh.m_attribute.pos_text[j+16]=y0;		m_mesh.m_attribute.pos_text[j+17]=0.0;
				m_mesh.m_attribute.texCoord_text[k+10]=s1;		m_mesh.m_attribute.texCoord_text[k+11]=t0;

				//base_x += glyph->advance_x;
				base_x += (((float)glyph->advance_x)*4/3);

			}
		}
	}
}
// --------------------------------------------------------------- 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 );
}
예제 #15
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);
    }
}
예제 #16
0
void BatchRenderer2D::drawString(const std::string& text, const vec3& position, const Font& font, unsigned int color)
{
	float samplerIndex = 0.0f;
	
	bool found = false;
	for (size_t i = 0; i < m_Textures.size(); i++)
	{
		if (m_Textures[i] == font.getID())
		{
			found = true;
			samplerIndex = (float)(i + 1);
			break;
		}
	}

	if (!found)
	{
		if (m_Textures.size() >= MAX_TEXTURES)
		{
			end();
			begin();
		}

		m_Textures.push_back(font.getID());
		samplerIndex = (float)m_Textures.size();
	}

	float x = position.x;
	const vec2& scale = font.getScale();

	for (size_t i = 0; i < text.length(); i++)
	{
		const char& c = text[i];
		ftgl::texture_glyph_t* glyph = ftgl::texture_font_get_glyph(font.getFont(), c);
		if (glyph)
		{
			if (i > 0)
			{
				float kerning = texture_glyph_get_kerning(glyph, text[i - 1]);
				x += kerning / scale.x;
			}

			float x0 = x + glyph->offset_x / scale.x;
			float y0 = position.y + glyph->offset_y / scale.y;
			float x1 = x0 + glyph->width / scale.x;
			float y1 = y0 - glyph->height / scale.y;

			float u0 = glyph->s0;
			float v0 = glyph->t0;
			float u1 = glyph->s1;
			float v1 = glyph->t1;

			m_Buffer->position = *m_TransformationBack * vec3(x0, y0, 0.0f);
			m_Buffer->uv = vec2(u0, v0);
			m_Buffer->sampler = samplerIndex;
			m_Buffer->color = color;
			m_Buffer++;

			m_Buffer->position = *m_TransformationBack * vec3(x0, y1, 0.0f);
			m_Buffer->uv = vec2(u0, v1);
			m_Buffer->sampler = samplerIndex;
			m_Buffer->color = color;
			m_Buffer++;

			m_Buffer->position = *m_TransformationBack * vec3(x1, y1, 0.0f);
			m_Buffer->uv = vec2(u1, v1);
			m_Buffer->sampler = samplerIndex;
			m_Buffer->color = color;
			m_Buffer++;

			m_Buffer->position = *m_TransformationBack * vec3(x1, y0, 0.0f);
			m_Buffer->uv = vec2(u1, v0);
			m_Buffer->sampler = samplerIndex;
			m_Buffer->color = color;
			m_Buffer++;

			m_IndexCount += 6;

			x += glyph->advance_x / scale.x;
		}
	}

	/*m_Buffer->position = vec3(-8, -8, 0);
	m_Buffer->uv = vec2(0, 1);
	m_Buffer->sampler = samplerIndex;
	m_Buffer->color = color;
	m_Buffer++;

	m_Buffer->position = vec3(8, -8, 0);
	m_Buffer->uv = vec2(1, 1);
	m_Buffer->sampler = samplerIndex;
	m_Buffer->color = color;
	m_Buffer++;

	m_Buffer->position = vec3(8, 8, 0);
	m_Buffer->uv = vec2(1, 0);
	m_Buffer->sampler = samplerIndex;
	m_Buffer->color = color;
	m_Buffer++;

	m_Buffer->position = vec3(-8, 8, 0);
	m_Buffer->uv = vec2(0, 0);
	m_Buffer->sampler = samplerIndex;
	m_Buffer->color = color;
	m_Buffer++;

	m_IndexCount += 6;*/
}
예제 #17
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 );
}
예제 #18
0
파일: Render.cpp 프로젝트: edunad/TomatoLib
	void Render::Text(Font* font, const std::string& text, float x, float y, const Color& color) {
		if (color.A == 0) return;
		this->SetTexture(font->Atlas->id);
		this->SetShader(this->DefaultShaderText.ProgramHandle);

		x += this->_DrawOffset.X;
		y += this->_DrawOffset.Y;

		y -= font->FontHandle->height / 4;

		float cx = x;
		float cy = y;
		int len = (int)text.size();

		this->CheckSpace(len * 4, len * 6); // per square, 4 vertices and 6 indices

		float currentMaxLineHeight = 0;
		for (int 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;
			}

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

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

			float w = (float)glyph->width;
			float h = (float)font->FontHandle->height;

			_vertexData a, b, c, d;

			float lw = cx + glyph->offset_x;
			float lh = cy + h - glyph->offset_y;

			float x1 = glyph->s0;
			float x2 = glyph->s1;
			float y1 = glyph->t0;
			float y2 = glyph->t1;

			float pixelWidth = 1.0f / this->DefaultFont->Atlas->width;
			float pixelHeight = 1.0f / this->DefaultFont->Atlas->height;

			a.Location.X = lw;
			a.Location.Y = lh;

			b.Location.X = lw + w;
			b.Location.Y = lh;

			c.Location.X = lw;
			c.Location.Y = lh + glyph->height;

			d.Location.X = lw + w;
			d.Location.Y = lh + glyph->height;

			a.TextureLocation.X = x1;
			a.TextureLocation.Y = y1;

			b.TextureLocation.X = x2;
			b.TextureLocation.Y = y1;

			c.TextureLocation.X = x1;
			c.TextureLocation.Y = y2;

			d.TextureLocation.X = x2;
			d.TextureLocation.Y = y2;


			if (this->ClippingEnabled) {
				if (lw < this->_ClippingPos.X) {
					// if the sign is fully outside of the clipping, then just skip it.
					if (lw + w < this->_ClippingPos.X) {
						cx += glyph->advance_x;
						continue;
					} else {
						// calculate the new screen and texture location
						float offset = this->_ClippingPos.X - lw;

						a.Location.X += offset;
						c.Location.X += offset;

						a.TextureLocation.X += offset * pixelWidth;
						c.TextureLocation.X += offset * pixelWidth;
					}
				}

				if (lw + w > this->_ClippingPos.X + this->_ClippingSize.X) {
					if (cx > this->_ClippingPos.X + this->_ClippingSize.X) {
						cx += glyph->advance_x;
						continue;
					} else {
						float offset = lw + w - this->_ClippingPos.X - this->_ClippingSize.X;

						b.Location.X -= offset;
						d.Location.X -= offset;

						b.TextureLocation.X -= offset * pixelWidth;
						d.TextureLocation.X -= offset * pixelWidth;
					}
				}

				if (a.Location.Y < this->_ClippingPos.Y) {
					if (d.Location.Y < this->_ClippingPos.Y) {
						cx += glyph->advance_x;
						continue;
					} else {
						float offset = this->_ClippingPos.Y - a.Location.Y;

						a.Location.Y += offset;
						b.Location.Y += offset;

						a.TextureLocation.Y += offset * pixelHeight;
						b.TextureLocation.Y += offset * pixelHeight;
					}
				}

				if (d.Location.Y > this->_ClippingPos.Y + this->_ClippingSize.Y) {
					if (b.Location.Y > this->_ClippingPos.Y + this->_ClippingSize.Y) {
						cx += glyph->advance_x;
						continue;
					} else {
						float offset = d.Location.Y - this->_ClippingPos.Y - this->_ClippingSize.Y;

						c.Location.Y -= offset;
						d.Location.Y -= offset;

						c.TextureLocation.Y -= offset * pixelHeight;
						d.TextureLocation.Y -= offset * pixelHeight;
					}
				}
			}

			a.Color = color;
			b.Color = color;
			c.Color = color;
			d.Color = color;

			unsigned int curVertices = this->VerticeDataCount;

			VERTICE_PUSH(a);
			VERTICE_PUSH(b);
			VERTICE_PUSH(c);
			VERTICE_PUSH(d);

			INDICE_PUSH(curVertices + 0);
			INDICE_PUSH(curVertices + 1);
			INDICE_PUSH(curVertices + 2);

			INDICE_PUSH(curVertices + 1);
			INDICE_PUSH(curVertices + 3);
			INDICE_PUSH(curVertices + 2);

			cx += glyph->advance_x;
		}
	}
예제 #19
0
void opengl_font_print(
	mFloat px, 
	mFloat py, 
	const wchar_t* msg,
	mFloat r,
	mFloat g,
	mFloat b,
	mFloat a)
{
	GLfloat colors[] =
	{
		r, g, b, a
	};

	GLfloat use_texture[] =
	{
		1.0f, 0.0f
	};

	size_t i,
	       len = wcslen(msg);

	float dx = 0.0f;
	mFloat cwidth = (mFloat)0.0;

	GLfloat matrix_copy[16];
	opengl_font_t* font = (opengl_font_t*)current_font->data;

	fontSize(L"M", &cwidth, NULL);

	opengl_view_copy(matrix_copy);

	opengl_setup_view(
	        px * window_zoom,
	        py * window_zoom,
	        1.0f,
	      - 1.0f);

	glEnable(GL_TEXTURE_2D);	
	glBindTexture(GL_TEXTURE_2D, font->atlas->id);

	for(i = 0 ; i < len ; i++)
	{
		texture_glyph_t *glyph;

		if(msg[i] == L'\t')
		{
			dx += 8.0f * cwidth * window_zoom;
			continue;
		}

		glyph = texture_font_get_glyph(font->font, msg[i]);
		
		if(glyph != NULL)
		{
			GLfloat x0 = dx + (GLfloat)glyph->offset_x;
			GLfloat y0 = (GLfloat)glyph->offset_y;
			GLfloat x1 = x0 + (GLfloat)glyph->width;
			GLfloat y1 = y0 - (GLfloat)glyph->height - 1.25f;

			GLfloat s0 = glyph->s0;
			GLfloat t0 = glyph->t0;
			GLfloat s1 = glyph->s1;
			GLfloat t1 = glyph->t1 + 0.00125f;

			GLfloat vertices[] = 
			{
				x0, y0,
				x0, y1,
				x1, y0,
				x1, y1
			};
	
			GLfloat tex_indices[] =
			{
				s0, t0,
				s0, t1,
				s1, t0,
				s1, t1
			};

			opengl_draw_data(vertices, tex_indices, colors, use_texture);
			dx += glyph->advance_x + texture_glyph_get_kerning(glyph, msg[i]);
		}
	}

	glDisable(GL_TEXTURE_2D);

	opengl_view_set(matrix_copy);
}
float TextureGlyph::GetKerning(const wchar_t charcode) {
    return texture_glyph_get_kerning(static_cast<const texture_glyph_t*>(self_),
                                     charcode);
}
예제 #21
0
파일: stats.cpp 프로젝트: rarosu/car2d
void Stats::update_text()
{
	// Destroy any old vertex buffers.
	glDeleteBuffers(1, &position_vbo);
	glDeleteBuffers(1, &texcoord_vbo);
	glDeleteVertexArrays(1, &vao);
	vertex_count = 0;

	// Bail out if we do not have any text.
	if (lines.size() == 0)
		return;

	// Count the number of vertices.
	for (int i = 0; i < lines.size(); ++i)
	{
		vertex_count += lines[i].text.size() * 6;
	}

	// Generate the new vertices.
	glm::vec2 pen;
	std::vector<glm::vec2> positions(vertex_count);
	std::vector<glm::vec2> texcoords(vertex_count);
	int offset = 0;
	for (int i = 0; i < lines.size(); ++i)
	{
		const std::string& text = lines[i].text;
		int text_length = text.size();

		pen.x = 0;
		for (int k = 0; k < text_length; ++k)
		{
			wchar_t c = (wchar_t) text[k];
			texture_glyph_t* glyph = texture_font_get_glyph(texture_font, c);

			float kerning = 0.0f;
			if (k > 0)
			{
				kerning = texture_glyph_get_kerning(glyph, text[k - 1]);
			}

			pen.x += kerning;

			float x0 = pen.x + glyph->offset_x;
			float y0 = pen.y + glyph->offset_y;
			float x1 = x0 + glyph->width;
			float y1 = y0 - glyph->height;

			positions[offset + k * 6 + 0] = glm::vec2(x0, y0);
			positions[offset + k * 6 + 1] = glm::vec2(x0, y1);
			positions[offset + k * 6 + 2] = glm::vec2(x1, y1);
			positions[offset + k * 6 + 3] = glm::vec2(x0, y0);
			positions[offset + k * 6 + 4] = glm::vec2(x1, y1);
			positions[offset + k * 6 + 5] = glm::vec2(x1, y0);

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

			texcoords[offset + k * 6 + 0] = glm::vec2(s0, t0);
			texcoords[offset + k * 6 + 1] = glm::vec2(s0, t1);
			texcoords[offset + k * 6 + 2] = glm::vec2(s1, t1);
			texcoords[offset + k * 6 + 3] = glm::vec2(s0, t0);
			texcoords[offset + k * 6 + 4] = glm::vec2(s1, t1);
			texcoords[offset + k * 6 + 5] = glm::vec2(s1, t0);

			pen.x += glyph->advance_x;
		}

		pen.y -= (texture_font->ascender - texture_font->descender) + texture_font->linegap;
		offset += text_length * 6;
	}

	// Generate new vertex buffers.
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);

	glGenBuffers(1, &position_vbo);
	glBindBuffer(GL_ARRAY_BUFFER, position_vbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * vertex_count, &positions[0], GL_STATIC_DRAW);
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(0);

	glGenBuffers(1, &texcoord_vbo);
	glBindBuffer(GL_ARRAY_BUFFER, texcoord_vbo);
	glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * vertex_count, &texcoords[0], GL_STATIC_DRAW);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(1);
}
예제 #22
0
// 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;
}
예제 #23
0
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();
		}
    }
}
예제 #24
0
TextInfo FontRenderer::RenderText(std::string text, float xPos, float yPos, float pixelWidthLimit, const glm::vec4 color, FontShader* shader, bool wordFormat)
{
	TextInfo result;
	result.start_position = glm::vec2(0, 0);
	result.end_position = glm::vec2(0, 0);

	float scaleX = ContextWindow::getCurrent().getWidth();
	float scaleY = ContextWindow::getCurrent().getHeight();

	float x = xPos / scaleX;
	float firstPos = (float)xPos;
	float limitX = (pixelWidthLimit + xPos) / scaleX;
	int yAdvance = 0;

	auto fit = [&text, pixelWidthLimit](int index, float xPos, float headStart, ftgl::texture_glyph_t* glyph)
	{
		float x = (float)xPos;
		for (; text[index + 1] != ' ' && text[index + 1] != 0; ++index)
		{
			unsigned char c = text[index];
			x += glyph->advance_x;
			if ((xPos + pixelWidthLimit) < x + headStart)
				return false;
		}
		return true;
	};

	glEnable(GL_BLEND);
	glDisable(GL_DEPTH_TEST);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	shader->useShader();

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

	for (int i = 0; i < text.size(); i++)
	{
		unsigned char c = text[i];
		ftgl::texture_glyph_t* glyph = ftgl::texture_font_get_glyph(font, c);
		if (glyph != NULL)
		{
			IndexedModel * im = fontMesh->getQuad()->getIndexedModel();
			if (i > 0)
			{
				float kerning = texture_glyph_get_kerning(glyph, text[i - 1]);
				x += kerning / scaleX;
			}

			if (i > 0)
			{
				if (text[i - 1] == ' ' && text[i] != ' ')
				{
					if (!fit(i, firstPos, x * scaleX, glyph) && c != ' ')
					{
						x = xPos / scaleX;
						yPos -= font->ascender - font->descender;	// highest glyph height - lowest glyph height
						yAdvance++;
					}
				}
			}

			float x0 = x + glyph->offset_x / scaleX;
			float y0 = (yPos + glyph->offset_y) / scaleY;
			float x1 = x0 + glyph->width / scaleX;
			float y1 = y0 - glyph->height / scaleY;

			if (i == 0)
			{
				result.start_position.x = x0;
				result.start_position.y = y0;
				result.end_position.x = x1;
			}
			if (x1 > result.end_position.x)
				result.end_position.x = x1;
			result.end_position.y = y1;
		
			im->positions[0] = glm::vec3(x0, y1, 0.0f);
			im->positions[1] = glm::vec3(x0, y0, 0.0f);
			im->positions[2] = glm::vec3(x1, y1, 0.0f);
			im->positions[3] = glm::vec3(x1, y0, 0.0f);

#if 0	// Font debug
			glUseProgram(0);

			glLineWidth(1.0);
			glBegin(GL_LINES);

			glColor3f(1, 0, 0);

			glVertex3f(x0, y1, -1.0f);	// Vertical left debug line
			glVertex3f(x0, y0, -1.0f);

			glVertex3f(x1, y1, -1.0f);	// Vertical right
			glVertex3f(x1, y0, -1.0f);

			glVertex3f(x0, y1, -1.0f);	// Horizontal bottom
			glVertex3f(x1, y1, -1.0f);

			glVertex3f(x0, y0, -1.0f);	// Horizontal top
			glVertex3f(x1, y0, -1.0f);
			glEnd();

			shader->useShader();
#endif
			im->texCoords[0] = glm::vec2(glyph->s0, glyph->t1);
			im->texCoords[1] = glm::vec2(glyph->s0, glyph->t0);
			im->texCoords[2] = glm::vec2(glyph->s1, glyph->t1);
			im->texCoords[3] = glm::vec2(glyph->s1, glyph->t0);

			glBindVertexArray(fontMesh->getVertexArrayID());
			glBindBuffer(GL_ARRAY_BUFFER, fontMesh->getVertexBufferID());
			glBufferSubData(GL_ARRAY_BUFFER, 0, im->positions.size() * sizeof(float) * 3, &im->positions[0]);

			glBindBuffer(GL_ARRAY_BUFFER, fontMesh->getTextureBufferID());
			glBufferSubData(GL_ARRAY_BUFFER, 0, im->texCoords.size() * sizeof(float) * 2, &im->texCoords[0]);

			shader->setTextColor(color);
			shader->update();
			fontMesh->render();

			x += glyph->advance_x / scaleX;
		}
	}

	glEnable(GL_DEPTH_TEST);
	glDisable(GL_BLEND);
	glUseProgram(0);

	result.num_rows = yAdvance + 1;
	result.height = (font->ascender - font->descender) * (float)yAdvance;
	result.width = result.end_position.x - result.start_position.x;

#if 1	// Font debug
	glUseProgram(0);

	glLineWidth(1.0);

	glBegin(GL_LINES);

	glColor3f(1, 0, 0);

	glVertex3f(result.start_position.x, result.start_position.y, -1.0f);	// Vertical left debug line
	glVertex3f(result.end_position.x, result.end_position.y, -1.0f);

	glEnd();

	shader->useShader();
#endif

	return result;
}