OpenGL hat vier verschiedene Hauptversionen, wobei die Versionen für mobile Geräte und eingebettete Systeme (OpenGL | ES) und das Web über JavaScript (WebGL) nicht berücksichtigt werden. Genau wie Direct3D 11 eine andere Vorgehensweise als Direct3D 8 hat, hat OpenGL 3 eine andere Vorgehensweise als OpenGL 1. Der große Unterschied ist, dass OpenGL-Versionen meist nur Add-Ons zu den älteren Versionen sind (aber nicht völlig).
Zusätzlich zu den verschiedenen Editionen und Versionen von OpenGL hat das Haupt-OpenGL auch das Konzept von Profilen hinzugefügt. Nämlich das Kompatibilitätsprofil (das die Unterstützung für APIs älterer Versionen aktiviert) und das Kernprofil (das diese alten APIs deaktiviert). Dinge wie glBegin
funktionieren einfach nicht, wenn Sie das Core-Profil verwenden, sondern, wenn Sie das Kompatibilitätsprofil verwenden (das die Standardeinstellung ist).
Als eine weitere große Komplikation werden einige Implementierungen von OpenGL (wie unter anderem von Apple) neuere OpenGL-Funktionen nur dann aktivieren, wenn Sie das Core-Profil verwenden. Dies bedeutet , dass Sie müssen mit älteren APIs stoppen , um zu neueren APIs zu verwenden.
Sie haben dann einige sehr verwirrende Szenarien für Tutorials:
- Das Tutorial ist alt und verwendet nur veraltete APIs.
- Das Tutorial ist neu und gut geschrieben und verwendet nur Core-kompatible APIs.
- Das Lernprogramm ist neu, geht jedoch fälschlicherweise davon aus, dass Sie mit einem Treiber arbeiten, der alle APIs im Kompatibilitätsmodus aktiviert und neue und alte APIs frei mischt.
- Das Tutorial bezieht sich auf eine andere Version von OpenGL wie OpenGL | ES, die keine der alten APIs in irgendeiner Version unterstützt.
Dinge wie glBegin
sind Teil dessen, was manchmal als Sofortmodus-API bezeichnet wird. Dies ist auch sehr verwirrend, da es in OpenGL keinen beibehaltenen Modus gibt und der "unmittelbare Modus" in Grafiken bereits eine andere Definition hatte. Es ist viel besser, diese APIs nur als OpenGL 1.x-APIs zu bezeichnen, da sie seit OpenGL 2.1 veraltet sind.
Die 1.x-API von OpenGL übermittelte Scheitelpunkte sofort an die Grafik-Pipeline in früheren Zeiten. Dies funktionierte gut, wenn die Geschwindigkeit der Hardware, mit der Scheitelpunkte gerendert wurden, in etwa der Geschwindigkeit der CPU entsprach, die die Scheitelpunktdaten erzeugte. OpenGL hat damals nur die Dreiecksrasterung und nicht viel mehr ausgelagert.
Heutzutage kann die GPU eine große Anzahl von Scheitelpunkten mit sehr hoher Geschwindigkeit durchkauen und gleichzeitig eine erweiterte Scheitelpunkt- und Pixel-Transformation durchführen, und die CPU kann einfach nicht einmal aus der Ferne mithalten. Darüber hinaus wurde die Schnittstelle zwischen der CPU und der GPU auf diesen Geschwindigkeitsunterschied ausgelegt, sodass es nicht einmal mehr möglich ist, Scheitelpunkte einzeln an die GPU zu senden.
Alle GL-Treiber müssen emulieren, glBegin
indem sie intern einen Scheitelpunktpuffer zuweisen, die mit glVertex
in diesen Puffer gesendeten Scheitelpunkte einfügen und dann den gesamten Puffer in einem einzelnen Zeichenaufruf senden, wenn dieser glEnd
aufgerufen wird. Der Aufwand für diese Funktionen ist weitaus größer als wenn Sie den Vertex-Puffer selbst aktualisiert haben. Aus diesem Grund wird in einigen Dokumentationen (aus Versehen!) Der Vertex-Puffer als "Optimierung" bezeichnet (dies ist keine Optimierung; dies ist der einzige Weg, dies tatsächlich zu tun) mit der GPU sprechen).
Es gibt verschiedene andere APIs, die in OpenGL im Laufe der Jahre veraltet oder veraltet sind. Die sogenannte Festfunktionspipeline ist ein weiteres solches Stück. In einigen Dokumentationen wird diese Pipeline möglicherweise noch verwendet oder mit der programmierbaren Pipeline gemischt. Die Pipeline mit festen Funktionen stammt aus früheren Zeiten, als Grafikkarten die gesamte Mathematik fest codierten, die zum Rendern von 3D-Szenen verwendet wurde, und die OpenGL-API darauf beschränkt war, einige Konfigurationswerte für diese Mathematik festzulegen. Heutzutage hat die Hardware sehr wenig hartcodierte Mathematik und führt (genau wie Ihre CPU) stattdessen vom Benutzer bereitgestellte Programme (oft als Shader bezeichnet) aus.
Wieder müssen die Treiber die alte API emulieren, da die Funktionen mit festen Funktionen auf der Hardware einfach nicht mehr vorhanden sind. Dies bedeutet, dass in den Treiber eine Reihe von Kompatibilitätsshadern eingebettet sind, die die alte Mathematik aus den Tagen mit festen Funktionen ausführen, die verwendet wird, wenn Sie keine eigenen Shader bereitstellen. Die alten OpenGL-Funktionen, die diesen alten Status mit festen Funktionen ändern (wie die alte OpenGL-Beleuchtungs-API), verwenden derzeit moderne OpenGL-Funktionen wie einheitliche Puffer, um diese Werte den Kompatibilitätsshadern des Treibers zuzuführen.
Treiber, die Kompatibilität unterstützen, müssen viel hinter den Kulissen arbeiten, um herauszufinden, wann Sie diese veralteten Funktionen verwenden, und um sicherzustellen, dass Sie sie reibungslos mit modernen Funktionen kombinieren können, was den Aufwand erhöht und den Treiber erheblich verkompliziert. Dies ist einer der Gründe, warum Sie von einigen Treibern dazu gezwungen werden, das Core-Profil auf neuere Funktionen umzustellen. Dies vereinfacht die Einbindung der Treiber erheblich, da die alte und die neue API, die gleichzeitig verwendet werden, nicht unterstützt werden müssen.
In vielen Dokumentationen wird möglicherweise empfohlen, mit den alten APIs zu beginnen, da diese einfacher zu handhaben sind. Direct3D löste dieses Problem für Anfänger, indem es eine Begleitbibliothek ( DirectX Tool Kit ) anbot , die einfachere Zeichnungs-APIs und vorab geschriebene Shader bietet, die mit der Verwendung von Direct3D 11 frei gemischt werden können, wenn Ihr Fachwissen wächst. Die breitere OpenGL-Community hat sich leider größtenteils an das Kompatibilitätsprofil für Anfänger gehalten, was problematisch ist, da es wieder Systeme gibt, mit denen Sie alte OpenGL-APIs nicht mit den neueren mischen können. Es gibt inoffizielle Bibliotheken und Tools für ein einfacheres Rendern in der neuen OpenGL mit unterschiedlichen Funktionen und Anwendungsfällen und Sprachen ( MonoGame zum Beispiel für .NET-Benutzer), aber nichts, was offiziell gebilligt oder weitestgehend vereinbart wurde.
Die Dokumentation, die Sie finden, ist möglicherweise nicht für OpenGL, sondern für eine der anderen ähnlichen APIs. OpenGL | ES 1.x hatte ein Rendering mit festen Funktionen, verfügte jedoch nicht über die OpenGL 1.x-APIs für die Übermittlung von Scheitelpunkten. OpenGL | ES 2.x + und WebGL 1+ haben überhaupt keine Funktionen mit festen Funktionen, und für diese APIs gibt es keine Abwärtskompatibilitätsmodi.
Diese APIs sehen dem OpenGL-Hauptprogramm sehr ähnlich. Sie sind nicht ganz kompatibel, aber es gibt offizielle Erweiterungen für OpenGL, die einige (nicht alle) Treiber unterstützen, um mit OpenGL | ES (auf dem WebGL basiert) kompatibel zu werden. Weil die Dinge vorher nicht verwirrend genug waren.