OpenGL ES 2.0 Schnellstart

Autor: Zen und die Kunst der Computerprogrammierung

1. Einleitung

Opengl (Open Graphics Library) ist eine plattformübergreifende API zum Rendern zweidimensionaler Bilder, Videos und Grafiken der Benutzeroberfläche. In den letzten Jahren hat sich Opengl mit der weit verbreiteten Beliebtheit mobiler Geräte und dem Aufstieg des Internets der Dinge (Internet of Things) zur bevorzugten Lösung für die Entwicklung leistungsstarker, plattformübergreifender Grafikanwendungen entwickelt. Das Zeichnen hochwertiger Spielgrafiken auf Mobilgeräten war schon immer schwierig. Aus diesem Grund wurde Opengl ES (Embedded Systems) entwickelt, eine speziell für eingebettete Systeme entwickelte Opengl-API.

Als CTO mit langjähriger Programmiererfahrung bin ich zwar nicht sehr vertraut mit Computergrafik, lese aber sehr gerne Bücher, insbesondere technische Bücher in verwandten Bereichen, wie z. B. OpenGL Programming Guide (der offizielle Leitfaden zum Erlernen der OpenGL-Programmierung und zur Hochentwicklung). Dieses Buch bietet sehr detaillierte Grundkenntnisse und Tutorials, und der Autor hat viele Jahre Erfahrung gesammelt, um den Lesern durch kontinuierliches Lernen und Zusammenfassen zu helfen, Opengl besser zu verstehen.

Auf dieser Grundlage wird in diesem Artikel das Buch „OpenGL Programming Guide“ als Ausgangspunkt verwendet, versucht, den Prozess vom Grundwissen bis zur Realisierung eines leistungsstarken plattformübergreifenden Spiel-Rendering-Programms abzuschließen und die Verwendung von Opengl ES 2.0 für Spiele zu erläutern Rendering und Lead-Leser Beherrschen Sie Schritt für Schritt die Verwendungs- und Optimierungstechniken von Opengl und erreichen Sie letztendlich das Ziel, die Effizienz des Spiele-Renderings zu verbessern.

Schauen wir uns zunächst die Geschichte von OpenGL an:

Um Innovationen in der wissenschaftlichen Forschung und Anwendung zu fördern, lud Khronos 1992 Wilkinson, Carver, Kovac, Heitz und andere ein, an der Erfindung der OpenGL-API mitzuarbeiten. Es definiert eine Reihe von Spezifikationen, einschließlich standardisierter Schnittstellen in Grafikverarbeitungspipelines, Beleuchtungsmodellen, Texturzuordnung usw., und bietet eine plattformübergreifende zugrunde liegende Implementierung.

Nach mehreren Jahren der Entwicklung wurde 1994 Version 1.1 von OpenGL als erste Version veröffentlicht. Version 1.1 bietet einen kleinen Funktionsumfang und bietet hauptsächlich Unterstützung für Würfelobjekte, Texturabbildung, Beleuchtungsmodelle, geometrische Transformationen und Vertex-Array-Objekte.

1997 wurde Version 2.0 von OpenGL offiziell veröffentlicht. Version 2.0 erbt alle Funktionen von Version 1.1 und fügt Unterstützung für Vektor-, Matrix- und Shadersprachen hinzu. Gleichzeitig wurde eine virtuelle Maschine eingeführt und Entwicklern ermöglicht, Shader-Programme zur Laufzeit zu kompilieren und zu verknüpfen.

Im Jahr 2008 wurde OpenGL Version 3.0 veröffentlicht. Unter Beibehaltung aller Funktionen von OpenGL 2.0 fügte diese Version Unterstützung für heterogenes Computing (Heterogeneous Computing) sowie neue Funktionen wie 3D-Texturierung und Vertex Buffer Object hinzu.

Aus der Entwicklung im Laufe der Jahre können wir ersehen, dass OpenGL eine Phase rasanter Entwicklung durchlaufen hat und die aktuelle Version ebenfalls OpenGL 4.3 ist. Gleichzeitig wurde von ARM Opengl ES eingeführt, eine speziell für eingebettete Geräte entwickelte API mit einer längeren Geschichte von mehr als 20 Jahren. Seine Positionierung ist jedoch etwas Besonderes, da es nur einen kleinen Teil der OpenGL-Funktionen bereitstellt und viele Leistungsoptimierungen vornimmt.

