2012年7月31日火曜日

単純な初期化の解説

前の節に続いてDirect2Dの解説をします。

Direct2Dの初期化

何を描画するかでどんなオブジェクトを初期化する必要があるかも変わってきますが、最低限必要なものとしてはファクトリとレンダーターゲットがあります。
以下はこの2つを初期化する例です。
-------------------
//ファクトリ
ID2D1Factory* pD2DFactory ;
//レンダーターゲット
ID2D1HwndRenderTarget* pHwndRenderTarget ;

//ファクトリの作成
D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
&pD2DFactory);

//レンダーターゲットのサイズの準備
RECT rect;
::GetClientRect(hWnd, &rect);
D2D1_SIZE_U size =
D2D1::Size<UINT>(rect.right, rect.bottom);

//レンダーターゲットの作成
pD2DFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(hWnd, size),
&pHwndRenderTarget);
----------------------------
(完全なサンプルは前の節で示しています。)


ファクトリ( ID2D1Factory )というのはDirect2Dのリソース(描画用オブジェクト等)を作るための工場みたいなものです。Direct2Dを利用する時はまずはこれを作る必要があります。

ファクトリを作るにはD2D1CreateFactory()という関数を呼びます。
この時に引数で指定できるのはシングルスレッド用にするかマルチスレッド用にするかです。

ファクトリを使って次に説明するレンダーターゲットを作る事が出来ます。レンダーターゲットは重要なリソースです。


レンダーターゲット(ID2D1RenderTarget )は描画対象を管理するインターフェースです。この インターフェース を通して描画に必要な関数を呼び出せます。ブラシを作る時にも必要です。
この ID2D1RenderTarget にはいくつか派生の インターフェース があり、今回作ったのは普通のウインドウを描画対象にするための ID2D1HwndRenderTarge という インターフェース です。
(Direct3Dと同じ描画先に出力したい場合は別の インターフェース を使う必要があります。)

レンダーターゲットの作成は先ほど作成したファクトリのメソッド CreateHwndRenderTarget() を使って行います。
その際、いくつかの初期設定が行えるのですが、例で示したデフォルトの設定でハードウェアレンダリングによる高速な描画が期待できます。

描画の実行

をする時は、今作ったレンダーターゲットのメソッドBeginDraw()EndDraw()の間で行います。

例)
pHwndRenderTarget->BeginDraw();
//画面を一色で塗り潰す
pHwndRenderTarget->Clear(D2D1::ColorF(1.0F, 1.0F, 1.0F));

pHwndRenderTarget->EndDraw();

前節のサンプルでは描画テストをするRenderTest()という関数の中でブラシを作成していました。(リンク:ブラシの概要

// ブラシの作成 --------
ID2D1SolidColorBrush* pGreenBrush = NULL;

pHwndRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(0.0F, 1.0F, 0.0F), &pGreenBrush);
-----------------------

そしてBeginDraw()とEndDraw()の間で 四角形の描画等をしていました。
//四角形の描画-----------
D2D1_RECT_F rect1 =
D2D1::RectF(100.0F, 50.0F, 300.0F, 100.F);
pHwndRenderTarget->FillRectangle(&rect1, pGreenBrush);
----------------------------
そして開放していました。
pGreenBrush->Release();

リソースについて

リソースというのは型通りの説明をするならばCOMのIUnknownというインターフェースを継承するID2D1Resource型の派生クラスです。
簡単に言ってしまえばDirect2Dで使用する描画関連の情報です。

リソースにはビデオメモリに配置する物と、そうでない物があります。今回使用したリソースは
・ファクトリ( ID2D1Factory
・レンダーターゲット( ID2D1HwndRenderTarge
・ブラシ (ID2D1Brush)
の3つであり、
この内レンダーターゲットとブラシはビデオメモリと関連付けられます。
ビデオメモリと関連付けられるリソースはデバイス依存、そうでないリソースはデバイス非依存と呼ばれたりもします。ここで言うデバイスはグラフィック装置というニュアンスです。

リソースは単なる構造体のデータなどとは違い、Direct2DAPIによってメモリ管理がなされる、言わば「重めのデータ」あるいは「高貴なデータ」と言った感じがします。

今回のサンプルではデバイスの初期化に比重を置き、ブラシを使った図形の描画はRenderTest()内にまとめました。しかし短い時間に何度も描画する場合はリソースを頻繁に作成するのではなく、ファクトリやレンダーターゲットと同様にクラスメンバとして管理するのが良いでしょう。
ただし、今回利用したSolidColorBrush(単色のブラシ)に関しては毎回作ってもさほど重くもないとか。…また、アプリケーションによってはウインドウのリサイズ時にしか再描画の必要がなくてパフォーマンスが気にならないというケースもあるでしょうが。

ブラシの色の変更

今回作ったブラシの名前が pGreenBrushなので使う色の種類毎にブラシを用意しなければならない様に思えるかも知れませんが、そんな事はありません。 ブラシには色を変更するメソッドが用意されています。
以下はいずれもブラシを赤色に再設定する例です

pGreenBrush->SetColor(D2D1::ColorF(1.0f, 0.0f, 0.0f));
pGreenBrush->SetColor(D2D1::ColorF(0xFF0000));
pGreenBrush->SetColor(D2D1::ColorF(D2D1::ColorF::Red));

SetColor()の引数の中では
namespace D2D1の関数を使って色を作っています。

透明度の設定
は以下のメソッドで出来ます。
 pGreenBrush->SetOpacity(0.5);//半透明

SetColorに4つめの引数を与えて色の設定と一緒に設定する事もできます。
pGreenBrush->SetColor(D2D1::ColorF(1.0f, 0.0f, 0.0f, 0.5f));

リソースの解放

リソース型は IUnknownというインターフェースを継承すると上で書きました。リソースを解放するにはこのIUnKnownのRelease()というメソッドを使います。

//ファクトリとレンダーターゲットの解放例

pHwndRenderTarget->Release();
pD2DFactory->Release();

C++でnewしたオブジェクトを2回deleteしてはいけないのと同様、リソースも通常は2回以上 Release() してはいけません。

今回のサンプルのクラスをコピー(代入)禁止にしたのは、デストラクタでリソースを解放する様にしたからです(より正確に言うとデストラクタの中のD2D::DestroyDevice()というメソッドで開放処理をしています)。

0 件のコメント: