roo*_*han 13 c++ winapi direct2d
我正在编程模拟,我想将我的应用程序从使用GDI移植到使用Direct2D.但我的Direct2D代码比我的GDI代码要慢得多.
我在屏幕上渲染了很多椭圆.在我的GDI应用程序中,我绘制到内存设备上下文,然后使用BitBlt在Windows设备上下文中绘制.使用Direct2D,我绘制到ID2D1HwndRenderTarget.
我的问题是,当使用GDI时,我可以轻松绘制400多个椭圆,并且仍然有400 FPS.当我使用Direct2D执行相同数量的省略号时,我的FPS下降到30FPS.
我已经关闭了antialiasing,但它并没有真正帮助.有趣的是,与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);
}
Run Code Online (Sandbox Code Playgroud)
在我的Begin和End函数之间,我使用标准的GDI方式绘制省略号.
以下是使用Direct2D的开始和结束函数:
VOID BeginDrawing() {
this->RenderTarget->BeginDraw();
RenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::CornflowerBlue));
RenderTarget->SetTransform(this->ScalingMatrix * this->TranslateMatrix);
}
VOID EndDrawing() {
this->RenderTarget->EndDraw();
}
Run Code Online (Sandbox Code Playgroud)
以下是我如何设置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);
Run Code Online (Sandbox Code Playgroud)
先感谢您.
Rob*_*ert 32
首次尝试Direct2D时常见的错误是开发人员没有正确缓存D2D资源,而是经常创建和销毁资源.如果所有省略号的大小相似,则应创建并缓存此椭圆对象一次.如果您有30种不同的尺寸/形状,则只为所有30种尺寸/形状创建椭圆版本一次.这显着加速了Direct2D.矩形和所有其他基元也是如此.如果基元存在太多变体,则缩放缓存对象与重复创建/销毁也是一种解决方案,尽管使用其原始大小的资源是理想的,并且存储卡具有相当多的内存来存储资源.
Gdi椭圆看起来非常糟糕,直接使用Direct3D相当复杂,特别是对于椭圆,大多边形和更高级别的基元.正确使用Direct2D后,您应该能够获得良好的速度和高质量的渲染.
前段时间,由于性能低下,我拒绝将渲染代码从 GDI 迁移到 Direct2D。正如我从谷歌了解到的,Direct2D 性能取决于驱动程序和硬件优化,您不应该期望不同硬件上的速度相同。GDI 已经很老了,几乎在任何地方都能正常工作。
必须说我已经尝试使用它来绘制简单的几何图元,而 Direct2D 似乎是更健壮的库,并且可能在复杂场景中可以提高性能,但这不是我的情况。
如果您需要更高质量的 GDI 性能 - 尝试直接使用 OpenGL 或 Direct3D。
这是一个相关的问题: TDirect2DCanvas 慢还是我做错了什么?
| 归档时间: |
|
| 查看次数: |
12073 次 |
| 最近记录: |