I'm programming a simulation at the moment, and I want to port my application from using GDI to using Direct2D. But my Direct2D code is much slower than my GDI code.
I render a lot of ellipses on the screen. In my GDI application I draw to a memory device context and then use BitBlt to draw on the windows device context. With Direct2D, I draw onto a ID2D1HwndRenderTarget.
My Problem is, when using GDI, I can draw easily 400+ ellipses and still have 400 FPS. When I do the same number of ellipses with Direct2D, my FPS drops down to 30FPS.
I already switched antialiasing off but it doesn't really help. The interesting thing is that drawing just a few ellipses is faster in Direct2D compared to GDI. Is there anything I can do to improve the performance in Direct2D, or should I keep my application using GDI?
Here is my drawing code using 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);
}
Between my Begin and End function, I draw my ellipses the standard GDI way.
Here are my begin and end functions using Direct2D:
VOID BeginDrawing() {
this->RenderTarget->BeginDraw();
RenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::CornflowerBlue));
RenderTarget->SetTransform(this->ScalingMatrix * this->TranslateMatrix);
}
VOID EndDrawing() {
this->RenderTarget->EndDraw();
}
And here is how I set up my Direct2D interfaces. It's all wrapped in class; that's why I cant post the full code:
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);
Thank you in advance.