GDI versus Direct2D
Ich bin die Programmierung einer simulation im moment, und ich will mein port Anwendung von der Verwendung von GDI mit Direct2D. Aber meine Direct2D-code ist wesentlich langsamer als meine GDI-code.
Ich machen eine Menge von Ellipsen auf dem Bildschirm. In meinem GDI Anwendung ich ziehen, um einen Speicher-Gerätekontext und verwenden Sie dann BitBlt zu ziehen auf den windows-Gerätekontext. Mit Direct2D, ich zeichne auf ein ID2D1HwndRenderTarget.
Mein Problem ist, bei der Verwendung von GDI, ich kann ziehen leicht 400+ Ellipsen und haben noch 400 FPS. Wenn ich die gleiche Anzahl von Ellipsen mit Direct2D, meine FPS sinkt auf 30FPS.
Ich schon umgestiegen antialiasing ausschalten, aber es spielt nicht wirklich helfen. Das interessante an der Sache ist, dass die Zeichnung nur ein paar Ellipsen ist schneller in Direct2D im Vergleich zu GDI. Kann ich irgendetwas tun zur Verbesserung der Leistung in Direct2D, oder sollte ich meine Anwendung mit GDI?
Hier ist meine Zeichnung code mit 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);
}
Zwischen dem Begin-und End-Funktion, ziehe ich meine Ellipsen die standard-GDI-Weg.
Hier sind meine die begin-und end-Funktionen, die mit Direct2D:
VOID BeginDrawing() {
this->RenderTarget->BeginDraw();
RenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::CornflowerBlue));
RenderTarget->SetTransform(this->ScalingMatrix * this->TranslateMatrix);
}
VOID EndDrawing() {
this->RenderTarget->EndDraw();
}
Und hier ist, wie ich meine Direct2D-Schnittstellen. Es ist alles eingewickelt in der Klasse; das ist, warum ich kann nicht nach der vollständige 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);
Vielen Dank im Voraus.
Die Zeichnung code ist standerd Direct2D code zum zeichnen einer ellipse. Ich benutze die FillEllipse und DrawEllipse Funktion und sonst nichts, das ist, warum ich mich nicht per post.
Der Hauptgrund für die Einführung von Direct2D wurde eine neue, saubere API und das Basis-framework für DirectWrite. Zeichnen von Text ist die heutige teuersten Betrieb und DirectWrite hat eine große Verbesserung der Geschwindigkeit für qualitativ hochwertige Texte. Vielleicht sollten Sie überlegen, Tests mit anderen basic-Zeichnung primitiven. Ich bezweifle, dass deine app nur zeichnen von Ellipsen.
InformationsquelleAutor roohan | 2012-11-08
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vor einiger Zeit habe ich abgelehnt Migration rendering code von GDI zu Direct2D aufgrund der niedrigen Leistung. So wie ich das verstehe von google, Direct2D-performance hängt davon ab, Treiber-und hardware-Optimierungen, und Sie sollten nicht erwarten, dass die gleiche Geschwindigkeit auf verschiedenen hardware. GDI ist ziemlich alt und funktioniert auch fast überall.
Muss sagen, ich habe versucht, verwenden es zum zeichnen von einfachen geometrie-primitive in der Erwägung, dass Direct2D zu sein scheint viel mehr robuste Bibliothek und vielleicht könnte es ein performance-boost auf komplexe Szenarien, aber das ist nicht mein Fall.
Wenn Sie brauchen, GDI Leistung mit besserer Qualität – versuchen mit OpenGL oder Direct3D direkt.
Dies ist eine Verwandte Frage:
Ist TDirect2DCanvas langsam oder mache ich etwas falsch?
Portierung von GDI, GDI+ einfach sein sollte. GDI+ unterstützt anti-Aliasing-Ausgang, so dass die Qualität ist so gut, wie Direct2D und die performance von GDI+ ist noch besser als Direct2D.
Direct2D hängt von der Anwesenheit einer DirectX-10/11-Treiber. In dem Fall, dass es nicht vorhanden ist Direct2D zurückgreifen, um software-rendering, in welchem Fall es ' s Leistung ist im schlimmsten Fall auf Augenhöhe mit gdi. Wenn die hardware ist DirectX10/11-fähigen Direct2D übertrifft gdi durch eine LANGE erschossen. GDI+ war ein großer Versuch, aber GDI+ leidet unter schlechter performance als gdi. Ehrlich gesagt, ist die beste Antwort wäre für die OP zu verwenden, was er ist komfortabel mit, dann, nachdem er hat eine funktionierende Anwendung, wenn es nicht so pro formant, wie er will, zu Optimieren!
InformationsquelleAutor Eugene
Ein häufiger Fehler bei ersten versuchen mit Direct2D-Entwickler nicht richtig-cache der D2D-Ressourcen und, anstatt das erstellen und vernichten von Ressourcen allzu oft. Wenn alle Ellipsen sind ähnlich dimensioniert, Sie sollten erstellen und cache diese ellipse Objekt einmal. Wenn Sie über 30 unterschiedlichen Größen/Formen, erstellen ellipse Versionen für alle 30 Größen/Formen nur einmal. Dies erheblich beschleunigt Direct2D. Gleiches gilt für Rechtecke und alle anderen primitiven. Skalierung ein zwischengespeichertes Objekt versus wiederholte Erstellung/Zerstörung ist auch eine Lösung für einige Szenarien, wenn zu viele Variationen existieren für eine primitive, aber mit einer Ressource auf seine native Größe ist ideal und Speicher-Karten ziemlich wenig Speicher zum speichern Ihrer Ressourcen.
Gdi Ellipsen sehen absolut schrecklich und mit Direct3D-direkt ist relativ Komplex, besonders für Ellipsen, große Polygone und höher-level-primitiven. Mit der richtigen Verwendung von Direct2D, die Sie sollten in der Lage, eine gute Geschwindigkeit und hohe Qualität rendering.
Kann ich nur hinzufügen, dass Direct3d ist nicht die Antwort, denn Sie würde tun müssen, genau die gleichen Dinge, die Sie tun müssen, Direct2d mit Bezug auf caching/pre-erstellen von Geometrien, um die beste Leistung aus ihm heraus. Direct2d basiert auf Direct3d und zu einem großen Teil nimmt die Schmerzen zu tun, 2d-Grafiken mit ihm, vor allem Dinge wie Bürsten, AA, Linien und so weiter.
D2D und D3D sind ganz anders. Sie können Speicher freigeben, erstellen Sie composite-renderings, aber die Vorbereitung und Erbringung der D2D-Szene im Vergleich zu einem D3D-Szene ist anders. Aber es ist nicht allzu schwer zu composite. D2D verwenden für den Rahmen, text, verschiedenen spärliche Teile der Szene, und fügen Sie dann D3D für große Daten-Teile der Szene. D3D für 2D ist eine einfachere form von rendering als voll-3D, aber alles ist immer noch eine Linie oder ein Dreieck Topologie so zu planen, über die Verwendung trigonometrischer Funktionen zu erstellen, alles mit den Eckpunkten in D3D Welt. D2D schützt Sie mit nur Eckpunkte.
^ Diese hier sind die Antworten.
InformationsquelleAutor Robert