Es gibt nur Miku

Das Ergebnis der Arbeit an der FSGL-Bibliothek mit OpenGL ES und Code:

Als nächstes werde ich beschreiben, wie alles programmiert wurde und verschiedene interessante Probleme gelöst wurden.

Zuerst initialisieren wir den OpenGL ES-Kontext, wie ich im vorherigen Beitrag geschrieben habe. Im Folgenden betrachten wir nur das Rendern und eine kurze Beschreibung des Codes.

Die Matrix beobachtet dich

Diese Figur von Miku im Video besteht aus Dreiecken. Um in OpenGL ein Dreieck zu zeichnen, müssen Sie drei Punkte mit den Koordinaten x, y, z angeben. in 2D-Koordinaten des OpenGL-Kontexts.
Da wir eine Figur zeichnen müssen, die 3D-Koordinaten enthält, müssen wir eine Projektionsmatrix verwenden. Wir müssen das Modell auch drehen, vergrößern oder was auch immer wir tun möchten – Hierzu wird die Modellmatrix verwendet. In OpenGL gibt es kein Konzept einer Kamera; tatsächlich drehen sich Objekte um eine statische Kamera. Hierzu wird eine Ansichtsmatrix verwendet.

Um die Implementierung von OpenGL ES zu vereinfachen – es enthält keine Matrixdaten. Sie können Bibliotheken verwenden, die fehlende Funktionalität hinzufügen, zum Beispiel GLM.

Shader

Um es dem Entwickler zu ermöglichen, alles und in irgendeiner Weise zu zeichnen, muss OpenGL ES Vertex- und Fragment-Shader implementieren. Der Vertex-Shader muss Rendering-Koordinaten als Eingabe erhalten, Transformationen mithilfe von Matrizen durchführen und die Koordinaten an gl_Position übergeben. Fragment- oder Pixel-Shader – Zeichnet bereits Farbe/Textur, wendet Überlagerung an usw.

Ich habe Shader in GLSL geschrieben. In meiner aktuellen Implementierung sind Shader als C-Strings

direkt in den Hauptanwendungscode integriert

Puffer

Der Vertex-Puffer enthält die Koordinaten der Scheitelpunkte (Vertices); dieser Puffer enthält auch Koordinaten für die Texturierung und andere für Shader notwendige Daten. Nachdem Sie den Vertex-Puffer generiert haben, müssen Sie den Zeiger an die Daten für den Vertex-Shader binden. Dies erfolgt mit dem Befehl glVertexAttribPointer, bei dem Sie die Anzahl der Elemente, einen Zeiger auf den Anfang der Daten und die Schrittgröße angeben müssen, die zum Durchlaufen des Puffers verwendet wird. In meiner Implementierung erfolgt die Bindung von Scheitelpunktkoordinaten und Texturkoordinaten für den Pixel-Shader. Es ist jedoch anzumerken, dass die Übertragung der Daten (Texturkoordinaten) an den Fragment-Shader über den Vertex-Shader erfolgt. Um dies zu erreichen, werden die Koordinaten mit Varying angegeben.

Damit OpenGL weiß, in welcher Reihenfolge Punkte für Dreiecke gezeichnet werden müssen – Sie benötigen einen Indexpuffer (Index). Der Indexpuffer enthält die Scheitelpunktnummer im Array. Unter Verwendung dreier solcher Indizes wird ein Dreieck erhalten.

Texturen

Zuerst müssen Sie eine Textur für OpenGL laden/generieren. Hierzu habe ich SDL_LoadBMP verwendet, die Textur wird aus einer BMP-Datei geladen. Es ist jedoch zu beachten, dass nur 24-Bit-BMPs geeignet sind und die Farben darin nicht in der üblichen RGB-Reihenfolge, sondern in BGR gespeichert werden. Das heißt, nach dem Laden müssen Sie den roten Kanal durch einen blauen ersetzen.
Texturkoordinaten werden im Format angegeben UV< /a>, das heißt, Sie müssen nur zwei Koordinaten übertragen. Die Texturausgabe erfolgt im Fragment-Shader. Dazu müssen Sie die Textur in einen Fragment-Shader binden.

Nichts Besonderes

Da OpenGL gemäß unseren Anweisungen 3D bis 2D zeichnet – dann um die Tiefe zu implementieren und unsichtbare Dreiecke auszuwählen – Sie müssen Culling und einen Tiefenpuffer (Z-Puffer) verwenden. In meiner Implementierung ist es mir gelungen, die manuelle Generierung des Tiefenpuffers mithilfe von zwei Befehlen zu vermeiden: glEnable(GL_DEPTH_TEST); und Auswahlen glEnable(GL_CULL_FACE);
Stellen Sie außerdem sicher, dass die Nahebene für die Projektionsmatrix größer als Null ist, denn Die Überprüfung der Tiefe mit einer Null-Nahebene funktioniert nicht.

Rendering

Um den Vertex-Puffer und den Index-Puffer mit etwas Bewusstem zu füllen, zum Beispiel dem Miku-Modell, müssen Sie dieses Modell laden. Hierfür habe ich die Bibliothek assimp verwendet. Miku wurde in eine Wavefront-OBJ-Formatdatei eingefügt, mit assimp geladen und die Datenkonvertierung von assimp in Vertex- und Indexpuffer wurde implementiert.

Das Rendern erfolgt in mehreren Schritten:

  1. Rotieren Sie Miku mithilfe der Modellmatrixrotation
  2. Bildschirm und Tiefenpuffer löschen
  3. Zeichnen von Dreiecken mit dem glDrawElements-Befehl.

Nächste Stufe – Implementierung des Renderings in WebGL mit Emscripten.

Quellcode:
https://github.com/demensdeum/OpenGLES3-Experiments/tree/master/8-sdl-gles-obj-textured-assimp-miku
Modell:
https://sketchfab.com/models/7310aaeb8370428e966bdcff414273e7

 

Leave a Comment

Your email address will not be published. Required fields are marked *