Zusammenfassend bietet Opengl die Vorteile einer plattformübergreifenden und hohen Leistung, während Opengl ES in eingebetteten Systemen positioniert ist, was besonders für das Rendern von Spielen wichtig ist. Daher wird es zweifellos hilfreich sein zu verstehen, wie OpenGL ES 2.0 funktioniert und wie man es zum Rendern von Spielen verwendet.

2. Erläuterung grundlegender Konzepte und Begriffe

2.1 Abstrakte Struktur von Opengl

Opengl ist eine plattformübergreifende 3D-Grafik-Rendering-Bibliothek. Ihre Grundeinheit ist ein sogenanntes „Render Target“, das alle für das Rendering erforderlichen Ressourcen in GPU-Hardware kapselt. Ein Renderziel umfasst einen Speicherbereich, der Daten wie Farbwerte, Normalen, Positionen, Texturkoordinaten und Tiefenwerte speichert. Renderziele können untereinander oder zwischen verschiedenen Renderern gemeinsam genutzt werden. Wenn ein Renderer rendern muss, schreibt er die zum Rendern erforderlichen Daten in das Rendering-Ziel und benachrichtigt dann andere Renderer, die Daten zu lesen und zu rendern.

Opengl verfügt über ein Grundkonzept zum Rendern von Zuständen. Es bezieht sich auf die Erfassung verschiedener Daten während des Rendervorgangs. Einschließlich Ansichtsfenster (Ansichtsfenster), Projektionsmatrix (Projektionsmatrix), Modellansichtsmatrix (Modellansichtsmatrix), Farbe, Material, Lichtquelle, Textur usw. Der Rendering-Status kann über einige Funktionen festgelegt oder die Matrix oder das Array, auf die er zeigt, direkt geändert werden.

Ein weiteres wichtiges Konzept sind Puffer. Renderziele und Renderstatus werden durch Puffer verwaltet. Der Puffer ist ein Speicherbereich zum Speichern von Daten. Dabei kann es sich um Videospeicher, Festplattendateien, Programmvariablen usw. handeln. Der Zweck des Puffers besteht darin, Daten während des Rendervorgangs weiterzuleiten. In Opengl gibt es zwei Arten von Puffern, nämlich „Puffer mit fester Größe“ und „Puffer mit variabler Größe“. Feste Puffer behalten im Allgemeinen die gleiche Größe, während variable Puffergrößen je nach Bedarf dynamisch angepasst werden können.

Es gibt ein weiteres wichtiges Konzept namens „Vertex-Array-Objekt“. Es handelt sich um eine Datenstruktur, die vom Renderer zum Speichern von Scheitelpunktinformationen verwendet wird. Jedes Scheitelpunkt-Array-Objekt verfügt über ein eigenes Scheitelpunktformat, eine eigene Scheitelpunktnummer, einen eigenen Scheitelpunktdatenzeiger und andere Attribute. Wenn der Renderer ein Objekt rendern möchte, muss er nur dieses Vertex-Array-Objekt aufrufen.

Schließlich gibt es noch ein wichtiges Konzept namens „Shader“, bei dem es sich eigentlich um ein kleines CPU-Programm handelt, das auf der GPU-Hardware läuft und für die Ausführung verschiedener Aufgaben des Grafik-Renderings verantwortlich ist. Shader werden in zwei Hauptkategorien unterteilt, nämlich „Vertex-Shader“ und „Pixel-Shader“. Der Vertex-Shader ist für die Berechnung der Position, Farbe, Normale, Texturkoordinaten und anderer Attribute jedes Scheitelpunkts verantwortlich, während der Pixel-Shader für die Berechnung der Farbe jedes Pixels, der Abtastkoordinaten der Texturkarte und anderer Attribute verantwortlich ist.

2.2 Funktionsweise von OpenGL ES 2.0

