如何为 OpenGL 文本渲染计算字符映射中的最佳字形边界
Posted
技术标签:
【中文标题】如何为 OpenGL 文本渲染计算字符映射中的最佳字形边界【英文标题】:How to calculate the optimal glyph bounds in a character map for OpenGL text rendering 【发布时间】:2014-07-30 23:02:22 【问题描述】:为了使用 OpenGL 渲染文本,我采用带纹理的四边形方法,为每个需要表示的字符绘制一个四边形。我将所有字符纹理信息存储在单个纹理中,并在纹理矩阵上使用 glScalef 和 glTranslatef 来选择纹理中的正确字符。起初我只在用于创建纹理的图像中放置了几个字符,并且效果很好。
从那时起,我需要渲染更多字符,例如小写字母。我尝试添加更多字符,但现在我的文本未对齐且更小。
是否有正确的方法来创建角色映射,或者我的方法都错了?
注意:我使用的是单一样式的字体,所以字体尺寸不应该是问题,但是我想添加对具有非统一大小字符的字体的支持。
编辑:我使用顶点缓冲区进行绘图而不是立即模式。
编辑 2:包含字符映射的纹理有 9 行,每行有 11 个字符。由于字符大小相同,所以我在纹理矩阵上使用 glscalef 到纹理宽度的 1/9,高度的 1/11。 VBO 定义四边形 (0,0),(1,0),(0,1),(1,1) 和 tex 坐标 (0,0),(1,0),(0,1),( 1,1)。不对齐似乎是由于我的转换不完全适合每个字形。如何计算每个字形的最佳边界?
【问题讨论】:
您应该只为每个四边形生成适当的纹理坐标,而不是 glScalef glTransform(无论如何都已弃用)。 我正在尝试将所需的 OpenGL 版本保持在尽可能低的水平,因此我使用了这些功能。我确实有字符映射上字符的坐标,如果这也是您所指的,但它基于每个字符相对于字符映射大小的统一大小。这个尺寸被 OpenGL 标准化为 1:1。 段落的后半部分没有太多意义。正如 datenwolf 所说,设置四边形的纹理坐标(使用glTexCoord2d
或类似的)而不是弄乱纹理矩阵。
对不起,我应该提到我正在使用顶点缓冲区进行绘图而不是立即模式,部分原因是它很容易移植到 OpenGL ES。
@Josh:那还是没有道理,不是简单地调整纹理坐标。纹理坐标不是现代 OpenGL 的一些特性。自从纹理被引入以来,它们就一直是 OpenGL 的一部分,这在 20 多年前发生在 OpenGL-1.0 中。您肯定会为您的顶点缓冲区提供纹理坐标数组。这就是角色纹理坐标所在的位置。
【参考方案1】:
希望这对其他人有用。最佳字形边界可以通过首先标准化每个字母的像素偏移量来计算,使它们是 0 和 1 范围内的数字。宽度和高度也可以标准化以确定正确的边界框。如果宽度和高度是统一的,例如在单声道字体中,则可以使用静态宽度和高度值来计算字形边界。
为每个字形保存一组像素位置值手动计算会很繁琐,因此最好在字符映射的第一个像素处开始第一个字形,并且每个字母之间没有间距。这将使使用 for 循环轻松计算左下角 uv 坐标
void GetUVs(Vector2* us, Vector2* vs, float charWidth, float charHeight, int cols, int rows)
for (int x = 0; x < cols; x++)
for (int y = 0; y < rows; y++)
int index = x + cols * y;
us[index].x = x * charWidth;
vs[index].y = y * charHeight;
其余的边界可以通过分别添加宽度、高度以及宽度和高度来计算。
【讨论】:
以上是关于如何为 OpenGL 文本渲染计算字符映射中的最佳字形边界的主要内容,如果未能解决你的问题,请参考以下文章