如何在渲染sdf freetypegl字体时摆脱奇怪的东西?

时间:2018-12-31 19:55:05

标签: c++ opengl 2d freetype

我正在使用带签名距离字段渲染模式的freetypegl渲染文本。 这很难捕获,因此我不得不录制视频(即使录制全高清60 fps也很难捕获)。另外,我不得不记录更多的顶点,我不知道为什么它会这样工作,但是最大的问题是scene窗口何时渲染。当数据较少时,问题几乎是看不见的。

此外,当我打开Material或其他任何折叠的标题时,问题立即消失

在视频中,它显示在右侧-Layout窗口中。当我们仔细观察时,fpsgui window等文字会变得很奇怪。

问题肯定来自文本,我做了同样的测试而没有渲染文本,没关系。

https://www.youtube.com/watch?v=D5i761KVq0Y&feature=youtu.be

void RenderData::DrawString(const std::string& text, const Vector2& position, uint color, float scale, const Font& font)
{
    using namespace ftgl;
    texture_font_t* ftFont = font.getFTFont();

    float textSlot = FindTexture(font.getTexture().get());

    Vector2 finalPosition = position;

    for (const auto& c : text) {
        AddGlyph(finalPosition, c, textSlot, color, scale, ftFont);
    }
}


void RenderData::AddGlyph(Vector2& position, const char string, float textureSlot, uint color, float scale, texture_font_t* ftFont)
{
    texture_glyph_t* glyph = texture_font_get_glyph(ftFont, &string);
    if (glyph) {
        if (string) {
            position.x += texture_glyph_get_kerning(glyph, &string - 1) * scale;
        }

        float x0 = position.x + static_cast<float>(glyph->offset_x) * scale,
              y0 = position.y + (ftFont->ascender + ftFont->descender - static_cast<float>(glyph->offset_y)) * scale,
              x1 = x0 + static_cast<float>(glyph->width) * scale,
              y1 = y0 + static_cast<float>(glyph->height) * scale,

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

        //adds vertex data 
        AddVertexData(Vector2(x0, y0), Vector2(u0, v0), color, textureSlot);
        AddVertexData(Vector2(x0, y1), Vector2(u0, v1), color, textureSlot);
        AddVertexData(Vector2(x1, y1), Vector2(u1, v1), color, textureSlot);
        AddVertexData(Vector2(x1, y0), Vector2(u1, v0), color, textureSlot);

        //adds indexes with rect pattern - index + 0; index + 1; index + 2; 
        //index + 2; index + 3; index + 0
        AddRectElements();

        position.x += glyph->advance_x * scale;
        position.y += glyph->advance_y * scale;
    }
}


float RenderData::FindTexture(Texture* t)
{
    float result = 0.0f;
    bool found = false;
    for (uint i = 0; i < texture.size(); ++i) {
        if (texture[i] == t) {
            result = static_cast<float>(i + 1);
            found = true;
            break;
        }
    }

    if (!found) {
        const int maxTexturePerDrawCall = 32;
        if (texture.size() >= maxTexturePerDrawCall ) {
            AddDrawCall();
            Clear();
        }
        texture.push_back(t);
        result = static_cast<float>(texture.size());
    }

    return result;
}

Font::Font(const std::string& name, const std::string& filename, float size)
    : name(name), filename(filename), size(size)
{
    FTAtlas = ftgl::texture_atlas_new(512, 512, 1);
    FTFont = ftgl::texture_font_new_from_file(FTAtlas, size, filename.c_str());
    FTFont->rendermode = RENDER_SIGNED_DISTANCE_FIELD;

    TextureParameters parameters = { RED, TextureFilter::LINEAR, LINEAR, CLAMP_TO_EDGE };
    texture = texture->Create(512, 512, parameters);
    texture->setData(FTAtlas->data);
}

和片段着色器

#version 460 core

layout (location = 0) out vec4 f_color;                                                             

layout(location = 1) uniform float width;
layout(location = 2) uniform float edge;

layout(location = 5) uniform sampler2D u_textureSampler[32];

in vec2 te_uv;                                              
in vec4 te_color;
in float te_textID;

void main()
{
    float finalAlpha = 1.0f;
    if(te_textID > 0) {
        int texID = int(te_textID - 0.5);   
        float distance = 1.0 - texture2D(u_textureSampler[texID], te_uv).r,
              alpha = 1.0 - smoothstep(width, width + edge, distance);

        finalAlpha = alpha;
    }    

    f_color = vec4(te_color.rgb, te_color.a * finalAlpha);
}

当我将其更改为普通模式而不是sdf时,什么都没有改变,但是对于sdf,也许还有另一种方法(使用普通渲染看起来也很糟糕)。

为什么文本行事怪异?该如何解决?

0 个答案:

没有答案