Win32 API 日本語リファレンス
ホームGraphics.Direct2D › ID2D1CommandList

ID2D1CommandList

COM
IIDb4f34a19-2383-4d76-94f6-ec343657c3dc継承元ID2D1Image自前メソッド開始 vtbl4

公式ドキュメント

記録して再生できる一連のコマンドを表します。

解説(Remarks)

コマンドリストには、記録されたコマンド群とともにリソースの静的なコピーが含まれることはありません。すべてのビットマップ、エフェクト、ジオメトリは実際のリソースへの参照として格納され、すべてのブラシは値として格納されます。リソースの作成と破棄はすべてコマンドリストの外部で行われます。次の表は、リソースがコマンドリスト内でどのように扱われるかを示しています。

リソース コマンドリストでの扱い
単色ブラシ 値渡しされます。
ビットマップブラシ ブラシは値渡しされますが、ブラシの作成に使用されるビットマップは実際には参照されます。
グラデーションブラシ – 線形グラデーションと放射グラデーションの両方 ブラシは値渡しされますが、グラデーションストップコレクション自体は参照されます。グラデーションストップコレクションオブジェクトは不変です。
ビットマップ 参照渡しされます。
描画状態ブロック デバイスコンテキスト上の実際の状態は、変換の設定などの set 関数に変換され、値渡しされます。
ジオメトリ 値渡しされる不変オブジェクト。
ストロークスタイル 値渡しされる不変オブジェクト。
メッシュ 値渡しされる不変オブジェクト。

ターゲットとしてのコマンドリストの使用

次の擬似コードは、ターゲットがコマンドリストまたはビットマップのいずれかとして設定されるさまざまなケースを示しています。
//create a D2D device from an already created DXGI device 
ID2D1Device *pD2D1Device;
pD2D1Factory->CreateDevice(pDxgiDevice, &pD2D1Device);

//create a D2D device context from the D2D device
ID2D1DeviceContext *pD2D1DeviceContext;
pD2D1Device->CreateD2D1DeviceContext(&pD2D1DeviceContext);

//create command list
ID2D1CommandList *pCommandList1;
pD2D1DeviceContext->CreateCommandList(&pCommandList1);

//CreateBitmap
ID2D1Bitmap *pBitmap1;
ID2D1Bitmap *pBitmap2;
pD2D1DeviceContext->CreateBitmap(…, &pBitmap1);
pD2D1DeviceContext->CreateBitmap(…, &pBitmap2);

//Set the bitmap as the target
pD2D1DeviceContext->SetTarget(pBitmap1);
pD2D1DeviceContext->BeginDraw();
RenderMyVectorContent(pD2D1DeviceContext);
pD2D1DeviceContext->EndDraw();

//Set the command list as the target
pD2D1DeviceContext->SetTarget(pCommandList1);
pD2D1DeviceContext->BeginDraw();
RenderMyVectorContent(pD2D1DeviceContext);
pD2D1DeviceContext->EndDraw();

//Drawing a command list to a bitmap target
pD2D1DeviceContext->SetTarget(pBitmap2);
pD2D1DeviceContext->BeginDraw();
pD2D1DeviceContext->DrawImage(pCommandList1);
pD2D1DeviceContext->EndDraw();
後で完全な忠実度で再生するためにベクターコンテンツを保持する唯一の方法は、ターゲットの種類をコマンドリストに設定することです。ビットマップがターゲットとして設定されると、そのターゲットへの描画はすべてラスタライズされます。

ブラシを作成するためのコマンドリストの使用

コマンドリストは再生時に忠実度を保持できるため、パターンブラシをサポートするのに適した方法です。目的のパターンをコマンドリストとして格納し、それを使用してイメージブラシを作成できます。このブラシを使ってパスを塗りつぶすことができます。

コマンドリストでパスを塗りつぶすことをサポートするブラシの種類は、イメージブラシと呼ばれます。

次の擬似コードは、イメージブラシでコマンドリストを使用するプロセスを示しています。

