我正在使用带签名距离字段渲染模式的freetypegl渲染文本。
这很难捕获,因此我不得不录制视频(即使录制全高清60 fps也很难捕获)。另外,我不得不记录更多的顶点,我不知道为什么它会这样工作,但是最大的问题是scene
窗口何时渲染。当数据较少时,问题几乎是看不见的。
此外,当我打开Material
或其他任何折叠的标题时,问题立即消失
在视频中,它显示在右侧-Layout
窗口中。当我们仔细观察时,fps
,gui 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,也许还有另一种方法(使用普通渲染看起来也很糟糕)。
为什么文本行事怪异?该如何解决?