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

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.

Seite durchsuchen nach:

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