zpc930 / freetype-gl

Automatically exported from code.google.com/p/freetype-gl
Other
0 stars 0 forks source link

Unable to get descending glyphs positioned properly. #35

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
This is a simple issue I am having that is most likely with my own code. I am 
trying to get glyphs like 'g' and 'j' rendering properly but they seem to not 
be positioned properly with the data I am providing.

Screenshot is attached. Here is the code I am using to build the string that I 
am rendering.

[code]
// Codepoint is a typedef of char32_t, part of the C++11 standard.
SH_Rect SH_Font::getGlyphTex(short size,Codepoint utf8Codepoint)
{
    cacheFontSize(size);

    texture_glyph_t* glyph = texture_font_get_glyph(mTextureFonts[size],utf8Codepoint);

    // Reverse the y values so that the glyph renders right-side up.
    SH_Vector2 topRight    { glyph->s1, glyph->t0 };
    SH_Vector2 bottomLeft  { glyph->s0, glyph->t1 };

    return SH_Rect { bottomLeft, topRight };
}

float SH_Font::getKerning(short size,Codepoint current,Codepoint preceeding)
{
    cacheFontSize(size);
    texture_glyph_t* g = texture_font_get_glyph(mTextureFonts[size],current);
    return texture_glyph_get_kerning(g,preceeding);
}

SH_Vector2 SH_Font::getOffset(short size,Codepoint c)
{
    cacheFontSize(size);
    texture_glyph_t* glyph = texture_font_get_glyph(mTextureFonts[size],c);
    return SH_Vector2 { glyph->offset_x, glyph->offset_y };
}

SH_Vector2 SH_Font::getGlyphSize(short size,Codepoint c)
{
    cacheFontSize(size);
    texture_glyph_t* glyph = texture_font_get_glyph(mTextureFonts[size],c);
    return SH_Vector2 { glyph->width, glyph->height };
}

bool SH_Font::load(const string& resourceName)
{
    mName = resourceName;

    SH_Filesystem::readFile(resourceName,mFontData);

    if(!mFontData.empty())
    {
        unsigned missed = 0;
        mAtlas = texture_atlas_new(512,512,1);

        cacheFontSize(8);
        cacheFontSize(12);
        cacheFontSize(24);

        if(missed > 0)
        {
            SH_Log::out("%s [%s] -> %s %d","SH_Font",mName.c_str(),"Loaded font, but missed a few glyphs:",missed);
        }

        // Bind the null texture...
        SH_Graphics::bindTexture(GL_TEXTURE_2D,0);
    }

    return true;
}

void SH_FontComponent::drawString(const SH_String& renderString)
{
    assert(mFont);

    SH_String oldString = mRenderString;
    mRenderString = renderString;

    // We might not have set the size, but if the string changes, we have to
    // recompile.
    if(mIsCompiled)
    {
        mIsCompiled = (mRenderString == oldString);
    }

    // Compile the render command.
    if(!mIsCompiled)
    {
        SH_Log::out("%s [%s] -> %s '%ls' \n","SH_Font",mFont->getName().c_str(),"Compiling string",mRenderString.c_str());

        SH_Color vertColor { 1,1,1,1 };

        vector<SH_Vertex> vertices;
        vertices.resize(mRenderString.size() * 4);

        vector<GLushort> indices;
        indices.resize(mRenderString.size() * 6);

        SH_Vector2 pen { 0,0 };

        for(unsigned i=0;i<renderString.size();i++)
        {
            if(i > 0)
            {
                pen.x += mFont->getKerning(mFontSize,renderString[i],renderString[i-1]);
            }

            if(renderString[i] == U'\n')
            {
                pen.x = 0.0f;
                pen.y -= mFont->getLineHeight(mFontSize);
                continue;
            }

            SH_Vector2 glyphSize = mFont->getGlyphSize(mFontSize,renderString[i]);

            if(renderString[i] == U' ')
            {
                pen.x += mFont->getAdvanceX(mFontSize,' ');
                pen.x += glyphSize.x;
                continue;
            }

            SH_Rect    glyphTex = mFont->getGlyphTex(mFontSize,renderString[i]);
            SH_Vector2 offset =   mFont->getOffset(mFontSize,renderString[i]);
            SH_Vector2 advance =  mFont->getAdvance(mFontSize,renderString[i]);

            float hFrameWidth = glyphSize.x * 0.5f;
            float hFrameHeight = glyphSize.y * 0.5f;

            vertices[i*4+0] = SH_Vertex {
                { -hFrameWidth, -hFrameHeight, 0 },
                glyphTex.getBottomLeft(),
                vertColor //,normal,binormal,tannormal
            };
            vertices[i*4+1] = SH_Vertex {
                { hFrameWidth, -hFrameHeight, 0 },
                glyphTex.getBottomRight(),
                vertColor //,normal,binormal,tannormal
            };
            vertices[i*4+2] = SH_Vertex {
                { hFrameWidth, hFrameHeight, 0 },
                glyphTex.getTopRight(),
                vertColor //,normal,binormal,tannormal
            };
            vertices[i*4+3] = SH_Vertex {
                { -hFrameWidth,  hFrameHeight, 0 },
                glyphTex.getTopLeft(),
                vertColor //,normal,binormal,tannormal
            };

            offset *= 0.5;
            for(unsigned j=0;j<4;j++)
            {
                vertices[i*4+j].Position += pen + offset;
            }

            indices[i*6+0] = ((i*4) + 0);
            indices[i*6+1] = ((i*4) + 2);
            indices[i*6+2] = ((i*4) + 1);
            indices[i*6+3] = ((i*4) + 0);
            indices[i*6+4] = ((i*4) + 3);
            indices[i*6+5] = ((i*4) + 2);

            pen += advance;
        }

        SH_Graphics::bindArrayBuffer(mInstruction.VertexBuffer);
        glBufferData(GL_ARRAY_BUFFER,vertices.size()*sizeof(SH_Vertex),&vertices[0],GL_STATIC_DRAW);

        SH_Graphics::bindElementBuffer(mInstruction.IndexBuffer);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,indices.size()*sizeof(GLushort),&indices[0],GL_STATIC_DRAW);

        mInstruction.IndexCount = (unsigned)indices.size();
        mInstruction.RenderMode = SH_RENDERMODE_TRIANGLES;

        mIsCompiled = true;
    }

    // Draw call.
    render();
}
[/code]

Original issue reported on code.google.com by mikrya...@gmail.com on 10 Sep 2012 at 1:26

Attachments:

GoogleCodeExporter commented 9 years ago
You should have a look at the demo source code that show how to position your 
glyph properly. I'm not familiar with your code so it's difficult to help you.  
Maybe you should start with a simple text like "ajg" and print individual glyph 
information to check all's ok.

Hope that helps.

Original comment by Nicolas.Rougier@gmail.com on 17 Sep 2012 at 7:24

GoogleCodeExporter commented 9 years ago
Ah, forgot to update the post. I was able to get everything working fine by
changing the quad generation from half-extents to using the data as-is.
Thanks for the reply though. Appreciate it.

Original comment by mikrya...@gmail.com on 17 Sep 2012 at 2:38

GoogleCodeExporter commented 9 years ago
Ok.

Original comment by Nicolas.Rougier@gmail.com on 17 Sep 2012 at 2:42