文字列の表示


~デバッグのためにも必要だよね~




■はじめに

fps 値 (frames per second:一秒間に画面を更新した回数) を表示するために必要なので、 デバッグ用の文字表示として、文字列の表示を用意しました。
今回は、次のソースを使います。

■フォント表示クラス

今回は、独立性を考えて、クラス化してみました。 文字列表示用に定義したクラスは次のとおりです。

class CMyFont{
private:
    LPD3DXFONT  m_lpFont;
public:
    CMyFont(){m_lpFont = NULL;};
    virtual void Init(LPDIRECT3DDEVICE8 lpD3DDEV, int w, int h);               // 初期化 (DirectX の初期化の後に呼ぶ)
    virtual void Print(char *str, int x, int y, D3DCOLOR color=0xffffffff);    // 表示
    virtual void Clean();                                                      // オブジェクトの開放
};

フォントの為のインターフェイスは、LPD3DXFONT です。 このポインタを、メンバー変数として表示オブジェクトごとに用意します。
表示するときは、Print を毎フレーム使います。文字列 str と、位置 x, y を指定します。 白以外の色で文字を表示したいときには、さらに D3DCOLOR 型で色を指定します。

■使い方

実際に使うときには、次のように使います。 ありがちな Hello world を作ってみました。 次の関数は、WinMain のウィンドウを作成した後です。

// Direct3D の初期化
if(SUCCEEDED(InitD3D(hWnd))){
    
    sFont.Init(s_lpD3DDEV, 12, 24);// ★★★★★ Direct3D の初期化

    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);

    // メインループ
    MSG msg;
    while (!s_end)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
            // メッセージの処理
        }else{
            // Direct3D の描画
            // バックバッファと Z バッファをクリア
            s_lpD3DDEV->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0);
            // シーン開始
            s_lpD3DDEV->BeginScene();
            
            // 描画などの処理
            sFont.Print("Hello world!", 0,0);// ★★★★★ フォントの描画
            
            // シーン終了
            s_lpD3DDEV->EndScene();
            if (FAILED(s_lpD3DDEV->Present(NULL,NULL,NULL,NULL)))
                s_lpD3DDEV->Reset(&s_d3dpp);// バックバッファをプライマリバッファにコピー
        }
    }
}

// 終了
sFont.Clean();    // ★★★★★ フォントの後かたずけ
RELEASE(s_lpD3DDEV);
RELEASE(s_lpD3D);

return 0;

DirectX として表示するので、BeginScene と、EndScene の間で表示します。

■関数の中身

実は、初期化が一番大切です。
ここで、フォントの種類及び、サイズを指定します。 CreateFont でフォントを設定、作成した後に、D3DXCreateFont で、DirectX で使えるように設定します。

void CMyFont::Init(LPDIRECT3DDEVICE8 lpD3DDEV, int w, int h)
{
    HDC        hTextDC = NULL;
    HFONT    hFont = NULL, hOldFont = NULL;
    
    hTextDC = CreateCompatibleDC(NULL);
    hFont = CreateFont( h, w, 0, 0,
                      FW_REGULAR,
                      FALSE,FALSE,FALSE,
                      SHIFTJIS_CHARSET,
                      OUT_DEFAULT_PRECIS,
                      CLIP_DEFAULT_PRECIS,
                      DEFAULT_QUALITY,
                      DEFAULT_PITCH,
                      "MS ゴシック"
                      );
    if(!hFont) return;
    hOldFont = (HFONT)SelectObject(hTextDC, hFont);
    
    if( FAILED( D3DXCreateFont( lpD3DDEV, hFont, &m_lpFont ) ) ) {
        MessageBox( 0, "D3DXCreateFontIndirect FALSE", "ok", MB_OK);
        return;
    }
    SelectObject(hTextDC, hOldFont);
    DeleteObject(hFont);
}

表示するときには、RECT 型の長方形で、表示領域を設定して、DrawText で表示します。

void CMyFont::Print( char *str, int x, int y, D3DCOLOR color )
{
    RECT rect;
    rect.left = x; 
    rect.right = WIDTH;
    rect.top = y;
    rect.bottom = HEIGHT;

    // デバイス上に、整形した テキストを描画する
    m_lpFont->DrawText(str, -1, &rect
                    ,DT_LEFT | DT_EXPANDTABS
                    ,color
                    );
}

後始末は、作成したオブジェクトを開放します。

void CMyFont::Clean()
{
    RELEASE(m_lpFont);
}




もどる

imagire@gmail.com