Technikpfad

Aus DGL Wiki
Wechseln zu: Navigation, Suche

Einleitung

Willkommen auf dem Technikpfad! Wenn Sie wissen wollen, wie OpenGL funktioniert und wie die Räder ineinandergreifen sind Sie hier genau richtig.

Der Trampelpfad

Fangen wir ganz grob an. Was ist OpenGL? - OpenGL ist eine API welche die Schnittstelle zur Grafikhardware darstellt. Weiterhin ist OpenGL als Statemachine konzipiert. D.h. die GL kann verschiedene Zustände (engl. State) einnehmen und ihr aktueller Status beeinflusst ihre Ausgabe. Auch wenn dies jetzt sehr wage und vielleicht auch seltsam klingt, ist dies nichts besonders Kompliziertes. Ein Beispiel: Die aktuelle Farbe kann mit glColor gesetzt werden. Ändert man die Farbe, ändert sich der "Farbzustand" der GL und bleibt solange aktuell, bis eine neue Farbe zugewiesen wurde. OpenGL wechselt also niemals von alleine in irgend einen Zustand zurück. Die Farbe ist nur ein, sehr einfacher Zustand. OpenGL verfügt noch über viel mehr Zustände z.B. ob Texturen verwendet werden sollen, oder ob die Beleuchtung aktiviert ist. Viele der Zustände von OpenGL kann man mit glEnable und glDisable aktivieren bzw. deaktivieren. Soviel zur API. Doch wie funktioniert OpenGL?


Betrachten wir zuerst die Puffer. OpenGL verfügt über verschiedene Puffer. Der wichtigste ist ganz klar der Framebuffer der die auszugebenden Bildinformationen enthält und meist mittles Doppelpufferung betrieben wird. Die Aufgabe des Framebuffers ist die Daten die auf dem Bildschirm ausgegeben werden sollen zwischen zu speichern und dann mit einem mal auszugeben (flushen). Dem Framebuffer zur Seite stehen

  • der Tiefenpuffer der bei der Bildentstehung wichtig ist (Er enthält die Entfernung zum Betrachter. Damit kann man sicherstellen, dass Objekte sich gegenseitig korrekt verdecken.),
  • der Stencilbuffer, mit dessen Hilfe man Teile der Ausgabe vor Zugriffen schützen kann,
  • der Farbpuffer (eigentlich die Farbpuffer da im RGBA Modus für jede Farbe ein Puffer vorhanden ist.) und
  • Spezialpuffer wie der Feedbackpuffer oder der Selektionpuffer.

Die meisten Puffer kann man sich als 2 dimensionales Feld vorstellen, welche genau die Ausmaße der Zeichenfläche haben. Jeder Eintrag in einem Puffer gehört dann zu dem Pixel welches die selben Koordinaten auf dem Renderkontext hat. Sie alle dienem dem Zwischenspeichern von Werten die dann bei Bedarf abgefragt werden können.

Die Puffer werden entweder über die feste Funktionspipeline (Renderingpipeline) oder mittels Shader befüllt. (Zu den Shadern wird es an dieser Stelle nur wenige Informationen geben. Wer mehr wissen will sollte sich den Beleuchtungspfad ansehen.)

Seit einigen Jahren verfügen Grafikkarten über programmierbare Renderingpipelines. Damit kann man bei der Verarbeitung der Vertexinformationen vom vorgegebenen festen Weg abweichen und erhält mitunter sehr interessante Ergebnisse. Shader sind noch recht neu und es ist noch nicht abzusehen, was man (die entsprechende Hardware vorrausgesetzt) noch alles mit ihnen machen kann. Bislang werden Shader vorallem zur Bearbeitug von Materialien/Oberflächen eingesetzt. Z.B. um Bumpmapping zu realisieren.

Der festen Funkktionspipeline sollte etwas mehr Zeit gewidmet werden. (Wer den entsprechenden Artikel bereits gelesen hat, wird hier sein Wissen nocheinmal nachprüfen können.)

Die Renderingpipeline besteht aus zwei Teilen (und kann deshalb auch durch 2 Shadertypen, Pixel- und Fragmentshader, ersetzt werden).

Der erste Teil, die sogenannte Vertex-Pipeline hat ihren Namen von den Ausgangsinformationen. Sie erhält die Vertexinformationen und generiert daraus Fragmente. Dabei müssen verschiedene Stationen durchlaufen werden. Diese wären:

  1. Multiplikation mit der Modelviewmatrix um Augenkoordinaten zu erhalten.
  2. Erstellen der Primitive und einfärben dieser. (Flat-Shading Dabei tesselieren (genauer: triangulieren) aller Polygone die nicht in Dreiecksform vorliegen.
  3. Clipping an benutzerdefinierten Clipping Planes.
  4. Multiplikation mit der aktuellen Projektionsmatrix (siehe Matrix) um die aktuelle Kamerasicht zu erhalten.
  5. Clipping bezüglich der Kamera.
  6. Projektionsberechnung (Division durch w) um die eigentliche Ausgabe zu erhalten.
  7. Multiplikation mit der Viewport Matrix. (Damit erhält man den Teil der Ausgabe, der tatsächlich sichtbar sein soll. Das "Sichtfenster".)
  8. Anpassen der Tiefenwerte.
  9. Culling von nicht benötigten Polygonen.
  10. Anpassen an den Polygonmode.
  11. Rasterisierung um Fragmente zu erhalten.

Mit den nun im Framebuffer liegenden Fragmenten werden weitere Operationen durchgeführt. Diese sind Bestandteil der sogenannten "Fragment Pipeline". Folgende Operationen werden/können durchgeführt werden:

  1. Texelberechnung und Anwenden der Texel.
  2. Nebelberechung (siehe glFog)
  3. Antialiasing
  4. Scissor Test
  5. Alpha Test
  6. Stencil Test
  7. Tiefentest
  8. Blenden
  9. Dithering
  10. logische Operationen (siehe glLogicOp)
  11. Masking von Puffern. (Verhindern von Schreibzugriffen auf bestimmte Teile von einzelnen Puffern. siehe z.B. glColorMask, glDepthMask)


Anschließend stehen die Bildinformationen im Framebuffer zu Verfügung und müssen nur noch durch z.B. SwapBuffers auf den Bildschirm gebracht werden.

Soweit zum Hintergrund von OpenGL. Hier gehts zurück zu den Trampelpfaden.