Grafikperformance
-
Hi all
ich bau gerade an einem Frontend, was Datenreihen visualisiert. Das ist in meinem Fall relativ zeitaufwändig und teuer für die CPU.
Da ich mit den verfügbaren VCL-Komponenten die gewünschte flüssige Darstellung nicht erreiche, überlege ich mir nun Alternativen.1. Ich gehe hart auf WINAPI, schlage mit HDCs, HBITMAPs und BitBlt rum
2. Ich arbeite mich in DirectX ein
Mit beiden Dingen habe ich wenig, bzw. gar keine Erfahrung und müsste mich entsprechend einarbeiten. Im konkreten Fall geht es um eine Chartkomponente, die verschiedene Daten darstellt. Darüber ist anstelle des Mauszeigers ein Crosshair, welches performant und vorallem flüssig bewegt werden soll. Im konkreten Fall gerät das vor allem deswegen ins Stocken, weil der Renderprozess meines Charts aktuell auch gut und gerne mal 50-100ms dauert, je nach Datenaufkommen.
Dadurch wird die Komponente dann unhandlich.Von WINAPI oder DirectX erwarte ich mir deutlich höhere Zeichenperformance und für die Zukunft dann auch vielerlei andere Möglichkeiten ( Opacity z.B. )...
Welches würdet ihr mir empfehlen? ( oder gar etwas ganz anderes )
-
Wie groß sind die Datenreihen denn, die du da visualisieren willst? Zeichnest du auch immer nur den Ausschnitt der gerade dargestellt werden soll, oder einfach immer alles? Oder soll immer alles dargestellt werden?
Mit Direct3D wirst du natürlich potentiell die beste Performance bekommen. Die Frage ist nur, ob es wirklich nötig ist, Direct3D zu verwenden.
-
Naja der Chart setzt sich aus verschiedenen Teilen zusammen.
Zum einen ein Hintergrundbild, was ich aktuell nur beim ResizeEvent einmalig generiere und dann nur noch mit Draw in das TBitMap des Charts reinkopiere.
Danach werden die Datenreihen gezeichnet, die im Wesentlichen aus FillRect-Objekten bestehen, mitunter auch einige 1000.
Danach kommen noch horizontale und vertikale Achsen hinzu.
Beim Anzeigeprozess wird dann dieses TBitMap mittels Draw auf das eigentliche Canvas der Paintbox kopiert.Das ganze TBitMap wird aber vorher noch zwischengepuffert, damit man beim MouseMove dann nur noch mittels Draw den Puffer in die Paintbox kopiert und dann das Crosshair oben drauf zeichnet.
Möglicherweise werden noch Dinge neugezeichnet, die sich eigentlich gar nicht verändert haben...
-
Hm ok. Ich muss zugeben dass es mir schwer fällt, abzuschätzen ob das mit GDI dann richtig flüssig laufen würde oder nicht. Ich denke ich würde dir in dem Fall zu OpenGL raten, damit wirst du das vermutlich am einfachsten mit relativ guter Performance zu stande bringen. Für das was du da vorhast, sollte schon ein bisschen glBegin() und glEnd() gut genug sein. Und damit bekommt man sehr einfach was gezeichnet, auch wenn es veraltet ist. Modernes OpenGL und Direct3D, sind jedenfalls relativ aufwändig. Interessant wär vielleicht, auf welcher Hardware und welchen Betriebssystemen das laufen soll.
-
Laufen soll es auf verbreiteten Officerechnern mit üblichen Windows-BS ( also ab XP ). Ich werde nun trotzdem erstmal meinen derzeitigen Code untersuchen ob ich da noch Schwachstellen finde.
-
Ok, in dem Fall wäre wohl OpenGL 1.1 oder so eine Lösung, falls du es mit VCL Bordmitteln nicht schneller bekommst.
-
Wie groß sind denn die Datenreihen? Vielleicht kann man da mit etwas Intelligenz eine Reduktion erzielen? Ich habe ein ahnliches Problem, bei dem Zeitverläufe mit mehreren Zehntausend Datenpunkten als Diagramm angezeigt werden sollen. Statt jetzt 10.000 Stützpunkte in eine Kurve zu prügeln erzeuge ich ein repräsentatives Set aus 1.000 Stützpunkten und baue daraus die Kurve zusammen. Zur Visualisierung benutze ich die TeeCharts, dabei habe ich bisher keine Performanceprobleme feststellen können.
-
Erstmal vielen Danke für eure bisherigen Beiträge.
Das hat mich schon etwas näher an mein eigentliches Problem gebracht.
Es gibt tatsächlich noch unnötige Zeichenoperationen im meiner Renderfunktion.Ich teile jetzt meinen Chart in weitere Layer auf ( also z.B. pro Datenreihe ein HDC ) und kopiere die dann nur zusammen. Dadurch muss ich diverse Dinge nicht neu Zeichnen und kann sogar nur Teile des HDC mit Blit zusammenkopieren. Das sollte zunächst reichen um die Chartkomponenten auf Vordermann zu bringen.
Dennoch habe ich mich entschlossen, erstmal die WINAPI zu Hilfe zu nehmen, da ich ohnehin noch Transparenz benötige. Da ich das Zeichnen mit WINAPI auf HDC soweit schonmal hinbekomme, bin ich jetzt grad an der Transparenz dran. Da macht mir bei WINAPI-AlphaBlend aktuell der CBuilder Probleme... aber die muss ich selber lösen ^^
Danke euch erstmal