Opengl ES 2.0 ist eigentlich eine Teilmenge von OpenGL, entfernt jedoch die Funktionen, die auf Mobilgeräten nicht benötigt werden. Daher ist der Platzbedarf kleiner und die Startgeschwindigkeit bis zu einem gewissen Grad schneller als bei normalem OpenGL. Im Gegensatz zur Mainstream-Version von Opengl unterteilt Opengl ES 2.0 die Rendering-Pipeline in drei Phasen:

  1. Feste Funktionsstufe: In dieser Stufe werden die einfachsten geometrischen Operationen ausgeführt, z. B. Scheitelpunkttransformation, Translationsskalierung und Clipping.
  2. Programmierbare Shader-Phase: In dieser Phase werden einige erweiterte Berechnungen durchgeführt, z. B. Shader-Programme für physikalische Simulation, Bildverarbeitung und Animationseffekte.
  3. Fragment-Shader-Stufe: Diese Stufe generiert den endgültigen Pixelfarbwert und basiert hauptsächlich auf der Ausgabe der beiden vorherigen Stufen.

Die Rechenleistung der Pipeline mit festen Funktionen ist im Allgemeinen schwach, daher wird sie normalerweise nicht alleine, sondern zusammen mit programmierbaren Shadern verwendet. Aufgrund der fehlenden Hardwarebeschleunigung und der begrenzten Gleitkommafähigkeiten der GPU kann die Pipeline mit festen Funktionen sehr langsam sein. Programmierbare Shader verfügen über leistungsstarke Rechenfunktionen, können verschiedene komplexe Algorithmen ausführen und laufen viel schneller. Die vom Fragment-Shader generierten Farbwerte werden schließlich auf dem Bildschirm angezeigt. Daher ist der Fragment-Shader das letzte Glied in der gesamten Rendering-Pipeline.

3. Erläuterung der Grundprinzipien des Algorithmus, spezifischer Arbeitsschritte und mathematischer Formeln

3.1 Datenaustauschmechanismus

Einer der Kernmechanismen von Opengl ist die Datenübertragung. Der Renderer und der Treiber kommunizieren über zwei Endpunkte für den synchronen Datenaustausch. Es gibt zwei typische Datenaustauschmethoden:

Direkter Austausch

Auf diese Weise müssen die Daten vom Renderer zum Treiber oder umgekehrt vollständig über das Netzwerk verbunden sein. Auf diese Weise muss das sendende Ende die Daten serialisieren und das empfangende Ende muss auch die serialisierten Daten akzeptieren, um die Originaldaten wiederherzustellen.

Indirekter Austausch

Auf diese Weise werden die Daten einfach in den Videospeicher kopiert und dann vom Videospeicher auf das Laufwerk oder umgekehrt. Auf diese Weise kann die Existenz des Netzwerks vermieden werden, wodurch die Rendering-Effizienz verbessert wird. Dies erfordert jedoch Treiberzugriff auf die Rendering-Daten. Auf diese Weise kann die Verbindung zwischen dem Puffer in der Grafikkarte und dem Fenstersystem flexibler gestaltet werden, es erhöht jedoch auch die Komplexität.

3.2 Projektionsmatrix

Die Projektionsmatrix ist eine 4X4-Matrix, die die Transformationsbeziehung von der Kamera zum homogenen Koordinatensystem beschreibt. Es umfasst drei Komponenten:

  • Modellmatrix: Die Matrix beschreibt die Transformation vom Objektraum zum Weltraum.
  • Ansichtsmatrix: Die Matrix beschreibt die Transformation vom Kameraraum zum Beobachtungsraum.
  • Projektionsmatrix: Die Matrix beschreibt die Transformation des Ausschnittfensters nach der Perspektivteilung.

Diese Matrizen wandeln das lokale Koordinatensystem des Objekts in Koordinaten um, die für die Verwendung auf dem Bildschirm geeignet sind. Die von ihnen verwendete mathematische Formel lautet wie folgt:

$M = M_{Modell} \cdot M_{Ansicht} \cdot M_{Projektion}$

Unter diesen ist $M$ die endgültige Matrix, $M_{Modell}, M_{Ansicht} und M_{Projektion}$ repräsentieren die Modellmatrix, die Ansichtsmatrix bzw. die Projektionsmatrix.

Modellmatrix

