简体   繁体   中英

Text alignment in OpenGL with FreeType2

I'm trying to implement font rendering and have got into some trouble with glyph metrics. Here's the code where I get the metrics:

Glyph gl;
gl.width = face->glyph->metrics.width / 64;
gl.height = face->glyph->metrics.height / 64;
gl.character = i;
gl.advance = face->glyph->metrics.horiAdvance / 64;
gl.bearingX = face->glyph->metrics.horiBearingX / 64;
gl.bearingY = face->glyph->metrics.horiBearingY / 64;
gl.textureX = this->_textureWidth;

The value of gl.advance is way too small. Here is a picture of it:

If I'm dividing face->glyph->metrics.horiAdvance by 40, it looks like this:

The text is now readable, but the advance and X-, Y-bearing still don't look correct. This is what it should look like:

Here is my code where I draw the glyphs:

float aspect = this->_graphics->getMetrics().x / this->_graphics->getMetrics().y;

float offset = 0;
for(unsigned char c : str){
    Glyph g = this->_fonts[fontID]->getGlyph(c);

    vec2 pos = (position.getRelative() + vec2(offset, 0) + (vec2(g.bearingX, -g.bearingY) / SCALING) * scale - vec2(1, 1))
                * vec2(1, -1);
    glyphShader->setUniform("position", pos);
    glyphShader->setUniform("scale", (vec2(g.width, g.height * aspect) / SCALING) * scale);
    glyphShader->setUniform("glyphSize", vec2(g.width, g.height));
    glyphShader->setUniform("textureMetrics", this->_fonts[fontID]->getTextureMetrics());
    glyphShader->setUniform("textureOffset", vec2(g.textureX, 0));
    glyphShader->setUniform("image", 0);
    glyphShader->setUniform("color", color);

    this->_graphics->getMeshByID(guiInstance->_quadID)->drawMesh();

    offset += (g.advance / SCALING) * scale;
}

I'm doing some transformations on position to move the origin to the top-left corner and flipping the coordinate system on the X-Axis. Then I divide every pixel value by a constant factor, to have the font having the same size on every resolution. The ratio of the glyphs is correct, but not the alignment. And here is my vertex shader:

#version 400

layout(location=0) in vec4 vertPosition;
layout(location=1) in vec2 vertUV;

uniform vec2    position;
uniform vec2    scale;
uniform vec2    glyphSize;
uniform vec2    textureMetrics;
uniform vec2    textureOffset;

out vec2 fragUV;

void main(void){
    gl_Position = vertPosition * 
                  vec4(scale, 1, 1) + 
                  vec4(position, 0, 0);

    fragUV = vec2(vertUV.x * (glyphSize.x / textureMetrics.x) + (textureOffset.x / textureMetrics.x), 
                  -vertUV.y * (glyphSize.y / textureMetrics.y));
}

Why are the characters misaligned?

You divide by 64.

Since you are using OpenGL to render your text, you need to consider 2 things.

  • OpenGL position ranges from -1.0f to +1.0f. This is a magnitude of 2.0f.
  • OpenGL size ranges from 0.0f to 1.0f. This is a magnitude of 1.0f.

Some of the FreeType fields are representing the size of the font, while others are representing the position. In some cases, you will do arithmetic that combines both position and the size of the font.

The golden rule to remember is when combining size and position, multiply the size by 2.

Glyph gl;
gl.width = face->glyph->metrics.width / 64; //size
gl.height = face->glyph->metrics.height / 64; //size
gl.character = i;
gl.advance = face->glyph->metrics.horiAdvance / 64; //size
gl.bearingX = face->glyph->metrics.horiBearingX / 64; //position
gl.bearingY = face->glyph->metrics.horiBearingY / 64; //position
gl.textureX = this->_textureWidth;

//whenever combining size and position, multiply the size by 2
gl_Position = vertPosition * 
                  vec4(scale, 1, 1) * 2 /*multiply*/ + 
                  vec4(position, 0, 0);

PS: You shouldn't use aspect ratio with the font dimensions. It defeats the purpose of the font designers. The metrics provided by the font designers will give the optimal look for the fonts.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM