Seite 1 von 1

[gelöst] Lösung, um Text in Low-Level-Klasse zu rendern

Verfasst: 19. April 2010 14:02
von deedw
Hallo,

ich habe eine kleine Designfrage zur Benutzung von Qt bzw. eines QGLWidgets. Ich schreibe gerade einen kleinen OpenGL-Viewer (abgeleitet von QGLWidget) mit folgendem Design (abstrahiert):

Code: Alles auswählen

viewer----+
               |
     +---scene-----+
     |                    |
geometry      rendering object
Die Szene nimmt die Informationen aus der Geometrie (irgendwelche Punkte z.B.) und speichert sie in den Rendering-Objekten. Später wird der Viewer über

Code: Alles auswählen

makeCurrent()
aktiviert und rendert alle rendering objects über einen Aufruf der Methode

Code: Alles auswählen

render()
In der werden dann die zugehörigen OpenGL-Befehle abgesetzt (Punkte oder Linien zeichnen).

Mein Problem ist, dass ich nun Text im Viewer anzeigen will, z.B. zu jedem Punkt den Abstand zum Ursprung (0,0,0). Derzeit nutze ich gluProject und QGLWidget::renderText dafür, brauche deshalb aber auch den Viewer im Rendering-Objekt.

Da das kein gutes Design ist, suche ich eine bessere Lösung. Meine Frage ist, wie Ihr das angehen würdet?

Meine zwei Ideen sind:

1. Nur eine Referenz auf das QGLWidget und nicht den ganzen Viewer an die Rendering-Klasse geben. Pro: Leicht zu implementieren. Kontra: Die Low-Level-Klasse hat immer noch Zugriff auf GUI-Funktionen aus QWidget.

2. Ich erstelle im Viewer einen Container für Punkte und Strings. Dieser wird an die Rendering-Objekte gegeben und dort befüllt. Der Viewer rendert danach einfach nur noch den Inhalt des Containers. Pro: Gutes Design (denke ich). Kontra: Umständlich umzusetzen (das Design ist in echt etwas komplizierter als da oben zu sehen ist). Daneben weiß ich nicht, wie es mit der Laufzeit aussieht und ggf. halte ich Informationen auch doppelt im Speicher (zumindest als Pointer).

Freue mich über Antworten und Ideen.

Viele Grüße
Dee

Verfasst: 19. April 2010 14:07
von Troll.Soft
und wie ist es, wenn Du im Renderer ein Signal sendest mit allen Infos, das Du per Slot im Viewer auffängst? Alles sauber getrennt und die Übergabe einfach per Referenz.
tschüß
Troll.Soft

Verfasst: 19. April 2010 14:22
von deedw
Danke für die schnelle Antwort. Ich hatte ganz am Anfang (so vor 1 1/2 Jahren ca.) mal Experimente mit Q_OBJECT gemacht und dabei ist mir aufgefallen, dass so eine Abhängigkeit die Objekte (im Speicher) aufblähen. Deswegen bin ich damals zumindest bei den Low-Level-Klassen, von denen ich Tausende Objekte haben werde, weg vom Signal-Slot-Prinzip. Kannst Du das bestätigen oder widersprechen?

Daneben stellt sich mir auch die Frage, wie es dann mit der Performance aussieht. Nehmen wir an, ich habe 1000 Objekte in einer Szene (Kreise, Linien, Polynome etc.). Dann würden beim Rendern (also bei jeder Drehung), 1000 Signale relativ gleichzeitig an den Viewer gesandt werden. Hast Du da Informationen zu, ob ein Objekt das verträgt?

Ansonsten ist das aber auch eine gute Idee; ich hätte dann sozusagen nur den Aufwand, das Signal ganz unten mit einem Slot ganz oben zu verbinden.

Viele Grüße
Dee

PS: Ich nutze noch Qt 3.3.8 (Windows) bzw. Qt 3.3.2 (Solaris), falls das eine Rolle spielen sollte. Ein Upgrade auf Qt 4.5 ist aber in Planung.

