23 Erweiterungen und Versionen der OpenGL
23.010 Wo kann ich Informationen über die verschiedenen OpenGL
Extensions bekommen ?
Es gibt einmal die
OpenGL extension registry
und Informationen auf der
OpenGL org web page.
Auflistungen der Erweiterungen von verschiedenenen Grafikkarten/OpenGL-Implementationen
gibt es hier und
hier.
23.020 Woher weiss ich, welche OpenGL Version mein Programm nutzt ?
Einmal wird die Versionsnummer im Header gl.h per "#define" festgehalten.
Damit kann man bestimmte Funktionen in Abhängigkeit der vorhandenen OpenGL Bibliothek
aktivieren:
#ifdef GL_VERSION_1_2
// OpenGL 1.2 Funktionen nutzen
#endif
Die Version lässt sich auch zur Laufzeit des Programms feststellen. Vorausgesetzt, man
hat einen aktuellen OpenGL Context erzeugt, liefert der Befehl glGetString(GL_VERSION)
die Major- und Minor-Nummer (vor bzw. nach dem Punkt) sowie optionale Angaben über Release und
Hersteller.
23.030 Wo liegen die Unterschiede zwischen den verschiedenen OpenGL-Versionen ?
OpenGL 1.1 definiert zusätzlich:
-
Vertex Arrays (um Funktionsaufrufe auch ohne Nutzung von Display-Listen zu minimieren),
-
Polygon Offset (damit sich Objekte annähernd gleicher Position nicht durchdringen),
-
Logische Operationen im RGBA-Modus,
-
interne Texturformate (Vorgabe der internen Struktur von Texturdaten),
-
Texture Proxies (Textur-Verwaltung durch die OpenGL),
-
Textur-Kopien und Sub-Texturen (um Texturen oder Teilbereiche davon aus dem Framebuffer
bzw. Hauptspeicher auszulesen),
-
Texture Objects (Texturen und zugehörende Parameter werden als ein Objekt gespeichert).
OpenGL 1.2 definiert zusätzlich:
-
3D-Texturen mit Hardware-Unterstützung (Volume Rendering, z.B. Hineinsehen in einen Körper),
-
BGRA und gepackte Pixelformate (für spezielle Datei- und Framebufferformate),
-
automatisches Neu-Skalieren der Normalenvektoren (manchmal schneller als Normierung),
-
Specular Highlights nach dem Texturieren,
-
Texturkoordinaten "Edge Clamping" (Bindung an Vertexkoordinaten) zum Auffangen
von Rundungsfehlern,
-
LOD Kontrolle (Level of Detail) für Texturen. Vermeidet dass Laden von hochauflösenden MipMap Stufen,
falls diese nicht benötigt werden.
-
Vertex Array Erweiterungen (Zugriff auf Teilbereiche möglich, insgesamt effektivere
Optimierung),
-
ARB-genehmigte Extensions (Hersteller Extensions wie z.B. SGI_ext werden durch einheitliche
Standards der Form ARB_ext ersetzt). Verfügbarkeit muss vorher
abgefragt werden.
Mit OpenGL 1.2.1 wurde die GL_ARB_multitexture Extension eingeführt, um mehrere Texturen auf
ein Objekt zu bringen. Tipps zur Feststellung der unterstützten Extensions findet ihr
hier.
OpenGL definiert zusätzlich diese Funktionen:
-
Neue Texture Mapping Funktionen: Kompression und Cube Mapping, weitere Textur-Eigenschaften wie
Add, Combine, Dot3, Texture Border Clamp und Multitexture,
- Multisampling und
- Matrix transpose.
3Dlabs hat einen Entwurf für OpenGL 1.2 (2.2MB)
zur Diskussion gestellt, dass wesentliche Änderungen zu OpenGL 1.x enthält, u.a.
die Erweiterung um Memory Management und Zeitsteuerung.
23.040 Wie kann ich für verschiedene OpenGL Versionen gleichzeitig programmieren ?
Da die neuesten Funktionen oder Extensions zwar auf dem zur Entwicklung genutzten Rechner,
nicht aber unbedingt auf dem Rechner des späteren Anwenders vorhanden sein können,
sollte die Nutzung spezieller Möglichkeiten der eigenen OpenGL Implementation immer
gut überlegt sein.
Um sicherzugehen, dass ein Programm auf jeder OpenGL Plattform läuft, sollte man die
OpenGL-Version und die verfügbaren Extensions abfragen und danach geeignete Verzweigungen
im Programm einbauen:
#include <stdlib.h>
...
int gl12Supported;
gl12Supported = atof(glGetString(GL_VERSION)) >= 1.2;
...
if (gl12Supported) {
// OpenGL 1.2 vorhanden, neue Funktionen können genutzt werden
}
23.050 Wie finde ich heraus, welche OpenGL Extensions unterstützt werden ?
glGetString(GL_EXTENSIONS) gibt einen String zurück, der alle Extensions
(durch Leerzeichen getrennt) enthält.
Man kann sich auch GLView
herunterladen, um die unterstützen Extensions festzustellen.
23.060 Wie kann ich mein Programm aufbauen, so dass es auch auf Systemen funktioniert,
auf denen die genutzten Extensions nicht vorhanden sind ?
Während der Laufzeit des Programms ist es möglich, mittels glGetString(GL_EXTENSIONS)
die Verfügbarkeit einer bestimmten Extension abzufragen. Der genannte Befehl gibt eine
Liste aller Erweiterungen zurück, die sich entsprechend auswerten lässt:
#include <string.h>
const GLubyte *str;
int glPolyOffExtAvailable;
str = glGetString (GL_EXTENSIONS);
/* ist PolygonOffset verfuegbar ? */
glPolyOffExtAvailable = (strstr((const char *)str, "GL_EXT_polygon_offset") != NULL);
Ist die benötigte Extension verfügbar, kann sie auch genutzt werden. Allerdings sollte
im anderen Fall auch eine Ausweichlösung programmiert werden. Das gleiche trifft auch zu, wenn
man das Programm auf verschiedenen Plattformen entwickelt. Mit Hilfe des Präprozessors könnte
das etwa so aussehen:
#ifdef GL_EXT_polygon_offset
glEnable (GL_POLYGON_OFFSET_EXT);
glPolygonOffsetEXT (1., 1./(float)0x10000);
#endif /* GL_EXT_polygon_offset */
23.070 Wie kann ich Extensions unter MS Windows nutzen ?
Einige Extensions sind bereits durch die OpenGL32.lib definiert. Zusätzlich kann
die Treiberbibliothek der Grafikkarte weitere Extensions definieren. Diese lassen sich allerdings erst
über die während der Laufzeit ermittelten Adressen aufrufen. Ein Beispiel für
die ARB_multitexture kann so aussehen:
/* Header der Extension muss mit include eingefuegt werden (Hardware-speziell oder GL/glExt.h) */
#include "GL/glExt.h"
/* Zeiger auf Funktionsadressen */
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB;
/* Adressen ermitteln */
glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB");
glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress("glMultiTexCoord2fARB");
Nachdem die Funktionszeiger mit den Adressen initialisiert sind, können sie
ganz normal genutzt werden.
/* Texture 0 Min/Mag Filter setzen */
(*glActiveTextureARB) (GL_TEXTURE0_ARB);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
...
/* Multi-Texturiertes Viereck zeichnen */
glBegin (GL_QUADS);
(*glMultiTexCoord2fARB) (GL_TEXTURE0_ARB, 0.f, 0.f);
(*glMultiTexCoord2fARB) (GL_TEXTURE1_ARB, 0.f, 0.f);
glVertex3f (32.f,32.f, 0.f);
...
glEnd();
Weitere Informationen über wglGetProcAddress() enthält die MSDN-Dokumentation.
Da einige Programmierer Bauchschmerzen bei dem gezeigten Umgang mit den Funktionszeigern haben
werden, gibt es auch eine
überarbeitete Version der glext.h,
welche die gezeigte Lösung innerhalb von C-Präprozessor-Aufrufen versteckt.
23.080 Wie kann ich Extensions unter Linux nutzen ?
Vergleich mit Microsoft Windows (und damit im Gegensatz zu den meisten UNIX Systemen)
kann eine Extension in der OpenGL Bibliothek des Systems definiert sein. Während der
Laufzeit wird dann die entsprechende Funktionsadresse geladen.
Linux nutzt die OpenGL ABI.
23.090 Wo kann ich die Konstanten und Funktionsprototypen der Extensions herausbekommen ?
Hierfür gibt es die
OpenGL Extension Registry bzw. für die einzelnen Systeme:
glext.h ist kein Ersatz für gl.h, sondern eine Art Teilmenge. Sie definiert Zugriffsmethoden für
Extensions, die nicht durch die plattformspezifische gl.h beschrieben werden.
Das ist notwendig, da die plattformspezifische gl.h nichts über die jeweilige Grafikkarte und den
Funktionsumfang des Treibers wissen kann.
|