在 freetype 上转换字形时出现奇怪的转换
Weird transformation when transforming glyphs on freetype
我正在尝试为我正在开发的一个小游戏做一个简单的文本渲染引擎。我尝试按照各种教程进行操作,但我从来没有在 Y 坐标上找到正确的位置。
现在我正在学习本教程:
http://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Text_Rendering_01
我知道字形正在正确加载,因为我手动检查了它们。
问题是字形现在看起来像这样:
白色的东西应该是我想画的字形,但看起来很扭曲。
我认为问题出在转换上,看起来像这样:
float x2 = x + g->bitmap_left * sx;
float y2 = -y - g->bitmap_top * sy;
float w = g->bitmap.width * sx;
float h = g->bitmap.rows * sy;
GLfloat box[4][4] = {
{x2, -y2 , 0, 0},
{x2 + w, -y2 , 1, 0},
{x2, -y2 - h, 0, 1},
{x2 + w, -y2 - h, 1, 1},
};
因为它看起来不像没有旋转的转换,我认为它旋转字形并以奇怪的方式缩放它们。
但是如果我尝试像这样使用 glm
glm::mat4 MVP(glm::scale(glm::rotate(glm::translate(glm::mat4(1.0f), glm::vec3(x2, y2, 0.0f)), 0.0f, glm::vec3(0.0f, 0.0f, 1.0f)), glm::vec3(w, h, 0.0f)));
字符串看起来几乎是正确的,但它的 Y 位置不正确。
你能给我指明正确的方向吗?
我认为这是因为您没有正确使用度量数据来呈现每个字形。在这种情况下,我认为您需要获取从每个字形的边界框获取的 'baseline'。
类似这样的东西应该得到它:
FT_GlyphSlot slot = ftFace->glyph;
FT_Glyph glyph;
FT_Get_Glyph(slot, &glyph);
FT_BBox bbox;
//get dimensions in pixels
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox);
int baseLine = (int)bbox.yMin;
哦,并将该基线添加到您的 Y 位置。
我发现哪里出了问题,原来我理解教程的方式有误,这部分:
float x2 = x + g->bitmap_left * sx;
float y2 = -y - g->bitmap_top * sy;
float w = g->bitmap.width * sx;
float h = g->bitmap.rows * sy;
GLfloat box[4][4] = {
{x2, -y2 , 0, 0},
{x2 + w, -y2 , 1, 0},
{x2, -y2 - h, 0, 1},
{x2 + w, -y2 - h, 1, 1},
};
它不是一个转换它真正的顶点信息和它的边界是这样的:
glBufferData(GL_ARRAY_BUFFER, sizeof box, box, GL_DYNAMIC_DRAW);
这样你就可以得到屏幕上的每个字形,而不需要在着色器上进行转换。
我正在尝试为我正在开发的一个小游戏做一个简单的文本渲染引擎。我尝试按照各种教程进行操作,但我从来没有在 Y 坐标上找到正确的位置。
现在我正在学习本教程: http://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Text_Rendering_01
我知道字形正在正确加载,因为我手动检查了它们。
问题是字形现在看起来像这样:
白色的东西应该是我想画的字形,但看起来很扭曲。
我认为问题出在转换上,看起来像这样:
float x2 = x + g->bitmap_left * sx;
float y2 = -y - g->bitmap_top * sy;
float w = g->bitmap.width * sx;
float h = g->bitmap.rows * sy;
GLfloat box[4][4] = {
{x2, -y2 , 0, 0},
{x2 + w, -y2 , 1, 0},
{x2, -y2 - h, 0, 1},
{x2 + w, -y2 - h, 1, 1},
};
因为它看起来不像没有旋转的转换,我认为它旋转字形并以奇怪的方式缩放它们。
但是如果我尝试像这样使用 glm
glm::mat4 MVP(glm::scale(glm::rotate(glm::translate(glm::mat4(1.0f), glm::vec3(x2, y2, 0.0f)), 0.0f, glm::vec3(0.0f, 0.0f, 1.0f)), glm::vec3(w, h, 0.0f)));
字符串看起来几乎是正确的,但它的 Y 位置不正确。
你能给我指明正确的方向吗?
我认为这是因为您没有正确使用度量数据来呈现每个字形。在这种情况下,我认为您需要获取从每个字形的边界框获取的 'baseline'。
类似这样的东西应该得到它:
FT_GlyphSlot slot = ftFace->glyph;
FT_Glyph glyph;
FT_Get_Glyph(slot, &glyph);
FT_BBox bbox;
//get dimensions in pixels
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox);
int baseLine = (int)bbox.yMin;
哦,并将该基线添加到您的 Y 位置。
我发现哪里出了问题,原来我理解教程的方式有误,这部分:
float x2 = x + g->bitmap_left * sx;
float y2 = -y - g->bitmap_top * sy;
float w = g->bitmap.width * sx;
float h = g->bitmap.rows * sy;
GLfloat box[4][4] = {
{x2, -y2 , 0, 0},
{x2 + w, -y2 , 1, 0},
{x2, -y2 - h, 0, 1},
{x2 + w, -y2 - h, 1, 1},
};
它不是一个转换它真正的顶点信息和它的边界是这样的:
glBufferData(GL_ARRAY_BUFFER, sizeof box, box, GL_DYNAMIC_DRAW);
这样你就可以得到屏幕上的每个字形,而不需要在着色器上进行转换。