【发布时间】:2013-04-24 11:39:07
【问题描述】:
我正在使用NVidia Path extension(NV 路径)为 OpenGL 引擎编写文本模块。该扩展允许使用trutype metrics 加载系统和外部字体文件。现在,我需要能够在渲染文本时为字形设置标准字体大小(以像素为单位)。默认情况下,加载的字形具有 EMscale = 2048。搜索字形指标到像素的转换我发现了这个:
将 FUnit 转换为像素
em 方格中的值被转换为像素中的值 坐标系通过将它们乘以比例。这个比例是: pointSize * 分辨率 / (每英寸 72 点 * units_per_em )
所以 units_per_em 等于 2048,pointSize 和分辨率是我无法解决的未知数。如何获得视口宽度和高度的分辨率值以进入这个等式?另外,如果我的输入是字体的像素大小,点大小应该是多少?
我尝试使用不同类型的输入来求解这个方程,但我渲染的文本总是比参考文本 (AfterEffects) 更小(或更大)。
NV_Path 文档参考FreeType2 metrics。参考资料说:
在 face->glyph->metrics 中找到的指标通常用 26.6 像素格式(即 1/64 像素),除非您在调用 FT_Load_Glyph 或 FT_Load_Char 时使用 FT_LOAD_NO_SCALE 标志。在 在这种情况下,指标将以原始字体单位表示。
我尝试将文本模型矩阵缩小 1/64。它接近正确的大小,但仍不完美。
这是我目前在代码中设置文本渲染的方式:
emScale=2048;
glyphBase = glGenPathsNV(1+numChars);
pathTemplate= ~0;
glPathGlyphRangeNV(glyphBase,GL_SYSTEM_FONT_NAME_NV,
"Verdana",GL_BOLD_BIT_NV,0,numChars,GL_SKIP_MISSING_GLYPH_NV,pathTemplate,emScale);
/* Query font and glyph metrics. */
glGetPathMetricRangeNV(
GL_FONT_Y_MIN_BOUNDS_BIT_NV|
GL_FONT_Y_MAX_BOUNDS_BIT_NV|
GL_FONT_X_MIN_BOUNDS_BIT_NV|
GL_FONT_X_MAX_BOUNDS_BIT_NV|
GL_FONT_UNDERLINE_POSITION_BIT_NV|
GL_FONT_UNDERLINE_THICKNESS_BIT_NV,glyphBase+' ' ,1 ,6*sizeof(GLfloat),font_data);
glGetPathMetricRangeNV(GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV,
glyphBase,numChars,0,horizontalAdvance);
/* Query spacing information for example's message. */
messageLen = strlen(message);
xtranslate =(GLfloat*)malloc(sizeof(GLfloat) *messageLen);
if(!xtranslate){
fprintf(stderr, "%s: malloc of xtranslate failed\n", "Text3D error");
exit(1);
}
xtranslate[0] = 0.0f; /* Initial xtranslate is zero. */
/* Use 100% spacing; use 0.9 for both for 90% spacing. */
GLfloat advanceScale = 1.0f,
kerningScale = 1.0f;
glGetPathSpacingNV(GL_ACCUM_ADJACENT_PAIRS_NV,
(GLsizei)messageLen,GL_UNSIGNED_BYTE,message,glyphBase,
advanceScale,kerningScale,GL_TRANSLATE_X_NV,&xtranslate[1]); /* messageLen-1 accumulated translates are written here. */
const unsigned char *message_ub = (const unsigned char*)message;
totalAdvance = xtranslate[messageLen-1] +
horizontalAdvance[message_ub[messageLen-1]];
xBorder = totalAdvance / messageLen;
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_NOTEQUAL ,0 ,~0);
glStencilOp(GL_KEEP,GL_KEEP,GL_ZERO);
////////// init matrices /////////////
translate(model ,vec3(0));
translate(view ,vec3(0));
float nearF=1 ,farF = 1200;
glViewport(0,0,_viewPortW,_viewPortH);
glMatrixLoadIdentityEXT(GL_PROJECTION);
float aspect_ratio =(float) _viewPortW /(float) _viewPortH;
glMatrixFrustumEXT(GL_PROJECTION ,-aspect_ratio,aspect_ratio,-1 ,1 ,nearF,farF);
model=translate(model,vec3(0.0f,384.0,0.0f));//move up
//scale by 26.6 also doesn't work:
model=scale(model,vec3((1.0f/26.6f),1.0f/26.6f,1.0f/26.6f));
view=lookAt(vec3(0,0,0),vec3(0,0,-1),vec3(0,1,0));
}
【问题讨论】:
标签: opengl fonts truetype freetype