GL_NV_Path_Renderingを試す -その2-

前回は図形を書いてみたので今回は文字列を書いてみます。これもまたサンプルにあったほぼまんまのように見えますが、任意の英数文字N個に出来るよう改良しています。

初期化ブロック

初期化部分です。任意の文字数と言った割には、配列サイズを大きめにとっているだけだったりします。

const char* word = "This is Path Rendering";
int wordLen = strlen(word);
char  glyphChar[512];
char glyphPathIndexChar[512];

glyphBase = glGenPathsNV( wordLen*2 );
float emScale = 2048;
GLuint templatePathObject = ~0;

glPathGlyphsNV( glyphBase, 
    GL_SYSTEM_FONT_NAME_NV,  "Helvetica", GL_BOLD_BIT_NV,
    wordLen, GL_UNSIGNED_BYTE, word,
    GL_SKIP_MISSING_GLYPH_NV, templatePathObject, emScale );
memset( glyphChar, 0, sizeof(glyphChar) );
memset( glyphPathIndexChar, 0, sizeof(glyphPathIndexChar) );

for( int i = 0; i < wordLen; ++i ) {
  glyphPathIndexChar[i] = (char)i;
  glyphChar[i] = (char)i;
}
glyphChar[wordLen] = wordLen-1;

描画部分

文字列を書いている部分です。
やっぱりこちらも前回のパス描画と同様にステンシルに書いて、範囲をフィルすることでパスを描画している感じになっています。

GLfloat xtranslate[32+1] = { 0 }; // wordLen+1
glGetPathSpacingNV( GL_ACCUM_ADJACENT_PAIRS_NV,
    wordLen+1, GL_UNSIGNED_BYTE, 
    glyphChar,
    glyphBase, 1.0f, 1.0f, 
    GL_TRANSLATE_X_NV,
    xtranslate + 1 );
GLfloat yMinMax[2];
glGetPathMetricRangeNV( GL_FONT_Y_MIN_BOUNDS_BIT_NV|GL_FONT_Y_MAX_BOUNDS_BIT_NV,
            glyphBase, 1,
            2*sizeof(GLfloat),
            yMinMax );
// yMinMaxで行列セット
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, xtranslate[wordLen], yMinMax[0], yMinMax[1], -1, 1 );

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

glPathColorGenNV( GL_PRIMARY_COLOR, GL_PATH_OBJECT_BOUNDING_BOX_NV, GL_RGB, &rgbgrad[0][0] );

glStencilFillPathInstancedNV( wordLen, GL_UNSIGNED_BYTE, 
    glyphPathIndexChar,
    glyphBase, GL_PATH_FILL_MODE_NV, 0xFF, GL_TRANSLATE_X_NV, xtranslate );
glEnable( GL_STENCIL_TEST );
glStencilFunc( GL_NOTEQUAL, 0, 0xFF );
glStencilOp( GL_KEEP, GL_KEEP, GL_ZERO );
glColor3f( 0.5f, 0.5f, 0.5f );
glCoverFillPathInstancedNV(
   wordLen, GL_UNSIGNED_BYTE,
   glyphPathIndexChar,
   glyphBase,
   GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV,
   GL_TRANSLATE_X_NV, xtranslate );

glPathColorGenNV( GL_PRIMARY_COLOR, GL_NONE, 0, NULL );

実は一番最後の glPathColorGenNV が大切だったりします。これを忘れるとここでやったグラデーション設定が他の部分にまで適用されてしまい思うような描画結果になりません。

これを実行して得られた画像が以下のようになります。

描画するまで手間ではありますが、他のリソースを用意したり複雑な管理機構を作らなくても良さそうな点から、これを用いて文字列描画を行うようにするのは意外とアリな感じもします。

OpenGL プログラミング
すらりんをフォローする
すらりん日記

コメント

タイトルとURLをコピーしました