Da OpenGL eine Zustandsmaschine ist, bin ich ständig glEnable () und glDisable () in meinem Programm. Es gibt einige wenige Aufrufe, die ich nur am Anfang mache (wie zB glClearColor), aber die meisten anderen blicke ich an und aus (wie Beleuchtung, abhängig davon, ob ich ein Modell oder 3D Text oder die GUI rendere).
Wie behalten Sie den Überblick darüber, in welchen Zustand sich die Dinge befinden? Setzen / setzen Sie diese Dinge ständig am Anfang jeder Funktion? Ist das nicht viel unnötiger Aufwand?
Wenn ich zum Beispiel eine neue Funktion schreibe, weiß ich manchmal, in welchem Zustand sich die Funktion befindet, wenn ich die Funktion aufruft, und lasse glEnable oder glDisable oder andere verwandte statusschaltende Aufrufe oben in der Funktion aus. Andere Male schreibe ich die Funktion nur im Voraus und füge diese Dinge hinzu. Also sind meine Funktionen sehr unordentlich, einige modifizieren den OpenGL-Zustand und andere machen nur Vermutungen (die später gebrochen werden, und dann muss ich zurückgehen und herausfinden, warum etwas gelb wurde oder warum ein anderes Ding auf dem Kopf steht usw.) ).
Wie verfolgen Sie OpenGL über Funktionen in einer objektorientierten Umgebung?
Auch mit dieser Frage verbunden ist, wie man weiß, wann man push und pop verwenden soll und wann man den Wert einfach einstellen soll.
Nehmen wir zum Beispiel an, Sie haben ein Programm, das 3D-Material zeichnet und dann 2D-Material zeichnet. Offensichtlich ist die Projektionsmatrix in jedem Fall anders. Du auch:
Und warum?
Gute Frage. Denke darüber nach, wie Texturen funktionieren. Es gibt eine wahnsinnige Menge an Texturen, zwischen denen OpenGL wechseln kann, und Sie müssen das Texturieren aktivieren / deaktivieren, nachdem jedes Objekt gezeichnet wurde. Im Allgemeinen versuchen Sie, dies zu optimieren, indem Sie alle Objekte mit der gleichen Textur auf einmal zeichnen, aber es gibt immer noch eine bemerkenswerte Menge an Zustandsumschaltung, die weitergeht. Deswegen tue ich mein Bestes, um alles mit demselben Zustand auf einmal zu zeichnen, aber ich bin mir nicht sicher, ob es so wichtig ist, es so zu optimieren, wie du denkst.
Um zwischen den 3D- und 2D-Projektionsmodi zu pushen und zu pushen, ist Pushing und Popping für die hierarchische Modellierung gedacht. Wenn Sie Ihre 2D-Projektion an einem Ort relativ zu einem 3D-Objekt benötigen, drücken Sie die Matrix und wechseln Sie in den 2D-Projektionsmodus. Wenn Sie fertig sind, klicken Sie auf Pop. Wenn Sie jedoch ein 2D-GUI-Overlay schreiben, das eine konstante Position auf dem Bildschirm hat, sehe ich keinen Grund, warum Schieben und Poppen wichtig ist.
Sie könnten daran interessiert sein, mehr über Szenengraphbibliotheken zu lesen. Sie sollen Ihre Grafiken von einer höheren Ebene aus verwalten. Sie handhaben nicht alles gut, aber sie sind hervorragend darin, Ihre Geometrie für optimiertes Rendering zu organisieren. Sie können zusätzlich verwendet werden, um Ihre Szenen basierend auf dem OpenGL-Status zu sortieren, obwohl viele dies nicht tun. Wenn Sie den Status on auswählen, können Sie Ihre Geometrie in einer Reihenfolge darstellen, die zu weniger Zustandsübergängen führt. Hier ist ein schöner Überblick über Szenengraph-Bibliotheken:
Ich denke, der einfachste Ansatz wäre, eine eigene Render-Klasse zu schreiben, alle OpenGL-Zustandsmanipulationsfunktionen, die Sie verwenden, einzufügen und die von Ihnen gesetzten Zustände zu verwalten. Sie müssen berücksichtigen, dass das Ändern der Bildschirmauflösung oder das Umschalten des Vollbildmodus Ihre aktuellen Zustände und Daten des OpenGL-Renderkontexts ungültig macht, was bedeutet, dass Sie nach einem solchen Ereignis alle Zustände einstellen müssen, alle Texturen und Shaderprogramme erneut hochladen müssen .