Die Modellmatrix beschreibt die dreidimensionale Position des Objekts. Es handelt sich um eine 4X4-Matrix. Die vierte Spalte der Matrix stellt die Translationsmatrix dar, die den Ursprung des Objekts zum Ursprung des Weltkoordinatensystems verschiebt. Handelt es sich bei dem Objekt um ein dreidimensionales Modell, dann ist diese Matrix die Identitätsmatrix. Handelt es sich bei dem Objekt um eine andere Objektform, beispielsweise um einen Punkt, eine Linie, einen Strahl usw., muss die Modellmatrix entsprechend konvertiert werden.

$$\begin{bmatrix}\mathtt{m} {00}&\mathtt{m} {01}&\mathtt{m} {02}&\mathtt{m} {03}\ \mathtt{m} {10 }&\mathtt{m} {11}&\mathtt{m} {12}&\mathtt{m} {13}\ \mathtt{m} {20}&\mathtt{m} {21}&\mathtt{ m} {22}&\mathtt{m} {23}\ 0& 0 & 0 & 1 \end{bmatrix}$$

Matrix anzeigen

Die Ansichtsmatrix beschreibt die Position von Kamera zu Kamera und ist eine 4x4-Matrix. Die Kamera gibt eine Position im Weltkoordinatensystem an und die Ansichtsmatrix überträgt Objekte von der Kameraposition in das Weltkoordinatensystem.

$$\begin{bmatrix}\mathtt{v} {00}&\mathtt{v} {01}&\mathtt{v} {02}&-\mathtt{v} {03}\ \mathtt{v} { 10}&\mathtt{v} {11}&\mathtt{v} {12}&-\mathtt{v} {13}\ \mathtt{v} {20}&\mathtt{v} {21}&\ mathtt{v} {22}&-\mathtt{v} {23}\ 0& 0 & 0 & 1 \end{bmatrix}$$

Hier bedeutet $-v_{30}-v_{31}-v_{32}=0$ orthogonale Projektion. Andere Projektionsmodi wie perspektivische Projektion, orthogonale Projektion usw. können hier umgeschaltet werden.

Projektionsmatrix

Die Projektionsmatrix beschreibt die Position und Größe des Trimmfensters. Es handelt sich um eine 4X4-Matrix. Es projiziert das Objekt durch perspektivische Teilung auf das Beschneidungsfenster des Fensters und löst das Entspannungsphänomen zwischen dem Fenster und dem Objekt. Die untere linke Ecke des Fensters ist der Ursprung, die obere rechte Ecke ist ($w$, $h$) und die $z$-Achse zeigt weg.

$P=\frac{(z+p' n)/(p'_f-p'_n),(y+p'_n)/(p'_f-p'_n),-(z+p'_n) \cdot p' {r_x}/(p' fp'_n)-p'_n,\frac{-2z\cdot y}{p'_f-p'_n}+(p'_f+p'_n)} { (w+p''_n)/(p''_f-p''_n)(y+p'_n)}\Bigg| {\mathsf{clip}}_{(p',p'',p')}\Rightarrow p'_n < z \leq p'_f,~ p''_n<x<p''_f,$

Hier stellen $p'$, $p''$ und $p'$ das Seitenverhältnis des Fensters auf der $xy$-Ebene dar, $p_f$ ist die Oberfläche am nahen Ende und $p_n$ ist die Oberfläche am fernen Ende .

${\mathsf{left},\mathsf{richtig},\mathsf{bottom},\mathsf{top},\mathsf{near},~\mathsf{far}}$ stellt das Beschneidungsfenster dar, das der Projektionsmatrix entspricht.

$$\begin{pmatrix} w/2 \ h/2 \ f/(fn) \ n/(nf) \end{pmatrix}\qquad M_{\mathrm{proj}}^{-1}\mathbf{
v }\qquad \begin{pmatrix} \frac{2z}{w}(x'-p'')-1 \ -\frac{2y}{h}(y'+p')+1 \ -\frac{ zf+fp'_fn}{\overline{p'}}+\frac{f^2}{n+zf+fp'_fn} \ \frac{yf+fp'_fn}{\overline{p''}} +\frac{f^2}{n+yf+fp'_fn} \end{pmatrix}$$

Acho que você gosta

Origin blog.csdn.net/universsky2015/article/details/133446686
Recomendado
Clasificación