ゆとりーなの日記

日記的な事を書いて行くと思はれる

Direct2Dで一昔前󠄁のFFつぽいメニュー畫面を書く

Direct2Dはひとまづ初期化󠄁さへしてしまへば結構󠄁色々な事がわりと簡單にできる。
例へば一昔前󠄁のFFのメニュー畫面つぽいのもあつさり書ける。レンダリングターゲットはID2D1DeviceContextなりID2D1HWNDRendetTargetでもどちらでもよい。

// メニューのグラデーションを定義
Microsoft::WRL::ComPtr<ID2D1GradientStopCollection> stopCollection;
const std::array<D2D1_GRADIENT_STOP, 2> menuStops = {{
  {0.f, D2D1::ColorF(0.f, 0.f, 1.f)}, {1.f, D2D1::ColorF(0.f, 0.f, 0.3f)}
}};
d2d1DeviceContext->CreateGradientStopCollection(menuStops.data(), menuStops.size(), &stopCollection);

// メニュー用の線形グラデーションブラシを作る
const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES lgbp = D2D1::LinearGradientBrushProperties(D2D1::Point2(0.f, 320.f), D2D1::Point2(0.f, 480.f));
Microsoft::WRL::ComPtr<ID2D1LinearGradientBrush> menuBrush;
d2d1DeviceContext->CreateLinearGradientBrush(lgbp, stopCollection.Get(), &menuBrush);

// 枠のグラデーションを定義
const std::array<D2D1_GRADIENT_STOP, 2> frameStops = {{
  {0.f, D2D1::ColorF(1.f, 1.f, 1.f)}, {1.f, D2D1::ColorF(0.5f, 0.5f, 0.5f)}
}};
d2d1DeviceContext->CreateGradientStopCollection(frameStops.data(), frameStops.size(), &stopCollection);

// 枠用の線形グラデーションブラシを作る
Microsoft::WRL::ComPtr<ID2D1LinearGradientBrush> frameBrush;
d2d1DeviceContext->CreateLinearGradientBrush(lgbp, stopCollection.Get(), &frameBrush);

グラデーションの定義はD2D1_GRADIENT_STOPの配列で行なふ。0.fが始點の色で1.fが終󠄁點の色になつてこれらの間を良い感じにグラデーションする。途󠄁中に何か入れるとその色もグラデーションに反映される。作つた定義はレンダリングターゲットのCreateGradientStopCollectionに突󠄁つ込󠄁んでID2D1GradientStopCollectionを作る。
D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIESはどこを始點と終󠄁點にするかを定義する。指定する座標は何もしないなら描畫上の座標と同じでよい。今回のやうに指定するとy座標の320.f(0.fで指定した色)→480.f(1.fで指定した色)の範圍󠄁內で描畫すると、縱方向に指定した色に從つてグラデーションがかかる。
D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIESとID2D1GradientStopCollectionの用意󠄁ができたらレンダリングターゲットのCreateLinearGradientBrushで線形ブラシを作つて準備は終󠄁了。

// Direct3Dで畫面をクリア
float color[] = {0.f, 0.f, 0.f, 1.f}; 
d3d11DeviceContext->ClearRenderTargetView(d3d11RenderTargetView.Get(), color);

// Direct2Dでの描畫開始
d2d1DeviceContext->BeginDraw();

d2d1DeviceContext->FillRoundedRectangle(D2D1::RoundedRect(D2D1::Rect(0.f, 320.f, 640.f, 480.f), 10.f, 10.f), menuBrush.Get());
d2d1DeviceContext->DrawRoundedRectangle(D2D1::RoundedRect(D2D1::Rect(0.f, 320.f, 640.f, 480.f), 10.f, 10.f), frameBrush.Get(), 6.f);

// Direct2Dでの描畫終󠄁了
ThrowIfFail(d2d1DeviceContext->EndDraw(), "ID2D1DeviceContext::EndDraw");

// 描畫內容を畫面に反映
ThrowIfFail(dxgiSwapChain->Present(1, 0), "IDXGISwapChain::Present");

あとはBeginDrawとEndDrawの間で線形ブラシを使󠄁つて四角形と四角形の枠を表示する。Direct2DではFillほげほげが中も塗り潰して描畫、Drawほげほげは枠だけ描畫になる。Draw系の方は第3引數に枠の太さを指定出來る。

實行結果

f:id:nagoya313:20141006195827p:plain
それなりにFFつぽくなつた。因みに今回みたいにID2D1DeviceContextの方を使󠄁へばDirect3D11とも連󠄀繫できるので戰鬪畫面は3Dにできたりもする。