Verfasst: 19. April 2010 18:14
von Troll.Soft
deedw hat geschrieben:Danke für die schnelle Antwort. Ich hatte ganz am Anfang (so vor 1 1/2 Jahren ca.) mal Experimente mit Q_OBJECT gemacht und dabei ist mir aufgefallen, dass so eine Abhängigkeit die Objekte (im Speicher) aufblähen. Deswegen bin ich damals zumindest bei den Low-Level-Klassen, von denen ich Tausende Objekte haben werde, weg vom Signal-Slot-Prinzip. Kannst Du das bestätigen oder widersprechen?
bestätigen :) aber 1000 Objekte mal tausend Byte sind auf meinem Rechner man gerade mal ein mickriges MegaByte. Ich lege ebenfalls fleißig Objekte an im vierstelligen Bereich. Kein Probleme was den Speicher anbelangt. Sehr bequem, das Qt sich immer selbst ums Löschen kümmert.
Daneben stellt sich mir auch die Frage, wie es dann mit der Performance aussieht. Nehmen wir an, ich habe 1000 Objekte in einer Szene (Kreise, Linien, Polynome etc.). Dann würden beim Rendern (also bei jeder Drehung), 1000 Signale relativ gleichzeitig an den Viewer gesandt werden. Hast Du da Informationen zu, ob ein Objekt das verträgt?
da dürfte nichts abstürzen. Das Signal Slot System ist sicher. Das einzige was abstürzen kann, ist die Performance. SignalSlot ist nicht das Schnellste. Sagt zumindest Qt selbst. Achte darauf, beim Übergeben der Daten nur Referenzen zu übergeben.
Ansonsten ist das aber auch eine gute Idee; ich hätte dann sozusagen nur den Aufwand, das Signal ganz unten mit einem Slot ganz oben zu verbinden.
Das dürfte wohl der geringste Aufwand sein :)
PS: Ich nutze noch Qt 3.3.8 (Windows) bzw. Qt 3.3.2 (Solaris), falls das eine Rolle spielen sollte. Ein Upgrade auf Qt 4.5 ist aber in Planung.
Qt 4.5 ist nun nicht gerade das Neueste. Die Quties behaupten: Qt 4.* sei schneller als 3.*

tschüß
Troll.Soft

Verfasst: 21. April 2010 07:51
von deedw
Ich habe mal den Test gemacht und die aktuelle Lösung auf Signal-Slot-Prinzip umgestellt. Sowohl die Speicherauslastung als auch die Geschwindigkeit ist relativ gleich geblieben. Sowas lässt sich natürlich nur vage messen. Ich denke aber, dass das eine gute Lösung ist.

Danke vielmals
Dee

Verfasst: 21. April 2010 09:12
von solarix
1000 Signale relativ gleichzeitig an den Viewer gesandt werden. Hast Du da Informationen zu, ob ein Objekt das verträgt?
http://doc.trolltech.com/4.6/signalsandslots.html hat geschrieben:On an i586-500, you can emit around 2,000,000 signals per second connected to one receiver, or around 1,200,000 per second connected to two receivers.

Verfasst: 14. September 2010 06:43
von deedw
Auch wenn das Thema schon älter ist, die Lösung sah am Ende ganz anders aus:

1. Die Renderobjekte erhalten mit dem render-Aufruf eine Referenz auf ein ViewerInterface. Dieses enthält eine Methode drawText, die die Objekte rufen können.

2. Der Viewer (konkret OGLViewer) leitet von ViewerInterface und QGLWidget ab und implementiert die drawText-Methode, so wie es QGLWidget braucht.

3. Jemand, der OGLViewer und Renderobjekte kennt (der Viewer sollte diese nicht enthalten), iteriert über alle Renderobjekte und ruft die render-Methode mit dem konkreten OGLViewer als Argument auf.

Auf die Art habe ich eine klare Trennung zwischen den Renderobjekten und der eigentlichen Implementierung des Viewers und komme sogar ohne Signale aus. Zusätzlich lässt sich der OGLViewer sehr leicht (z.B. gegen ein D3DViewer) austauschen, da sich das Interface nicht ändert.

Gruß Dee