文字を表示するには、フォントリソースから取得したグリフの情報をもとに表示する方法と、FONT ライブラリで用意されている文字描画クラスを利用する方法とがあります。
4.1. グリフの情報をもとに表示する
Font クラスの GetGlyph()
は、グリフの情報を Glyph 構造体で返します。この構造体には、グリフを文字として表示するために必要な情報が格納されており、以下のように定義されています。
struct Glyph { const void* pTexture; struct CharWidths { s8 left; u8 glyphWidth; s8 charWidth; } widths; u8 height; u16 texWidth; u16 texHeight; u16 cellX; u16 cellY; u8 isSheetUpdated; TexFmt texFormat; const TextureObject* pTextureObject; };
各メンバに格納されている値は以下のとおりです。幅や高さの値はピクセル単位で格納されています。
メンバ | 説明 |
---|---|
pTexture
|
シート(テクスチャイメージ)へのポインタ。 |
widths.left
|
左スペース幅。 |
widths.glyphWidth
|
グリフ幅。 |
widths.charWidth
|
文字幅。 右スペース幅は(文字幅 - グリフ幅 - 左スペース幅)で求めることができます。 |
height
|
セル(グリフイメージ)の高さ。 |
texWidth
|
シートの幅。 |
texHeight
|
シートの高さ。 |
cellX
|
シートの左上隅を原点としたときの、セル左上隅の X 座標。 |
cellY
|
シートの左上隅を原点としたときの、セル左上隅の Y 座標。 |
isSheetUpdated
|
シート更新フラグ。FONT ライブラリが参照します。 |
texFormat
|
シートの(テクスチャ)フォーマット。 |
pTextureObject
|
テクスチャオブジェクトなどの情報。FONT ライブラリが参照します。 |
シートのフォーマットの定義と glTexImage2D()
の引数に指定すべき値の対応は以下のとおりです。
フォーマット | format | type |
---|---|---|
FONT_SHEET_FORMAT_A4
|
GL_ALPHA_NATIVE_DMP
|
GL_UNSIGNED_4BITS_DMP
|
FONT_SHEET_FORMAT_A8
|
GL_ALPHA_NATIVE_DMP
|
GL_UNSIGNED_BYTE
|
FONT_SHEET_FORMAT_LA4
|
GL_LUMINANCE_ALPHA_NATIVE_DMP
|
GL_UNSIGNED_BYTE_4_4_DMP
|
FONT_SHEET_FORMAT_LA8
|
GL_LUMINANCE_ALPHA_NATIVE_DMP
|
GL_UNSIGNED_BYTE
|
FONT_SHEET_FORMAT_RGBA4
|
GL_RGBA_NATIVE_DMP
|
GL_UNSIGNED_SHORT_4_4_4_4
|
FONT_SHEET_FORMAT_RGB5A1
|
GL_RGBA_NATIVE_DMP
|
GL_UNSIGNED_SHORT_5_5_5_1
|
FONT_SHEET_FORMAT_RGBA8
|
GL_RGBA_NATIVE_DMP
|
GL_UNSIGNED_BYTE
|
FONT_SHEET_FORMAT_RGB565
|
GL_RGB_NATIVE_DMP
|
GL_UNSIGNED_SHORT_5_6_5
|
FONT_SHEET_FORMAT_RGB8
|
GL_RGB_NATIVE_DMP
|
GL_UNSIGNED_BYTE
|
表示するグリフイメージの、シート内での位置を特定するために必要なメンバは以下のとおりです。
3DS のテクスチャ座標は左下が原点であるのに対し、セル(グリフイメージ)の座標が左上を原点としていることに注意が必要です。そのため、テクスチャ座標の計算は以下のサンプルコードのように実装します。
Glyph glyph; myFont.GetGlyph(&glyph, character); const f32 texLeft = 1.0f * glyph.cellX / glyph.texWidth; const f32 texRight = 1.0f * (glyph.cellX + glyph.widths.glyphWidth) / glyph.texWidth; // グリフイメージの座標とテクスチャ座標の原点の違いに注意すること const f32 texTop = 1.0f * (glyph.texHeight - glyph.cellY) / glyph.texHeight; const f32 texBottom = 1.0f * (glyph.texHeight - (glyph.cellY + glyph.height)) / glyph.texHeight;
4.2. FONT ライブラリのクラスを利用する
FONT ライブラリでは、文字(列)を描画するためのクラスを用意しています。また、単純な文字の描画だけでなく、以下のような機能を有しています。
- 文字色の変更
- 文字ごとの縦または横方向のグラデーション
- 文字の拡大縮小
- 強制的な等幅フォント表示
- 文字間、行間、タブ幅の処理
- 左右寄せ
- 文字列の自動改行
- フォーマット文字列による描画(printf 相当)
- タグ文字列の処理(カスタマイズ可能)
FONT ライブラリによる文字の描画で使用するクラスは複数あり、以下のように連携して処理を行っています。その中で、アプリケーションでインスタンスを生成し、描画のための設定を行うクラスは、下図で橙色の四角形に記述されているクラスです。ちなみに、青色が継承元のクラス、緑色が暗黙的に使用されるクラスです。
FONT ライブラリのクラスを利用して文字の描画を行う場合は、3D コマンド(PICA レジスタ情報)を直接生成する RectDrawer クラスの使用を推奨します。
クラス | 行われる処理 |
---|---|
CharWriter | 文字単体の描画を行います。TextWriter を使用しない場合は、このクラスを継承して、文字列の成形などを行ってください。 |
TextWriter | 文字列の描画を行います。文字列を成形するための基本的な機能を備えています。 |
TagProcessor | タグ文字(0x0000~0x001F の制御文字)の処理を行います。改行(0x000A)とタブ文字(0x0009)以外にも対応したい場合は、継承したクラスをカスタマイズしてください。 |
RectDrawer | TextWriter(CharWriter)クラスが蓄積した、文字列表示情報から 3D コマンドを生成します。専用のシェーダプログラムに合わせた 3D コマンドを生成します。 |
4.2.1. アプリケーションでの実装手順
ここでは、FONT ライブラリのクラスを利用して文字列を画面に表示するまでに必要な手順を、サンプルデモに収録されている ResFont デモのソースを交えて説明します。
4.2.1.1. フォントリソースのロードと構築
文字の描画に使用するフォントリソースのロードおよび構築を最初に行います。サンプルデモでは、InitFont()
に ResFont クラスのインスタンスへのポインタとフォントリソースのファイル名(拡張子は bcfnt)を渡しています。
//--------------------------------------------------------------------------- //! @brief ResFontを構築します。 //! //! @param[out] pFont 構築するフォントへのポインタ。 //! @param[in] filePath ロードするフォントリソースファイル名。 //! //! @return ResFont構築の成否を返します。 //--------------------------------------------------------------------------- bool InitFont( nn::font::ResFont* pFont, const char* filePath) { // フォントリソースをロードします nn::fs::FileReader fontReader(filePath); s32 fileSize = (s32)fontReader.GetSize(); if ( fileSize <= 0 ) { return false; } void* buffer = s_AppHeap.Allocate(fileSize, nn::font::GlyphDataAlignment); if (buffer == NULL) { return false; } s32 readSize = fontReader.Read(buffer, fileSize); if (readSize != fileSize) { s_AppHeap.Free(buffer); return false; } // フォントリソースをセットします bool bSuccess = pFont->SetResource(buffer); NN_ASSERT(bSuccess); //--- 既にリソースをセット済みであるか,ロード済みであるか、 // リソースが不正な場合に失敗します。 if (! bSuccess) { s_AppHeap.Free(buffer); } // 描画用バッファを設定します。 const u32 drawBufferSize = nn::font::ResFont::GetDrawBufferSize(buffer); void* drawBuffer = s_AppHeap.Allocate(drawBufferSize, 4); NN_NULL_ASSERT(drawBuffer); pFont->SetDrawBuffer(drawBuffer); return bSuccess; }
FONT ライブラリでは、ロードされたフォントリソースの、グリフイメージが描かれているシートに GPU が直接アクセスする設定でテクスチャをロードするため、フォントリソースがデバイスメモリ上の 128 Byte アライメントのバッファに読み込まれていなければならないことに注意してください。なお、描画用バッファは 4 Byte アライメントの制限のみで、バッファをデバイスメモリ上に確保しなくてもかまいません。
ResFont クラス以外のフォントリソースを使用した場合の制限については、「3.3. ArchiveFont クラス」や「3.4. PackedFont クラス」を参照してください。
4.2.1.2. シェーダの初期化
表示で使用するシェーダバイナリをロードし、RectDrawer クラスが使用するバッファの確保を行います。サンプルデモでは、InitShaders()
に RectDrawer クラスのインスタンスへのポインタを渡しています。
//--------------------------------------------------------------------------- //! @brief シェーダの初期化を行います。 //! //! @param[in,out] pDrawer 初期化するインスタンスへのポインタ。 //--------------------------------------------------------------------------- void* InitShaders(nn::font::RectDrawer* pDrawer) { nn::fs::FileReader shaderReader(s_ShaderBinaryFilePath); const u32 fileSize = (u32)shaderReader.GetSize(); void* shaderBinary = s_AppHeap.Allocate(fileSize); NN_NULL_ASSERT(shaderBinary); #ifndef NN_BUILD_RELEASE s32 read = #endif // NN_BUILD_RELEASE shaderReader.Read(shaderBinary, fileSize); NN_ASSERT(read == fileSize); const u32 vtxBufCmdBufSize = nn::font::RectDrawer::GetVertexBufferCommandBufferSize( shaderBinary, fileSize); void *const vtxBufCmdBuf = s_AppHeap.Allocate(vtxBufCmdBufSize); NN_NULL_ASSERT(vtxBufCmdBuf); pDrawer->Initialize(vtxBufCmdBuf, shaderBinary, fileSize); s_AppHeap.Free(shaderBinary); return vtxBufCmdBuf; }
RectDrawer クラスでは、頂点バッファとコマンドバッファの 2 つのバッファを使用します。頂点バッファには、描画のための頂点座標が格納されます。コマンドバッファには描画のコマンドが格納されますが、シェーダバイナリのロードコマンド(プログラム、Swizzle パターン、定数レジスタ)などが含まれます。これらのバッファは GPU が直接アクセスするため、デバイスメモリから確保しなければなりません。バッファのアライメントの指定は特にありませんが、4 Byte または 16 Byte にすることを推奨します。
サンプルデモでは、2 つのバッファを 1 つの領域で確保していますが、それぞれのバッファに必要なサイズを取得する関数や、バッファを分けて確保した場合の初期化関数が用意されています。初期化に成功したあとは、シェーダバイナリをロードしていたバッファを解放することができます。
SDK には、RectDrawer クラスで使用するシェーダバイナリとして nnfont_RectDrawerShader.shbin が収録されています。このシェーダは、射影行列にスクリーンの左上が原点でスクリーンと画面のサイズが一致する正射影行列(ただし、Y 軸と Z 軸の方向が 3DS とは逆です)、モデルビュー行列に単位行列を設定することを想定しています。文字の表示位置や大きさの調整には、変形用の行列を浮動小数点定数レジスタに蓄積して対応しています。
4.2.1.3. 表示文字列用バッファの確保
文字列表示情報を蓄積するバッファ(表示文字列用バッファ)を確保します。表示文字列用バッファに必要なサイズは最大の表示文字数から計算されます。文字列の描画が完了したあとならば、同じバッファを使って文字列表示情報の蓄積を行うことができます。フォントや表示する文字を変更しない場合は、蓄積していた文字列表示情報をそのまま再利用することができ、さらに単一色で文字列を描画していた場合は、再度文字列表示情報の蓄積を行わずに、文字色のみを変更することができます。
//--------------------------------------------------------------------------- //! @brief 表示文字列用バッファを確保します。 //! //! @param[in] charMax 表示する文字列の最大文字数。 //! //! @return 確保した表示文字列用バッファへのポインタを返します。 //--------------------------------------------------------------------------- nn::font::DispStringBuffer* AllocDispStringBuffer(int charMax) { const u32 DrawBufferSize = nn::font::CharWriter::GetDispStringBufferSize(charMax); void *const bufMem = s_AppHeap.Allocate(DrawBufferSize); NN_NULL_ASSERT(bufMem); return nn::font::CharWriter::InitDispStringBuffer(bufMem, charMax); }
表示文字列用バッファはデバイスメモリ上に確保する必要はありません。バッファのアライメントの指定は特にありませんが、4 の倍数にすることを推奨します。
4.2.1.4. 描画設定
FONT ライブラリは描画のために必要最小限の設定を行いますので、以下の項目については、文字を描画する前にアプリケーションで適切に設定する必要があります。
- カリング
- シザーテスト
- ポリゴンオフセット
- アーリーデプステスト
- デプステスト
- ステンシルテスト
- マスク処理
- フレームバッファオブジェクト
アプリケーションで 3D モデル等を表示するためにカリングやデプステストを設定している場合、文字を描画する前に設定を変更しなければ、文字の描画に直前の設定が影響を与えることになります。
サンプルデモでは、InitDraw()
で描画設定を行うコマンドを生成しています。
//--------------------------------------------------------------------------- //! @brief 描画の初期設定を行います。 //! //! @param[in] width 画面の幅。 //! @param[in] height 画面の高さ。 //--------------------------------------------------------------------------- void InitDraw( int width, int height ) { // カラーバッファ情報 // LCDの向きに合わせて、幅と高さを入れ替えています。 const nn::font::ColorBufferInfo colBufInfo = { width, height, PICA_DATA_DEPTH24_STENCIL8_EXT }; const u32 screenSettingCommands[] = { // ビューポートの設定 NN_FONT_CMD_SET_VIEWPORT( 0, 0, colBufInfo.width, colBufInfo.height ), // シザー処理を無効 NN_FONT_CMD_SET_DISABLE_SCISSOR( colBufInfo ), // wバッファの無効化 // デプスレンジの設定 // ポリゴンオフセットの無効化 NN_FONT_CMD_SET_WBUFFER_DEPTHRANGE_POLYGONOFFSET( 0.0f, // wScale : 0.0 でWバッファが無効 0.0f, // depth range near 1.0f, // depth range far 0, // polygon offset units : 0.0 でポリゴンオフセットが無効 colBufInfo), }; nngxAdd3DCommand(screenSettingCommands, sizeof(screenSettingCommands), true); static const u32 s_InitCommands[] = { // カリングを無効 NN_FONT_CMD_SET_CULL_FACE( NN_FONT_CMD_CULL_FACE_DISABLE ), // ステンシルテストを無効 NN_FONT_CMD_SET_DISABLE_STENCIL_TEST(), // デプステストを無効 // カラーバッファの全ての成分を書き込み可 NN_FONT_CMD_SET_DEPTH_FUNC_COLOR_MASK( false, // isDepthTestEnabled 0, // depthFunc true, // depthMask true, // red true, // green true, // blue true), // alpha // アーリーデプステストを無効 NN_FONT_CMD_SET_ENABLE_EARLY_DEPTH_TEST( false ), // フレームバッファアクセス制御 NN_FONT_CMD_SET_FBACCESS( true, // colorRead true, // colorWrite false, // depthRead false, // depthWrite false, // stencilRead false), // stencilWrite }; nngxAdd3DCommand(s_InitCommands, sizeof(s_InitCommands), true); }
4.2.1.5. 描画ごとに行う処理
ここまでに行った処理は初期化にあたり、ここでは描画ごとに行う処理を説明します。
表示位置や文字色を指定した文字列の描画は (Wide)TextWriter クラスで行います。このクラスは、フレームごとにインスタンスを生成することを想定していますので、明示的な初期化関数を持っていません。デフォルトでタグ文字の処理を行うクラスも設定されますので、独自のタグ文字を処理する必要がない限りは、生成したインスタンスをそのまま使用することができます。また、文字列の書式を展開するバッファを設定していない場合は、書式つきの Printf()
を呼び出したときに、スタックから 256 文字分のメモリが確保されます。スタックを消費したくない場合や、256 文字分以上のバッファが必要な場合はアプリケーションで確保し、SetBuffer()
で設定してください。返り値には以前に設定されていたバッファへのポインタが返されます。
描画された文字列は、文字列表示情報として 1 文字ずつ蓄積されますので、「4.2.1.3. 表示文字列用バッファの確保」で確保した文字列情報を蓄積するバッファを SetDispStringBuffer()
で TextWriter クラスに設定してください。描画に使用するフォントリソースは SetFont()
で設定します。
表示位置(カーソル位置)の設定は SetCursor()
または MoveCursor()
で行います。前者は新しい表示位置そのままを指定し、後者は差分で表示位置を指定します。X, Y, Z 座標それぞれを個別に設定することも、まとめて設定することもできます。デフォルトの設定は (0.0, 0.0, 0.0) です。
表示位置を基準にして、文字列をどのように配置するのかは SetDrawFlag()
で設定します。文字列の配置は、文字列を描画する矩形領域の原点の配置を指定するフラグ(水平・垂直方向)と、文字列を寄せる方向を指定するフラグ(水平方向のみ)との論理和で指定します。フラグは nn::font::PositionFlag
列挙子で定義されています。デフォルトの設定は、HORIZONTAL_ALIGN_LEFT | HORIZONTAL_ORIGIN_LEFT | VERTICAL_ORIGIN_TOP
で、下図はデフォルト設定に対して各フラグを変更したときの配置の変化を示したものです。
文字の拡大縮小は SetScale()
または SetFontSize()
で行います。前者はフォントの幅と高さを基準とする倍率で指定し、後者は表示する文字の幅と高さをピクセルで指定します。拡大縮小はアセントとディセントにも影響を及ぼします。そのため、GetFontAscent()
や GetFontDescent()
は、フォントの持つアセントやディセントとは異なる値を返す可能性があります。デフォルトの設定は等倍です。
文字色の設定は SetTextColor()
で行います。また、SetGradationMode()
で水平・垂直方向にグラデーション効果を与えることができます。グラデーション効果に対しては、SetColorMapping()
で線形変換を設定することができ、設定によっては色の変化を逆転させることが可能です。なお、SetAlpha()
で文字色とは別に、追加のアルファ値を設定することができます。デフォルトの設定は、文字色が (255, 255, 255, 255)、グラデーション効果なし、線形変換なし、追加のアルファ値が 255 です。
1 行の高さの設定は SetLineHeight()
で行います。この設定は改行幅ではなく、行間を自動的に調整します。行間を直接設定する場合は SetLineSpace()
で行ってください。そのほか、タブ幅の設定は SetTabWidth()
、文字間の設定は SetCharSpace()
でそれぞれ行います。デフォルトの設定は、行間と文字間が 0、タブ幅は 4 文字です。
フォントの設定に関係なく、強制的に文字列を等幅で描画する場合は SetFixedWidth()
で描画幅を設定し、EnableFixedWidth(true)
で強制等幅描画を有効に設定してください。EnableFixedWidth()
に false
を指定すると強制等幅描画を無効に戻すことができます。デフォルトの設定は無効です。
ここまでの設定は文字の表示に関する設定であり、TextWriter クラスに対して行っていました。文字を描画するためのグラフィックス関連の設定は RectDrawer クラスに対して行います。
DrawBegin()
で描画を開始するための初期化を行います。描画モードやテクスチャなどを初期化するための描画コマンドが生成され、内部変数などの初期化も行いますので、SetParallax()
で視差を設定する場合はこの関数を呼び出したあとで設定しなければなりません。
射影行列とビュー行列の設定は SetProjectionMtx()
と SetViewMtxForText()
で行います。ライブラリが想定している射影行列は左上原点、スクリーンサイズと画面サイズが一致し、Y 軸と Z 軸の正方向が CTR の座標系と逆転している行列です。ビュー行列は単位行列を想定しています。
文字列の描画は TextWriter クラスで行います。文字を描画すると、文字列表示情報として表示文字列用バッファに一旦蓄積され、蓄積された情報から RectDrawer クラスが描画コマンドを生成します。
TextWriter::StartPrint()
で文字列描画の開始を宣言します。このとき、表示文字列用バッファがクリアされます。
TextWriter::Print()
または TextWriter::Printf()
で文字列を描画します。前者は書式文字列の指定なし、後者は書式文字列の指定ありです。
文字列の描画が完了したら、TextWriter::EndPrint()
で描画完了を宣言します。そのあとに、RectDrawer::BuildTextCommand()
で蓄積された情報をもとに描画コマンドを生成し、TextWriter::UseCommandBuffer()
で描画コマンドをコマンドバッファへ送ります。
最後に RectDrawe::DrawEnd()
を呼び出すことで描画コマンドのキックなどが行われ、レンダーバッファに文字が描画されます。
描画する文字列の内容や表示位置に変更がない場合は、TextWriter::StartPrint()
から TextWriter::EndPrint()
と RectDrawer::BuildTextCommand()
を再度実行することなく、同じ描画結果を得ることができます。さらに、単一色で描画していた場合は、文字色のみを変更することもできます。ただし、これは蓄積された文字列表示情報が保持されている場合に限ります。
以下のコードは、サンプルデモの該当部分です。
//--------------------------------------------------------------------------- //! @brief 文字列表示用にモデルビュー行列と射影行列を設定します。 //! //! @param[in] pDrawer RectDrawerオブジェクトへのポインタ。 //! @param[in] width 画面の幅。 //! @param[in] height 画面の高さ。 //--------------------------------------------------------------------------- void SetupTextCamera( nn::font::RectDrawer* pDrawer, int width, int height ) { // 射影行列を正射影に設定 { // 左上原点とし、Y軸とZ軸の向きが逆になるように設定します。 nn::math::MTX44 proj; f32 znear = 0.0f; f32 zfar = -1.0f; f32 t = 0; f32 b = static_cast<f32>(width); f32 l = 0; f32 r = static_cast<f32>(height); nn::math::MTX44OrthoPivot( &proj, l, r, b, t, znear, zfar, nn::math::PIVOT_UPSIDE_TO_TOP); pDrawer->SetProjectionMtx(proj); } // モデルビュー行列を単位行列に設定 { nn::math::MTX34 mv; nn::math::MTX34Identity(&mv); pDrawer->SetViewMtxForText(mv); } } //--------------------------------------------------------------------------- //! @brief ASCII文字列を描画します。 //! //! @param[in] pDrawer RectDrawerオブジェクトへのポインタ。 //! @param[in] pDrawStringBuf DispStringBufferオブジェクトへのポインタ。 //! @param[in] pFont フォントへのポインタ。 //! @param[in] width 画面の幅。 //! @param[in] height 画面の高さ。 //--------------------------------------------------------------------------- void DrawAscii( nn::font::RectDrawer* pDrawer, nn::font::DispStringBuffer* pDrawStringBuf, nn::font::ResFont* pFont, int width, int height ) { nn::font::TextWriter writer; writer.SetDispStringBuffer(pDrawStringBuf); writer.SetFont(pFont); writer.SetCursor(0, 0); // 文字列が変更されないので、文字列の描画コマンドを一度だけ作成します。 if (! s_InitAsciiString) { writer.StartPrint(); (void)writer.Print("DEMO: ResFont\n"); (void)writer.Print("\n"); // ASCIIの文字見本を表示 (void)writer.Print("All ASCII Character listing:\n"); (void)writer.Print("\n"); (void)writer.Print(" !\"#$%&'()*+,-./\n"); (void)writer.Print("0123456789:;<=>?\n"); (void)writer.Print("@ABCDEFGHIJKLMNO\n"); (void)writer.Print("PQRSTUVWXYZ[\\\]^_\n"); (void)writer.Print("`abcdefghijklmno\n"); (void)writer.Print("pqrstuvwxyz{|}~\n"); writer.EndPrint(); pDrawer->BuildTextCommand(&writer); s_InitAsciiString = true; } // 文字の色は、文字列の描画コマンドを再作成しなくても変更できます。 writer.SetTextColor(nn::util::Color8(s_Color, 255, s_Color, 255)); s_Color++; pDrawer->DrawBegin(); SetupTextCamera(pDrawer, width, height); writer.UseCommandBuffer(); pDrawer->DrawEnd(); }
4.2.1.6. ライブラリによる GPU 設定の変化
RectDrawer クラスを利用してフォントを描画すると、テクスチャのサンプラータイプや頂点属性のロードアドレスなど、様々な GPU 設定が変更されます。そのため、フォントを描画したあとは GPU のすべてのステートをバリデートし、アプリケーションで GPU 設定をすべてやり直すことを推奨していますが、これは冗長な処理となる可能性があります。
ここでは、フォントの描画時に行われる GPU 設定を、GPU の再設定にかかるコストを下げるための参考資料として紹介します。
コンバイナの設定
コンバイナは 3 ~ 5 を使用し、以下のように設定されています。シートのテクスチャフォーマットがアルファ成分を持つものかどうかで、一部の設定が異なります。ちなみに、文字色の表現は頂点カラーの設定で行われています。
設定 | カラー | アルファ |
---|---|---|
ソース 0 |
GL_TEXTURE0
|
GL_TEXTURE0
|
ソース 1 |
GL_CONSTANT
|
GL_CONSTANT
|
ソース 2 |
GL_CONSTANT
|
GL_CONSTANT
|
オペランド 0 |
(アルファなし) (アルファあり) |
GL_SRC_ALPHA
|
オペランド 1 |
GL_SRC_COLOR
|
GL_SRC_ALPHA
|
オペランド 2 |
GL_SRC_COLOR
|
GL_SRC_ALPHA
|
コンバイン |
GL_MODULATE
|
GL_MODULATE
|
スケール | 1.0 | 1.0 |
定数カラー | 白(1.0, 1.0, 1.0, 1.0) |
設定 | カラー | アルファ |
---|---|---|
ソース 0 |
GL_TEXTURE0
|
GL_TEXTURE0
|
ソース 1 |
GL_CONSTANT
|
GL_CONSTANT
|
ソース 2 |
GL_PREVIOUS
|
GL_PREVIOUS
|
オペランド 0 |
(アルファなし) (アルファあり) |
GL_ONE_MINUS_SRC_ALPHA
|
オペランド 1 |
GL_SRC_COLOR
|
GL_SRC_ALPHA
|
オペランド 2 |
GL_SRC_COLOR
|
GL_SRC_ALPHA
|
コンバイン |
GL_MULT_ADD_DMP
|
GL_MULT_ADD_DMP
|
スケール | 1.0 | 1.0 |
定数カラー | 黒(0.0, 0.0, 0.0, 0.0) |
設定 | カラー | アルファ |
---|---|---|
ソース 0 | GL_PRIMARY_COLOR | GL_PRIMARY_COLOR |
ソース 1 | GL_PREVIOUS | GL_PREVIOUS |
ソース 2 | GL_PREVIOUS | GL_PREVIOUS |
オペランド 0 | GL_SRC_COLOR | GL_SRC_ALPHA |
オペランド 1 | GL_SRC_COLOR | GL_SRC_ALPHA |
オペランド 2 | GL_SRC_COLOR | GL_SRC_ALPHA |
コンバイン | GL_MODULATE | GL_MODULATE |
スケール | 1.0 | 1.0 |
定数カラー | ※ 未設定のため不定 |
予約フラグメントシェーダの設定
予約フラグメントシェーダのうち、以下の機能の設定が変更されます。
機能 | 設定 |
---|---|
フラグメントオペレーションモード | 標準モード(GL_FRAGOP_MODE_GL_DMP ) |
フラグメントライティング | 無効 |
シャドウ(シャドウテクスチャ) | 無効 |
フォグ(ガス) | 無効 |
アルファテスト | 無効 |
ブレンディング | 有効 |
テクスチャの設定
テクスチャ 0 のみを使用し、GL_TEXTURE_2D
に設定します。テクスチャイメージのアドレスや解像度、フィルタ設定などが変更されます。
シェーダの設定
整数レジスタ i0 と浮動小数点定数レジスタ c0~c95 に、描画に必要なデータを設定しています。
シェーダプログラムは、頂点座標、頂点カラー、テクスチャ座標 0、テクスチャ座標 1、テクスチャ座標 2 を出力していますが、ジオメトリシェーダを使用することはできません。
4.2.2. タグ文字の処理をカスタマイズする
nn::font::TagProcessorBase クラスを継承したクラスをカスタマイズすることで、アプリケーション独自のタグ文字(0x0000~0x001F)の処理を実装することができます。
文字列を描画している途中に描画すべき文字としてタグ文字が現れたとき、TextWriter クラスは自身に設定されている TagProcessor クラスにタグ文字の処理を行わせます。TextWriter クラスには、タブ(0x0009)と改行(0x000A)を処理する TagProcessor クラスがデフォルトで設定されていますが、SetTagProcessor()
で独自の TagProcessor クラスを使用するように設定することができます。
タグ文字の処理をカスタマイズする場合は、Process()
と CalcRect()
をオーバーライドします。
virtual Operation Process( u16 code, PrintContext<CharType>* pContext); virtual Operation CalcRect(util::Rect* pRect, u16 code, PrintContext<CharType>* pContext);
これらの関数で返した値により、TextWriter クラスは文字を描画する座標の調整を行います。同じタグ文字に対して、Process()
と CalcRect()
が同じ返り値となるように実装してください。
定義 | TextWriter 側で行われる処理 |
---|---|
OPERATION_DEFAULT
|
次の文字との文字間を、行頭ならば空けず、行頭以外ならば空けます。 |
OPERATION_NO_CHAR_SPACE
|
次の文字との文字間を必ず空けません。 |
OPERATION_CHAR_SPACE
|
次の文字との文字間を必ず空けます。 |
OPERATION_NEXT_LINE
|
改行時の処理を行います。X 座標のみが調整され、Y 座標の調整はタグの処理中に行う必要があります。 |
OPERATION_END_DRAW
|
文字列の途中で文字列の描画を終了します。 |
引数 pContext
のメンバには、TextWriter クラスへのポインタがありますので、タグ文字によって文字色を変更するなどの処理を行うことができます。