現在、シミュレーションをプログラミングしており、GDI を使用するアプリケーションから Direct2D を使用するアプリケーションに移植したいと考えています。しかし、Direct2D コードは GDI コードよりもはるかに遅いです。
画面上にたくさんの楕円をレンダリングします。私の GDI アプリケーションでは、メモリ デバイス コンテキストに描画し、BitBlt を使用して Windows デバイス コンテキストに描画します。Direct2D では、ID2D1HwndRenderTarget に描画します。
私の問題は、GDI を使用すると、400 以上の楕円を簡単に描画でき、それでも 400 FPS を維持できることです。Direct2D で同じ数の楕円を実行すると、FPS が 30FPS まで低下します。
すでにアンチエイリアスをオフにしていますが、あまり役に立ちません。興味深いことに、いくつかの楕円を描くだけでも、GDI よりも Direct2D の方が高速です。Direct2D のパフォーマンスを向上させるためにできることはありますか? または、アプリケーションで GDI を使用し続ける必要がありますか?
GDIを使用した私の描画コードは次のとおりです。
VOID Begin() {
SelectObject(this->MemDeviceContext, this->MemoryBitmap);
this->BackgroundBrush = CreateSolidBrush(this->BackgroundColor);
HBRUSH OldBrush = (HBRUSH)SelectObject(this->MemDeviceContext, this->BackgroundBrush);
Rectangle(this->MemDeviceContext, -1, -1, 801, 601);
SelectObject(this->MemDeviceContext, OldBrush);
DeleteObject(this->BackgroundBrush);
SetViewportOrgEx(this->MemDeviceContext, 400, 300, &this->OldOrigin);
}
VOID End() {
SetViewportOrgEx(this->MemDeviceContext, this->OldOrigin.x, this->OldOrigin.y, 0);
BitBlt(this->DeviceContext, 0, 0, 800, 600, this->MemDeviceContext, 0, 0, SRCCOPY);
}
Begin 関数と End 関数の間に、標準的な GDI の方法で楕円を描画します。
Direct2D を使用した begin 関数と end 関数は次のとおりです。
VOID BeginDrawing() {
this->RenderTarget->BeginDraw();
RenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::CornflowerBlue));
RenderTarget->SetTransform(this->ScalingMatrix * this->TranslateMatrix);
}
VOID EndDrawing() {
this->RenderTarget->EndDraw();
}
Direct2D インターフェイスをセットアップする方法を次に示します。それはすべてクラスにラップされています。そのため、完全なコードを投稿することはできません:
if(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &Direct2DFactory) != S_OK)
throw std::runtime_error("RENDERWINDOW::InitializeDirect2D: Failed to create a factory interface.");
RECT WindowRect;
memset(&WindowRect, 0, sizeof(RECT));
GetClientRect(this->WndHandle, &WindowRect);
D2D1_SIZE_U WindowSize = D2D1::SizeU(WindowRect.right, WindowRect.bottom);
Direct2DFactory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_HARDWARE),
D2D1::HwndRenderTargetProperties(this->WndHandle, WindowSize, D2D1_PRESENT_OPTIONS_IMMEDIATELY), &RenderTarget);
前もって感謝します。