NVidia Path 拡張機能(NV Path)を使用して、OpenGL エンジン用のテキスト モジュールを作成しています。この拡張機能により、 trutype メトリックを使用してシステムおよび外部フォント ファイルをロードできます。ここで、テキストをレンダリングするときにグリフの標準フォント サイズ (ピクセル単位) を設定できるようにする必要があります。デフォルトでは、ロードされたグリフは EMscale = 2048 です。グリフのメトリクスからピクセルへの変換を検索すると、次のことがわかりました。
FUnit をピクセルに変換する
em 正方形の値は、スケールを掛けることによってピクセル座標系の値に変換されます。このスケールは次のとおりです: pointSize * resolution / (1 インチあたり 72 ポイント * units_per_em )
units_per_em は 2048 に等しいので、pointSize と解像度は解決できない未知数です。ビューポートの幅と高さの解像度の値を取得して、この式に入るにはどうすればよいですか? また、入力がフォントのピクセル サイズである場合、ポイント サイズはどうすればよいですか?
この方程式を別の種類の入力で解こうとしましたが、レンダリングされたテキストは常に参照テキスト (AfterEffects) よりも小さく (または大きく) なります。
NV_Path ドキュメントはFreeType2 メトリックを参照しています。リファレンスには次のように書かれています。
face->glyph->metrics にあるメトリックは、FT_Load_Glyph または FT_Load_Char を呼び出すときに FT_LOAD_NO_SCALE フラグを使用しない限り、通常 26.6 ピクセル形式 (つまり、1/64 ピクセル) で表されます。この場合、メトリックは元のフォント単位で表現されます。
テキスト モデル マトリックスを 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));
}