//Draw the pattern to the command list
ID2D1CommandList *pCommandList;
pD2D1DeviceContext->SetTarget(pCommandList);
pD2D1DeviceContext->BeginDraw();
DrawMyPattern(pD2D1DeviceContext);
pD2D1DeviceContext->EndDraw();

//Create the image brush from the command list
ID2D1ImageBrush *pImageBrush;
pD2D1DeviceContext->CreateImageBrush(
    pCommandList, 
    pImageBrushProperties,
    pBrushProperties,
    &pImageBrush);

//Fill the ellipse with the pattern brush
pD2D1DeviceContext->SetTarget(pTargetBitmap);
pD2D1DeviceContext->BeginDraw();
pD2D1DeviceContext->FillEllipse(pEllipse, pImageBrush);
pD2D1DeviceContext->EndDraw();

ブラシはイメージを受け入れるため、次のようなその他の利点もあります。

互換レンダーターゲットの代替としてのコマンドリストの使用

互換レンダーターゲットは、後で実際のシーンと合成される中間ビットマップへのオフスクリーンレンダリングに非常によく使用されます。特に印刷の場合、実際のプリミティブを保持する代わりにすべてがラスタライズされて XPS に送られるため、互換レンダーターゲットを使用するとメモリ使用量が増加します。このシナリオでは、開発者は互換レンダーターゲットを中間コマンドリストに置き換える方がよいでしょう。 次の擬似コードはこの点を示しています。
pD2D1Device->CreateDeviceContext(&pD2D1DeviceContext);
pRenderTarget->CreateCompatibleRenderTarget(…, &pCompatibleRenderTarget);

//render to the compatible render target
pCompatibleRenderTarget->BeginDraw();
RenderMyScene1(pCompatibleRenderTarget);
pCompatibleRenderTarget->EndDraw();

//get the bitmap from the compatible render target
pCompatibleRenderTarget->GetBitmap(pCompatBitmap);

//draw this bitmap on the device context
pD2D1DeviceContext->SetTarget(pTargetBitmap)
pD2D1DeviceContext->BeginDraw();
pD2D1DeviceContext->DrawBitmap(pCompatBitmap);
pD2D1DeviceContext->EndDraw();

//draw something else on the compatible render target
pCompatibleRenderTarget->BeginDraw();
pCompatibleRenderTarget->Clear();
pCompatibleRenderTarget->RenderScene2();
pCompatibleRenderTarget->EndDraw();

//get the bitmap from the compatible render target
pCompatibleRenderTarget->GetBitmap(pCompatBitmap);

//draw this bitmap on the device context
pD2D1DeviceContext->SetTarget(pTargetBitmap)
pD2D1DeviceContext->BeginDraw();
pD2D1DeviceContext->DrawBitmap(pCompatBitmap);
pD2D1DeviceContext->EndDraw();


//Use a command list instead for better quality and performance 

//store the original target
pOriginalTarget = pD2D1DeviceContext->GetTarget();

pD2D1DeviceContext->CreateCommandList(pCommandList1);

//draw to command list 1
pD2D1DeviceContext->SetTarget(pCommandList1);
pD2D1DeviceContext->BeginDraw();
RenderMyScene1(pD2D1DeviceContext);
pD2D1DeviceContext->EndDraw();

//draw the command list to the original target
pD2D1DeviceContext->SetTarget(pOriginalTarget);
pD2D1DeviceContext->BeginDraw();
pD2D1DeviceContext->DrawImage(pCommandList1);
pD2D1DeviceContext->EndDraw();

pD2D1DeviceContext->CreateCommandList(pCommandList2);

//draw something else to a new command list
pD2D1DeviceContext->SetTarget(pCommandList2);
pD2D1DeviceContext->BeginDraw();
pD2D1DeviceContext->RenderScene2();
pD2D1DeviceContext->EndDraw();

//draw the new command list on the old command list
pD2D1DeviceContext->SetTarget(pCommandList1);
pD2D1DeviceContext->BeginDraw();
pD2D1DeviceContext->DrawImage(pCommandList2);
pD2D1DeviceContext->EndDraw();

他の API との連携

Direct2D は、GDI および Direct3D/DXGI API と相互運用する際にシンプルなモデルを採用しています。コマンドリストはこれらのコマンドを記録しません。その代わりに、その場で内容をラスタライズし、ID2D1Bitmap として格納します。内容がラスタライズされるため、これらの相互運用ポイントは高い忠実度を維持しません。

GDI: コマンドシンクインターフェイスは Get/ReleaseDC() の呼び出しをサポートしません。ID2D1GdiInteropRenderTarget::ReleaseDC の呼び出しが行われると、Direct2D は更新された領域の内容を D2D1Bitmap にレンダリングします。これは、コピー合成モードでのエイリアス化された DrawBitmap の呼び出しとして再生されます。 コマンドの再生時にビットマップを正しい DPI でラスタライズするために、その時点で SetDPI() 関数を使用して設定されている DPI 値が使用されます。これは、シンクが SetDPI() の呼び出しを尊重する唯一のケースです。

DX: Direct3D はコマンドリストに直接レンダリングできません。この場合に Direct3D コンテンツをレンダリングするには、アプリケーションは Direct3D サーフェスに基づく ID2D1Bitmap を指定して DrawBitmap を呼び出すことができます。

メソッド 2

vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。

vtbl 4 HRESULT Stream(ID2D1CommandSink* sink)

コマンドリストの内容を、指定されたコマンドシンクにストリーミングします。

sinkID2D1CommandSink*inコマンドリストのストリーミング先となるシンク。

戻り値

型: HRESULT

メソッドが成功した場合は S_OK を返します。失敗した場合は HRESULT エラーコードを返します。

戻り値は、コマンドシンクの実装がその EndDraw メソッドを通じて返すあらゆる失敗を示します。

解説(Remarks)

コマンドシンクは、API の任意の呼び出し元によって実装できます。

コマンドリストがターゲットとして選択されている間に、呼び出し元がデザイン時に失敗する呼び出しを行うと、コマンドリストはエラー状態になります。stream の呼び出しは、渡されたシンクを一切呼び出すことなく失敗します。

使用例:

Class MyCommandSink : public ID2D1CommandSink
{
public:
    // All of the ID2D1CommandSink methods implemented here.
};

HRESULT
StreamToMyCommandSink(
    __in ID2D1CommandList *pCommandList 
    )
{
    HRESULT hr = S_OK;
    
    MyCommandSink *pCommandSink = new MyCommandSink();
    hr = pCommandSink ? S_OK : E_OUTOFMEMORY;

    if (SUCCEEDED(hr))
    {
        // Receive the contents of the command sink streamed to the sink.
        hr = pCommandList->Stream(pCommandSink);
    }

    SafeRelease(&pCommandSink);
   
    return hr;

}
vtbl 5 HRESULT Close()

コマンドリストにコマンドの受け付けを停止するよう指示します。これにより、コマンドリストをエフェクトへの入力として、または ID2D1DeviceContext::DrawImage の呼び出しで使用できるようになります。

戻り値

型: HRESULT

このメソッドは HRESULT を返します。取り得る値には、次の表に示すものが含まれますが、これらに限定されません。

HRESULT 説明
S_OK エラーは発生しませんでした。
D2DERR_WRONG_STATE コマンドリストで Close が既に呼び出されています。
メモ コマンドリストに関連付けられたデバイスコンテキストにエラーがある場合、コマンドリストは同じエラーを返します。

解説(Remarks)

このメソッドは、コマンドリストで既に呼び出されている場合は D2DERR_WRONG_STATE を返します。設定中にデバイスコンテキストでエラーが発生した場合は、そのエラーを返します。それ以外の場合は S_OK を返します。

Close メソッドがエラーを返した場合、それ以降のコマンドリストの使用はすべて同じエラーになります。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

HSP用 COM定義

#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"

#define global IID_ID2D1CommandList "{B4F34A19-2383-4D76-94F6-EC343657C3DC}"
#usecom global ID2D1CommandList IID_ID2D1CommandList "{}"
#comfunc global ID2D1CommandList_Stream  4 sptr
#comfunc global ID2D1CommandList_Close   5
; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。
; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。
; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。