Direct2D での描画

グラフィックス リソースを作成したら、描画する準備が整います。

楕円の描画

Circle プログラムは、非常に単純な描画ロジックを実行します。

  1. 背景を単色で塗りつぶします。
  2. 塗りつぶされた円を描画します。

円プログラムのスクリーン ショット。

レンダー ターゲットはウィンドウ (ビットマップやその他のオフスクリーン サーフェスとは対照的) であるため、描画は WM_PAINT メッセージに応答して実行されます。 次のコードは、Circle プログラムのウィンドウ プロシージャを示しています。

LRESULT MainWindow::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_PAINT:
            OnPaint();
            return 0;

         // Other messages not shown...
    }
    return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
}

円を描画するコードを次に示します。

void MainWindow::OnPaint()
{
    HRESULT hr = CreateGraphicsResources();
    if (SUCCEEDED(hr))
    {
        PAINTSTRUCT ps;
        BeginPaint(m_hwnd, &ps);
     
        pRenderTarget->BeginDraw();

        pRenderTarget->Clear( D2D1::ColorF(D2D1::ColorF::SkyBlue) );
        pRenderTarget->FillEllipse(ellipse, pBrush);

        hr = pRenderTarget->EndDraw();
        if (FAILED(hr) || hr == D2DERR_RECREATE_TARGET)
        {
            DiscardGraphicsResources();
        }
        EndPaint(m_hwnd, &ps);
    }
}

ID2D1RenderTarget インターフェイスは、すべての描画操作に使用されます。 プログラムの OnPaint メソッドは次の処理を行います。

  1. ID2D1RenderTarget::BeginDraw メソッドは描画の開始を通知します。
  2. ID2D1RenderTarget::Clear メソッドは、レンダー ターゲット全体を単色で塗りつぶします。 色は 、D2D1_COLOR_F 構造体として指定されます。 D2D1::ColorF クラスを使用して構造体を初期化できます。 詳細については、「 Direct2D での色の使用」を参照してください。
  3. ID2D1RenderTarget::FillEllipse メソッドは、塗りつぶしに指定したブラシを使用して塗りつぶし楕円を描画します。 楕円は、中心点と x および y 半径で指定されます。 x と y-radii が同じ場合、結果は円になります。
  4. ID2D1RenderTarget::EndDraw メソッドは、このフレームの描画の完了を通知します。 すべての描画操作は、 BeginDrawEndDraw の呼び出しの間に配置する必要があります。

BeginDrawClearFillEllipse の各メソッドはすべて void 戻り値の型を持っています。 これらのメソッドの実行中にエラーが発生した場合、 エラーは EndDraw メソッドの戻り値を通じて通知されます。 メソッドは CreateGraphicsResources 、「 Direct2D リソースの作成」トピックに示されています。 このメソッドは、レンダー ターゲットと純色ブラシを作成します。

デバイスは描画コマンドをバッファーに格納し、 EndDraw が呼び出されるまで実行を延期する場合があります。 ID2D1RenderTarget::Flush を呼び出すことで、保留中の描画コマンドをデバイスに強制的に実行させることができます。 ただし、フラッシュするとパフォーマンスが低下する可能性があります。

デバイス損失の処理

プログラムの実行中に、使用しているグラフィックス デバイスが使用できなくなる可能性があります。 たとえば、ディスプレイの解像度が変更された場合、またはユーザーがディスプレイ アダプターを削除すると、デバイスが失われる可能性があります。 デバイスが失われた場合、レンダー ターゲットも、デバイスに関連付けられたデバイス依存リソースと共に無効になります。 Direct2D は、EndDraw メソッドからエラー コード D2DERR_RECREATE_TARGETを返すことによって、紛失したデバイスに通知します。 このエラー コードが表示される場合は、レンダー ターゲットとすべてのデバイス依存リソースを再作成する必要があります。

リソースを破棄するには、そのリソースのインターフェイスを解放するだけです。

void MainWindow::DiscardGraphicsResources()
{
    SafeRelease(&pRenderTarget);
    SafeRelease(&pBrush);
}

リソースの作成は負荷の高い操作になる可能性があるため、 WM_PAINT メッセージごとにリソースを再作成しないでください。 リソースを 1 回作成し、デバイスの損失によってリソースが無効になるまで、またはリソースが不要になるまでリソース ポインターをキャッシュします。

Direct2D レンダリング ループ

描画内容に関係なく、プログラムは次のようなループを実行する必要があります。

  1. デバイスに依存しないリソースを作成します。
  2. シーンをレンダリングします。
    1. 有効なレンダー ターゲットが存在するかどうかを確認します。 そうでない場合は、レンダー ターゲットとデバイスに依存するリソースを作成します。
    2. ID2D1RenderTarget::BeginDraw を呼び出します。
    3. 描画コマンドを発行します。
    4. ID2D1RenderTarget::EndDraw を呼び出します。
    5. EndDrawD2DERR_RECREATE_TARGETを返す場合は、レンダー ターゲットとデバイスに依存するリソースを破棄します。
  3. シーンを更新または再描画する必要がある場合は、手順 2 を繰り返します。

レンダー ターゲットがウィンドウの場合は、ウィンドウが WM_PAINT メッセージを受信するたびに手順 2 が実行されます。

次に示すループでは、デバイス依存リソースを破棄し、次のループの開始時に再作成することで、デバイスの損失を処理します (手順 2a)。

次へ

DPI と Device-Independent ピクセル