Schnelles Zeichnen von Linien
Schnelles Zeichnen von Linien
Hallo,
ich habe vor eine Art Echtzeit-Oszilloskop-Widget zu bauen. Zu diesem Zwecke müßten zahlreiche Linien gemalt werden. Die Anzahl der Linien werde ich vor dem Zeichnen sicher minimieren. Wenn ich aber überlege, daß pro Bildschirmspalte eine vertikale Linie nötig sein könnte und das mit 15-20 fps kommt mir as doch reichlich viel vor. In ersten Tests erwiesen sich die Zeichenfunktionen (drawLine(),drawPolyline()) auch nicht als sehr schnell.
Könnte man sich nicht einfach zwei Speicherblöcke geben lassen, in denen man einfach nur ein paar Bits setzt und die als Bitmap abwechselnd in das Widget kopiert werden?
Erscheint Euch das praktikabel, oder habt Ihr bessere Vorschläge?
Danke,
Ulf
ich habe vor eine Art Echtzeit-Oszilloskop-Widget zu bauen. Zu diesem Zwecke müßten zahlreiche Linien gemalt werden. Die Anzahl der Linien werde ich vor dem Zeichnen sicher minimieren. Wenn ich aber überlege, daß pro Bildschirmspalte eine vertikale Linie nötig sein könnte und das mit 15-20 fps kommt mir as doch reichlich viel vor. In ersten Tests erwiesen sich die Zeichenfunktionen (drawLine(),drawPolyline()) auch nicht als sehr schnell.
Könnte man sich nicht einfach zwei Speicherblöcke geben lassen, in denen man einfach nur ein paar Bits setzt und die als Bitmap abwechselnd in das Widget kopiert werden?
Erscheint Euch das praktikabel, oder habt Ihr bessere Vorschläge?
Danke,
Ulf
Re: Schnelles Zeichnen von Linien
Guckst Du Dir bitte das mal an.stimpy hat geschrieben:Hallo,
Erscheint Euch das praktikabel, oder habt Ihr bessere Vorschläge?
Danke,
Ulf
Nimm' aber bitte die 5er Version von Januar 2006, denn diese ist auch für Qt 4.x lauffähig. Und wundere dich bitte nicht, das die Zoom-Funktion oft nicht so will, wie Du willst. Das ist ein ganz bekanntes Problem bei dem PlotWidget, bei dem aber bereits ganze Threads seitenweise darüber existieren, wie man sowas in den Griff bekommt.
QWT
QWT hatte ich vor ein paar Tagen installieren wollen, leider haber ich
nach einer Weile entnervt aufgegeben, weil die Makefiles nicht funktioniert
haben (VC++6). Und nach der x-ten Anpassung der Dateien habe ich
aufgegeben. Ich wußte ja nicht, daß da so Echtzeitoptimierungen schon
drin sind. Ich mach dann nochmal einen Anlauf...
Danke,
Ulf
nach einer Weile entnervt aufgegeben, weil die Makefiles nicht funktioniert
haben (VC++6). Und nach der x-ten Anpassung der Dateien habe ich
aufgegeben. Ich wußte ja nicht, daß da so Echtzeitoptimierungen schon
drin sind. Ich mach dann nochmal einen Anlauf...
Danke,
Ulf
Als Autor der Qwt Bibliothek will ich das so nicht stehen lassen: bei allen Anfragen bezüglich Performance Problemen, hat sich bislang eigentlich immer herausgestellt, daß das Problem mit einer ungeschickten Ansteuerung zu tun hatte. ( Das ist nicht als Vorwurf gemeint, da man es bei einem Projekt wie Qwt naturgemäß häufig mit programmierenden Ingenieuren zu tun hat, deren Fähigkeiten eher auf der fachlichen Seite liegen. )lepsai hat geschrieben:QWT ist lahm, finger weg davon...
Alle mir bekannten (bis auf eine OpenGL Canvas), allgemeinen Möglichkeiten das Zeichnen zu beschleunigen sind in Qwt implementiert. Erwähnenswert bessere Performance kann man eigentlich nur erzielen, wenn man individuelle Besonderheiten der Daten/Darstellung ausnutzen kann.
QwtPlot/QwtPlotItem unterstützt, daß eine Applikation das Zeichnen von Daten auch selber in die Hand nimmt. Wenn man also eine spezielle Optimierung implementieren kann, geht das sehr viel einfacher, als ein komplettes Plot Widget von Null aus zu programmieren.
Dafür muß man aber über ein gewisses Grundwissen im Umgang mit QPainter verfügen.
Letzendlich ist Qwt durch die Geschwindigkeit von Qt limitiert. Dabei gilt es zu beachten, daß Qt4 nach wie vor langsamer als Qt3 ist, wobei die Unterschiede auf X11 kleiner, bei Windows nennenswert und auf dem Mac sehr problematisch sind.
Uwe
PS: SourceForge hat nach wie vor Problemem mit anonymous CVS. Wenn es Probleme mit dem letzten offizielle Snapshot gibt, hilft eventuell: http://qwt.sourceforge.net/snapshot.
-
BartSimpson
- Beiträge: 1379
- Registriert: 6. November 2004 12:03
- Kontaktdaten:
Also ich wollte ja keine Glaubenskriege provozieren.
Bei dem QWT ist ein Beispiel "realtime_plot" dabei. Ist das ein Beispiel für die maximale Geschwindigkeit? Wo müßte ich mich denn reinhängen, um mehr rauszuholen?
Mal sehen, wie man OpenGL einfache Linien malt... *grusel*
Ich hatte ja gehofft, daß mir QT einen Speicherblock gibt, ich male rein und QT schickt das per Kopierbefehl in das Widget-Rechteck...
Bei dem QWT ist ein Beispiel "realtime_plot" dabei. Ist das ein Beispiel für die maximale Geschwindigkeit? Wo müßte ich mich denn reinhängen, um mehr rauszuholen?
Mal sehen, wie man OpenGL einfache Linien malt... *grusel*
Ich hatte ja gehofft, daß mir QT einen Speicherblock gibt, ich male rein und QT schickt das per Kopierbefehl in das Widget-Rechteck...
Wofür brauchst du eigentlich ein Echtzeit-Oszilloskop? Was willst du damit bezwecken?stimpy hat geschrieben:Also ich wollte ja keine Glaubenskriege provozieren.
Bei dem QWT ist ein Beispiel "realtime_plot" dabei. Ist das ein Beispiel für die maximale Geschwindigkeit? Wo müßte ich mich denn reinhängen, um mehr rauszuholen?
Mal sehen, wie man OpenGL einfache Linien malt... *grusel*
Ich hatte ja gehofft, daß mir QT einen Speicherblock gibt, ich male rein und QT schickt das per Kopierbefehl in das Widget-Rechteck...
Also, wenn ich Dir eine Empfehlung geben darf:
Als erstes solltest Du Dir überlegen, wie oft Du ein neues Bild tatsächlich brauchst und aus wievielen Linien es besteht. Häufig sind die Anforderungen völlig unkritisch, um ein Bild jeweils neu zu rendern - egal, ob optimiert oder nicht.
Schau Dir z.B mal das data_plot Beispiel von Qwt an: Dort wandern 2 Kurven von jeweils 200 Punkten in entgegengesetzter Richtung in 50ms Intervallen. Dabei wird der Plot in jedem Intervall komplett neu gerendert. Wenn Du in data_plot.cpp in Zeile 87 den Timer auf 10ms runtersetzt, fliegen (Qt3+Qt4, X11, 2.4 Ghz Pentium) die Kurven aneinander vorbei.
Falls das Beispiel auf Deiner Zielplattform ebenfalls flüssig läuft und Deine Anforderungen vergleichbar sind, vergiss diese Diskussion so schnell wie möglich.
Kommen z.B. zu einem Scatter Plot mit 1000000 Punkten 100 dazu, ist klar, daß das was bringt. Eine andere häufige Verwendung ist z.B wenn Daten von links nach rechts ergänzt werden und bei Erreichen der rechten Grenze, das dargestellte Intervall inkrementiert wird.
Um zu sagen, ob inkrementelles Zeichnen für Dich was bringt, müsstest Du aber mehr über Deine Applikation schreiben.
HTH,
Uwe
Als erstes solltest Du Dir überlegen, wie oft Du ein neues Bild tatsächlich brauchst und aus wievielen Linien es besteht. Häufig sind die Anforderungen völlig unkritisch, um ein Bild jeweils neu zu rendern - egal, ob optimiert oder nicht.
Schau Dir z.B mal das data_plot Beispiel von Qwt an: Dort wandern 2 Kurven von jeweils 200 Punkten in entgegengesetzter Richtung in 50ms Intervallen. Dabei wird der Plot in jedem Intervall komplett neu gerendert. Wenn Du in data_plot.cpp in Zeile 87 den Timer auf 10ms runtersetzt, fliegen (Qt3+Qt4, X11, 2.4 Ghz Pentium) die Kurven aneinander vorbei.
Falls das Beispiel auf Deiner Zielplattform ebenfalls flüssig läuft und Deine Anforderungen vergleichbar sind, vergiss diese Diskussion so schnell wie möglich.
Nein, es zeigt eine Optimierung für Situationen in denen Daten inkrementell wachsen. Um neue Daten anzuzeigen, muß man einen Plot nicht komplett neu zeichnen, sondern es genügt nur die neuen Daten anzuzeigen. (Qt 4.1.2/Win ist buggy, Du benötigst dafür Qt 4.1.1, oder einen 4.1.3 Snapshot).stimpy hat geschrieben: Bei dem QWT ist ein Beispiel "realtime_plot" dabei. Ist das ein Beispiel für die maximale Geschwindigkeit?
Kommen z.B. zu einem Scatter Plot mit 1000000 Punkten 100 dazu, ist klar, daß das was bringt. Eine andere häufige Verwendung ist z.B wenn Daten von links nach rechts ergänzt werden und bei Erreichen der rechten Grenze, das dargestellte Intervall inkrementiert wird.
Um zu sagen, ob inkrementelles Zeichnen für Dich was bringt, müsstest Du aber mehr über Deine Applikation schreiben.
HTH,
Uwe
Achja,
schreib noch folgende 2 Zeilen im data_plot Beispiel in den Konstruktor von DataPlot:
QwtPainter::setDeviceClipping(false);
canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
Das bringt noch einmal eine deutliche Verbesserung. Es gibt noch einen MSVC Bug/Feature, der zu einer kleineren Performancebremse führt. Wenn Du tatsächlich Qwt nutzen willst, erkläre ich Dir noch was man tun muß,
Uwe
schreib noch folgende 2 Zeilen im data_plot Beispiel in den Konstruktor von DataPlot:
QwtPainter::setDeviceClipping(false);
canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
Das bringt noch einmal eine deutliche Verbesserung. Es gibt noch einen MSVC Bug/Feature, der zu einer kleineren Performancebremse führt. Wenn Du tatsächlich Qwt nutzen willst, erkläre ich Dir noch was man tun muß,
Uwe
QWT - erster Eindruck
Hallo,
naja vielleicht ist "Echtzeit" etwas zu hoch gegriffen. Das ist eine Anwendung an der Uni, wo biologische Meßdaten mit momentan bis zu 200 kHz abgetastet werden. Da möchte man immer sehen, was gerade läuft.
200000 Daten werde also zu Segmenten verdichtet, die einem Pixel Bildschirmbreite entsprechen. In einem (z.B.) 500 Pixel breiten Widget werden 500 vertikale Linien gezogen vom Segment-Minimum zum Segment-Maximum (damit man Rauschen innerhalb des Segmentes erkennen kann). Welche Bildwiederholrate notwendig ist, weiß ich noch nicht. Bei 10 Hz müßten also 5000 Linien pro Sekunde gemalt werden. Bei einem ganz simplen Tests ohne weitere Optimierungen waren mit QT 6000 Linien/s machbar. Das könnte knapp werden.
QWT wollte ich schon mehrfach installieren, bin aber dabei stets gescheitert. Die generierten Makefiles bedürfen etlicher Nachbesserungen von Hand, damit sie überhaupt laufen (VC++6). Die Pfade zu den Includes und Libs des VC++ fehlen. Jetzt habe ich mehrere Stunden mit den Makefiles zugebracht aber immerhin, es geht.
Das Beispiel "data_plot" sieht bei kleinen Fenstern recht rasant aus. Sobald man aber das Fenster groß macht, oder andere Fenster verschiebt dann bricht die Geschwindigkeit ein (das können die OpenGL-Beispiele besser). Auf jeden Fall werde ich mich mal mehr mit QWT beschäftigen. Unverzichtbar wäre allerdings der obe beschriebene Modus der Minimum und Maximum des verdichteten Segments darstellt, damit ich nicht die Daten gefiltert anzeige. Geht das mit QWT?
Außerdem ist mir aufgefalen, daß während der Darstellung die Skalierung angepaßt wird - das sieht u.U. seltsam aus und kostet evtl. auch Zeit.
Wenn ich bahnbrechende Erkenntnisse mache, melde ich mich nochmal...
naja vielleicht ist "Echtzeit" etwas zu hoch gegriffen. Das ist eine Anwendung an der Uni, wo biologische Meßdaten mit momentan bis zu 200 kHz abgetastet werden. Da möchte man immer sehen, was gerade läuft.
200000 Daten werde also zu Segmenten verdichtet, die einem Pixel Bildschirmbreite entsprechen. In einem (z.B.) 500 Pixel breiten Widget werden 500 vertikale Linien gezogen vom Segment-Minimum zum Segment-Maximum (damit man Rauschen innerhalb des Segmentes erkennen kann). Welche Bildwiederholrate notwendig ist, weiß ich noch nicht. Bei 10 Hz müßten also 5000 Linien pro Sekunde gemalt werden. Bei einem ganz simplen Tests ohne weitere Optimierungen waren mit QT 6000 Linien/s machbar. Das könnte knapp werden.
QWT wollte ich schon mehrfach installieren, bin aber dabei stets gescheitert. Die generierten Makefiles bedürfen etlicher Nachbesserungen von Hand, damit sie überhaupt laufen (VC++6). Die Pfade zu den Includes und Libs des VC++ fehlen. Jetzt habe ich mehrere Stunden mit den Makefiles zugebracht aber immerhin, es geht.
Das Beispiel "data_plot" sieht bei kleinen Fenstern recht rasant aus. Sobald man aber das Fenster groß macht, oder andere Fenster verschiebt dann bricht die Geschwindigkeit ein (das können die OpenGL-Beispiele besser). Auf jeden Fall werde ich mich mal mehr mit QWT beschäftigen. Unverzichtbar wäre allerdings der obe beschriebene Modus der Minimum und Maximum des verdichteten Segments darstellt, damit ich nicht die Daten gefiltert anzeige. Geht das mit QWT?
Außerdem ist mir aufgefalen, daß während der Darstellung die Skalierung angepaßt wird - das sieht u.U. seltsam aus und kostet evtl. auch Zeit.
Wenn ich bahnbrechende Erkenntnisse mache, melde ich mich nochmal...
Re: QWT - erster Eindruck
Wenn die Linien die selbe Farbe haben sollen, geht das auch als ein gefülltes Polygon. Das würde dann wohl schneller gehen.stimpy hat geschrieben:200000 Daten werde also zu Segmenten verdichtet, die einem Pixel Bildschirmbreite entsprechen. In einem (z.B.) 500 Pixel breiten Widget werden 500 vertikale Linien gezogen vom Segment-Minimum zum Segment-Maximum (damit man Rauschen innerhalb des Segmentes erkennen kann). Welche Bildwiederholrate notwendig ist, weiß ich noch nicht. Bei 10 Hz müßten also 5000 Linien pro Sekunde gemalt werden
Da machst Du vermutlich etwas verkehrt bzw. Deine qmake Umgebung paßt nicht. Qwt/MSVC ist eine der häufig verwendeten Kombinationen.stimpy hat geschrieben: QWT wollte ich schon mehrfach installieren, bin aber dabei stets gescheitert. Die generierten Makefiles bedürfen etlicher Nachbesserungen von Hand, damit sie überhaupt laufen (VC++6). Die Pfade zu den Includes und Libs des VC++ fehlen. Jetzt habe ich mehrere Stunden mit den Makefiles zugebracht aber immerhin, es geht.
In Deinem Beispiel hast Du eine Kurve mit einem zugehörigen Datensatz von jeweils 500 Punkte. Diese Punkte bekommt die Kurve über die QwtData Schnittstelle. Da leitest Du einfach Deine eigene QwtData Klasse (nur Schnittstelle, keine Datenhaltung) ab und berechnest dort die 500 Werte aus den tatsächlichen Daten.stimpy hat geschrieben: Unverzichtbar wäre allerdings der obe beschriebene Modus der Minimum und Maximum des verdichteten Segments darstellt, damit ich nicht die Daten gefiltert anzeige. Geht das mit QWT?
Einfach Autoscaling abschalten,stimpy hat geschrieben: Außerdem ist mir aufgefalen, daß während der Darstellung die Skalierung angepaßt wird - das sieht u.U. seltsam aus und kostet evtl. auch Zeit.
Uwe
QWT Installation
Hab's heute nochmal installiert und den Fehler gefunden.Da machst Du vermutlich etwas verkehrt bzw. Deine qmake Umgebung paßt nicht. Qwt/MSVC ist eine der häufig verwendeten Kombinationen.
Ich muß VCVARS32.BAT ausführen, damit die Pfade stimmen.
Dann klappt die Installation von QWT.
Falls jemand mal danach sucht...
Ergebnisse
Hallo,
ich habe nochmal QWT getestet. Dazu habe ich das data_plot Beispiel ein wenig modifiziert. Unter Windows war das Ergebnis wirklich gut (über 50 Bilder/s braucht eh' keiner). Nur war die Systemlast dann auch schon bei 50%. Wenn man z.B. Fenster bewegt, ruckelt es.
Unter OS X war das Ergebnis unbrauchbar (733 MHz, bei Vollbild ca. 3 Bilder/s). Die "Echtzeitanzeige" soll ohne viel Last auf jedem Rechner laufen.
Jetzt werde ich mal sehen, wie man SDL in ein QT-Widget implantiert bzw. wie ich OpenGL zum Linienziehen mißbrauche. Für sachdienliche Hinweise wäre ich da sehr dankbar!
ich habe nochmal QWT getestet. Dazu habe ich das data_plot Beispiel ein wenig modifiziert. Unter Windows war das Ergebnis wirklich gut (über 50 Bilder/s braucht eh' keiner). Nur war die Systemlast dann auch schon bei 50%. Wenn man z.B. Fenster bewegt, ruckelt es.
Unter OS X war das Ergebnis unbrauchbar (733 MHz, bei Vollbild ca. 3 Bilder/s). Die "Echtzeitanzeige" soll ohne viel Last auf jedem Rechner laufen.
Jetzt werde ich mal sehen, wie man SDL in ein QT-Widget implantiert bzw. wie ich OpenGL zum Linienziehen mißbrauche. Für sachdienliche Hinweise wäre ich da sehr dankbar!
Wenn Du Dir die Berichte über die Performance von Qt4 auf den Mailinglisten anschaust, gilt wohl:
X11: Ok, fast so schnell wie Qt3
Windows: Langsam
Mac: Zu langsam
Das deckt sich mit dem, was Du schreibst.
Wenn die Mac Plattform für Dich wichtig ist, ist Qt4 für Deine Anwendung vermutlich keine geeignete Plattform und Du wirst um OpenGL kaum herum kommen.
Uwe
X11: Ok, fast so schnell wie Qt3
Windows: Langsam
Mac: Zu langsam
Das deckt sich mit dem, was Du schreibst.
Wenn die Mac Plattform für Dich wichtig ist, ist Qt4 für Deine Anwendung vermutlich keine geeignete Plattform und Du wirst um OpenGL kaum herum kommen.
Uwe