Ich habe meinen Motor mit einem Fehlerprüfcode scharfgeschaltet. Ich werde versuchen, diese Situation nach besten Kräften zu beschreiben. Immer wenn ich einen Shader lade und ein Fehler auftritt (Datei existiert nicht, Kompilierungsfehler, alles, was schief gehen könnte), lösche ich den Shader und setze den Zeiger auf 0 (ich kann mir keinen anderen Weg vorstellen, um sicherzugehen, dass ich es nicht tue versuchen, versehentlich Müll anzuhängen oder zu löschen). Ich möchte das Programm nicht stoppen, wenn dies passiert, weil jemand versehentlich eine einzelne Datei im Spielordner löschen oder ändern könnte und deshalb nicht das ganze Spiel unbrauchbar machen möchte.
Nun ist die Sache, gibt es ein Standardverhalten in der Situation, in der ich Shader an ein Programm anhänge, dessen Zeiger gleich 0 ist?
Wenn ich in meinem Programm einen Vertex-Shader gleich 0 und einen Fragment-Shader gleich 0 anhänge, verwendet OpenGL das Standardprogramm (zeigt alles weiß an):
Dies ist ein gedrehter Würfel, dessen Abmessungen sich bereits im Clipbereich befinden und ohne perspektivische Projektion oder Tiefenprüfung gerendert werden. Es wird aus einer OBJ-Datei geladen.
Wenn ich nun einen richtigen Fragment-Shader anhänge, der Vertex-Shader jedoch 0 ist, erhalte ich Folgendes:
Was ich erwarten würde, alles, was der Fragment-Shader tut, ist die Ausgabe eines vec4 (1.0, 0.3, 0.7, 1.0). Es gibt keinen Vertex-Shader, also verwendet OpenGL den Standard (ist dies eine korrekte Annahme?).
Wenn ich jetzt jedoch einen korrekten Vertex-Shader anhänge, aber einen Fragment-Shader gleich 0 anhänge (oder ich füge überhaupt keinen Fragment-Shader an), bekomme ich dieses Durcheinander:
Was Sie nicht sehen können, ist, dass dieses Modell ständig in verschiedenen Farben lackiert wird. Auf meinem Bildschirm sieht es also aus wie ein Säuretrip mit schwarzen horizontalen Linien.
Ich bin ein bisschen verwirrt, weil ich erwarten würde, dass der Würfel nur weiß ist. Ich möchte darauf hinweisen, dass mein Shader-Code Bare Bones ist. Ich tausche keine Variablen zwischen Vertex- und Fragment-Shadern aus. Wenn ich überprüfe, ob der Zeiger nicht gleich 0 ist, ändert sich nichts. Das verknüpfte Programm verhält sich so, als hätte ich ihm einen Zeiger gleich 0 gegeben. Das Seltsamste für mich ist, dass es immer schön schattiert ist, es ist nicht nur Müll.
BEARBEITEN: Vielleicht erwartet der Standardfragment-Shader einen gl_-Wert von dem Scheitelpunkt, den ich festlegen möchte? Das würde irgendwie erklären, warum die Oberfläche schön schattiert ist, der Fragment-Shader erwartet ein Glätten, aber dieser Wert ist nur Müll, weil ich ihn nicht gesetzt habe.
Ist dies nun ein "undefiniertes Verhalten" oder soll es so funktionieren?
Antworten:
Überprüfen Sie Abschnitt 2.11 der OpenGL 4.2-Spezifikation :
Dies ist "undefiniertes Verhalten", das sich pro Implementierung unterschiedlich verhält.
Was die Lösung betrifft, um keinen Shader finden zu können, habe ich festgestellt, dass es am besten ist, sowohl einen Vertex- als auch einen Fragment-Shader fest zu codieren und vor allem anderen zu laden und ihn dann anstelle fehlender Shader zu verwenden. Auf diese Weise werden viele der von mir definierten Uniformen (Transformationsmatrizen) immer noch durchlaufen und das Ergebnis wird halbwegs anständig aussehen. So mache ich es zum Beispiel (C #):
Auch das Hardcodieren einer Standardtextur ist eine gute Idee.
quelle
glShaderSource
eine Reihe von Zeichenfolgen erforderlich sind.#ifdef
. Es ist nicht vorhanden, sodass Sie jede Zeile als separate Zeichenfolge senden können. Ja, es funktioniert, aber es ist ein schrecklicher Codierungsstil. Es ist wie beim Erstellen einer CPP-Datei, indem jede Zeile einzeln eingeschlossen wird . Ja, es wird kompiliert, aber so verwenden Sie #include nicht.