OpenGL.org 3Dsource.de: Infos rund um 3D-Computergrafik, OpenGL und VRML
space Telefon-Tarife space VDI - Arbeitskreis Fahrzeugtechnik space Beschallungsanlagen und Elektroakustik space Heise-News space

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.

Seite durchsuchen nach:

Fragen oder Ideen an:
Thomas.Kern@3Dsource.de
Linux-Counter
(C) Thomas Kern