16 Display-Listen und Vertex Arrays
16.010 Warum beanspruchen Display Listen soviel Speicher ?
Die OpenGL Display List erstellt eine Kopie aller Daten, die hierdurch dargestellt
werden sollen (Koordinaten, Befehle, Verwaltung, eventuell auch Texturangaben.).
Ein glVertex3f() beansprucht bereits 3 Punkte mit jeweils 32-Bit (float), also
insgesamt 12 Bytes plus zusätzlicher Bytes für den Befehl an sich.
Obwohl hierdurch bereits sehr viel Speicherplatz belegt wird, kann die Verwaltung
der Display List bei den meisten OpenGL Implementationen sogar noch einen erheblichen
zusätzlichen Speicher belegen. Der Vorteil einer Display List besteht zwar in
einer möglichen Optimierung der enthaltenen Daten (Aufbereitung, Berechnung etc.),
allerdings zu Lasten des vom Programm benötigten Speichers.
16.020 Wie kann ich eine Display List in verschiedenen Contexts gemeinsam nutzen ?
Unter Microsoft Windows gibt es den Befehl wglShareLists(). Für Unix und GLX kann der
Parameter share beim Befehl glXCreateContext() genutzt werden (ältere Versionen
von MESA haben die GLX nur emuliert, hier kenne ich den Sachstand nicht genau).
GLUT erlaubt dagegen kein Display List Sharing (also die gemeinsame Nutzung).
Allerdings wäre es denkbar, die Funktionen glutCreateWindow() und glutSetWindow()
im Quelltext von GLUT entsprechend zu überarbeiten und eine eigene Version von GLUT zu erstellen.
Hierbei sollte man sicherstellen, dass die übrigen Funktionen von GLUT weiterhin
funktionieren. Die Verbreitung seines Programms schränkt man so natürlich ein,
wenn auf anderen Systemen nicht die angepasste Version von GLUT installiert ist.
16.030 Wie kann man Display Listen ineinander verschachteln ? Wird die
aufgerufene Liste in die aktuelle Liste kopiert ?
Nein. In die aufrufende Liste wird nur ein Verweis auf die enthaltene Display List
eingefügt. Damit ist es möglich, die enthaltene Liste zu löschen bzw.
zu ändern und beim Aufruf der umschliessenden Liste die Änderung sofort
zu sehen.
16.040 Wie kann ich eine bestimmte Funktion aufrufen, während eine
Display Liste abgearbeitet wird ?
Der Aufruf einer Display List entspricht einem einzigen Befehl, so dass während
dessen Ausführung kein zweites Kommando abgearbeitet werden kann.
Damit ist es weder möglich, nur einen Teil der Display List auszuführen, dann
anderen Befehl und dann den Rest der Liste, noch geht es, aus der Display List heraus
dem Programm die genaue Stelle der Abarbeitung zu signalisieren.
Um eine grössere Flexibilität zu erreichen, teilt man besser eine
umfangreichere Liste in mehrere kleine Listen, so dass man hier problemlos Zwischenbefehle
ausführen oder Änderungen vornehmen kann.
Es ist aber auch möglich, mit Multithreading zu arbeiten, also das Programm
in mehreren Tasks (voneinander weitgehend unabhängige Programmteile) auszuführen.
Ein Task wäre z.B. mit einer Display List beschäftigt, während ein
zweiter Task andere Befehle (Laden von Texturen etc.) ausführt.
16.050 Wie kann ich einen einzelnen Funktionsaufruf in einer Display Liste
ändern, die wesentlich mehr Befehle enthält ?
Eine OpenGL Display List ist eine Black Box, kann also nachträglich weder
bearbeitet werden noch kann man nach der Erzeugung herausfinden, welche Einzelbefehle
enthalten sind oder gerade ausgeführt werden.
Man kann aber eine Art Pseudo-Liste erstellen, die ausschliesslich weitere Display-Listen
mittels glCallList()) aufruft. Eine Bearbeitung der "grossen Liste" ist dann
möglich, indem die enthaltenen Listen geändert oder gelöscht werden.
16.060 Wie kann ich eine Liste der enthaltenen Befehle und Parameter aus einer
Display Liste ermitteln ?
Derzeit gibt es keine Möglichkeit, mit OpenGL Befehlen die Funktionsaufrufe
oder Parameter innerhalb einer Display List direkt zu ermitteln. Braucht man diese
Informationen unbedingt, muss das Programm selbst die an die Display List übergebenen
Daten und Befehle kontrollieren bzw. aufzeichnen.
Eine Lösungshilfe stellen OpenGL Kontrollprogramme
dar, die alle aufgerufenen OpenGL Befehle vor deren Ausführung erfassen und
protokollieren. Hierzu wird meist die originale OpenGL Bibliothek durch eine spezielle
Version ersetzt, die entsprechende Meldungen verarbeitet und weitergibt.
16.070 Ich habe mein Programm so abgeändert, dass es jetzt Display Listen nutzt.
Aber es läuft in keinster Weise schneller. Warum nicht ?
Der Geschwindigkeitsvorteil einer Display List hängt stark von der jeweils
verwendeten OpenGL Implementation ab. Um die maximale Performance zu erhalten, kann man
allerdings ein paar generelle Tips berücksichtigen:
Auf jeden Fall sollte man den zusätzlichen Speicherbedarf berücksichtigen.
Wird mehr Speicher benötigt als physikalisch zur Verfügung steht, kann
man grundsätzlich von einem Performanceverlust ausgehen, so dass hier auf Display-Listen
verzichtet werden sollte.
Display-Listen werden die Performance einer "fill-limited" Anwendung
(d.h. die Grafikkarte und nicht die Berechnung ist der bremsende Faktor)
nicht verbessern können. Um herauszubekommen ob die Grafikkarte den Engpass
darstellt, muss man nur die Geschwindigkeit des Programms in Fenstern verschiedener
Grösse vergleichen. Steigen die Frameraten mit kleinerer Fenstergrösse,
kommt die Grafikkarte mit der Darstellung der berechneten Punkte nicht hinterher.
Man sollte auch darauf verzichten, Display-Listen mit dem Parameter GL_COMPILE_AND_EXECUTE
zu erzeugen. Besser ist GL_COMPILE und ein separater Aufruf von glCallList().
In manchen Fällen bringt es auch einen Vorteil, wenn man verschiedene
Statusänderungen der OpenGL zusammenfasst (Licht, Blending etc. aktivieren/deaktivieren).
Da die Display-List nur einmal berechnet werden muss, kann hierbei vielleicht auch eine
Optimierung (Status, Matrizen) durchgeführt werden.
Weitere Tipps gibt es auf der Performance Seite.
16.080 Um Speicherplatz zu sparen, macht es Sinn meine Koordinaten zunächst
in short integer umzuwandeln, bevor ich diese in einer Display List speichere ?
In der Regel nicht, da die meisten OpenGL Implementationen intern mit einem festen
Format (32-Bit float) rechnen und alle Daten entsprechend umgewandelt werden.
16.090 Wenn ich die Texturen in einer Display List speichere, wird mein Programm dadurch schneller ?
Einige OpenGL Implementationen sind in der Lage, innerhalb von Display-Listen
den Umgang mit Texturen zu optimieren (Laden in und Verwaltung des Texturspeichers).
Für OpenGL 1.0 gilt immer noch, dass Display-Listen die beste Optimierungsmethode
bei Texturen darstellt.Der damit verbundene hohe Speicherbedarf führte dazu,
eine andere Methode zu entwickeln, nämlich
Texture Objects ab OpenGL 1.1. Auf diese sollte
auch immer die Wahl fallen, wenn OpenGL 1.1 auf dem System installiert ist.
16.100 Wenn ich Vertex Arrays in einer Display List speichere, wird mein
Programm dadurch schneller ?
Das hängt von der genutzten Implementation ab. Meist kann man aber davon ausgehen,
dass der höhere Speicherbedarf des Programms die Performance nachteilig beeinflusst.
Es gibt allerdings auch (teure) Systeme, die Display-Listen auf der Grafikhardware
speichern oder verwalten können, so dass hier immer ein Geschwindigkeitsvorteil
zu erwarten ist.
16.110 Wenn ich eine Display List in verschiedenen Contexts nutze, was passiert wenn
ich diese Liste lösche ? Muss ich sie in allen anderen Contexts auch löschen,
damit der Speicher endgültig freigegeben wird ?
Wird eine Display-List in einem Context geändert (bzw. gelöscht),
so stehen diese Änderungen sofort auch in allen anderen Contexts zur Verfügung.
Das Löschen einer Liste führt also zum Entfernen aus dem Speicher, unabhängig
vom aktivierten Context.
16.120 Wie viele Display Listen kann ich anlegen ?
Durch die OpenGL Spezifikation ist kein Limit festgelegt. Allerdings wird die
ID der jeweiligen Liste durch einen 32-Bit Integer dargestellt, damit sind maximal
232 verschiedene Listen denkbar. Vorher dürfte aber eher der
Speicher ausgehen ;-)
16.130 Wieviel Speicher beansprucht eine Display List ?
Siehe Frage 16.010. Grundsätzlich hängt die Antwort
aber von der Implementation ab.
16.140 Woher weiss ich, dass der von einer Display List genutzte Speicher
auch wieder freigegeben wurde ?
Auch diese Antwort hängt von der Implementation ab. Einige geben den Speicher
sofort nach dem Löschen der Liste frei, andere erst dann, wenn der Speicher wieder
benötigt bzw. das Programm beendet wird.
16.150 Wie kann ich Vertex Arrays so anlegen, dass sie einzelne Vertices gemeinsam nutzen ?
Der Umstand, dass Vertex Arrays die enthaltenen Daten über einen Index aufrufen
führt zu der Vermutung, dass sich so mehrfach vorhandene Vertices optimal
zusammenfassen und über einen gemeinsamen Index aufrufen lassen.
Allerdings wird diese Idee spätestens dann kaum zu realisieren sein, wenn
je nach Verwendung des Vertex (z.B. als Eckpunkt eines Würfels) jeweils
verschiedene Normalenvektoren benötigt werden. Es ist also in der Regel erforderlich,
auch in Vertex Arrays bestimmte Vertices mehrfach anzugeben.
Vertex Arrays wurden auch nicht eingeführt, um die Mehrfachdefinition von
einzelnen Vertices zu vermeiden. Vielmehr soll es damit möglich sein, grössere
Datenblöcke mit nur wenigen Befehlen an die OpenGL zu übergeben.
Es ist aber möglich, gemeinsam in verschiedenen Polygonen genutzte Vertices
nur einmal anzugeben. Das geht wie auch im normalen Verfahren mittels bestimmter
Primitive (GL_LINE_STRIP, GL_LINE_LOOP, GL_TRIANGLE_STRIP, GL_QUAD_STRIP).
Wie die tatsächliche Verwaltung der Daten eines Vertex Arrays erfolgt, ist aber weitgehend
der Implementation überlassen, das Ergebnis muss nur den Forderungen der
OpenGL Spezifikation entsprechen. Eine vielfach genutzte Möglichkeit
bietet die Extension EXT_compiled_vertex_array, die eine explizite Optimierung der
angegebenen Daten vor deren Darstellung erlaubt.
|