我正在使用NVidia Path extension(NV路径)为OpenGL引擎编写文本模块。该扩展程序允许使用trutype metrics加载系统和外部字体文件。现在,我需要能够在渲染文本时为字形设置标准字体大小(以像素为单位)。默认情况下,加载的字形有EMscale = 2048.搜索字形指标到像素的转换我发现了这个:
将FUnits转换为像素
em方块中的值将转换为像素中的值 通过将它们乘以比例来协调系统。这个规模是: pointSize * resolution /(每英寸72点* units_per_em)
所以units_per_em等于2048,pointSize和resolution是我无法解决的未知数。如何获得视口宽度和高度的分辨率值进入这个等式?另外,如果我的输入是字体的像素大小,那么点大小应该是多少?
我尝试使用不同类型的输入来解决这个等式,但我的渲染文本总是比参考文本(AfterEffects)更小(或更大)。
NV_Path文档引用FreeType2 metrics。参考文献说:
在face-> glyph->指标中找到的指标通常用。表示 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));
}
答案 0 :(得分:0)
分辨率取决于设备,使用的公式为DPI(每英寸点数)。 point_size是字体的大小,由用户在Points中选择。 A Point = 1/72英寸(实际上这是PostScript中使用的Point的大小,实际单位" Point"排版机使用的略有不同)。
可以使用OS相关方法查询设备分辨率。 Google for"显示DPI $ NAMEOFOPERATINGSYSTEM"。使用点大小可以为您提供与所用显示设备无关的恒定物理字体大小。
请注意,使用OpenGL渲染时,您仍然需要通过必须考虑的转换管道。